network_category_windows_test.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //go:build !e2e_testing
  2. // +build !e2e_testing
  3. package overlay
  4. import (
  5. "testing"
  6. )
  7. func Test_parseNetworkCategory(t *testing.T) {
  8. cases := []struct {
  9. in string
  10. wantCat networkCategory
  11. wantApply bool
  12. wantErr bool
  13. }{
  14. {"", 0, false, false},
  15. {"unset", 0, false, false},
  16. {" UNSET ", 0, false, false},
  17. {"private", networkCategoryPrivate, true, false},
  18. {"Private", networkCategoryPrivate, true, false},
  19. {" PRIVATE ", networkCategoryPrivate, true, false},
  20. {"public", networkCategoryPublic, true, false},
  21. {"PUBLIC", networkCategoryPublic, true, false},
  22. {"domain", networkCategoryDomainAuthenticated, true, false},
  23. {"DomainAuthenticated", networkCategoryDomainAuthenticated, true, false},
  24. {"garbage", 0, false, true},
  25. {"privates", 0, false, true},
  26. }
  27. for _, tc := range cases {
  28. cat, apply, err := parseNetworkCategory(tc.in)
  29. if (err != nil) != tc.wantErr {
  30. t.Errorf("parseNetworkCategory(%q) err=%v, wantErr=%v", tc.in, err, tc.wantErr)
  31. continue
  32. }
  33. if cat != tc.wantCat || apply != tc.wantApply {
  34. t.Errorf("parseNetworkCategory(%q) = (%v, %v), want (%v, %v)", tc.in, cat, apply, tc.wantCat, tc.wantApply)
  35. }
  36. }
  37. }
  38. // Test_NLM_round_trip exercises every COM call path used by setNetworkCategory
  39. // without mutating the host's network state. It validates the CLSID/IID
  40. // constants and every vtable index by enumerating connections, fetching the
  41. // adapter id and parent network, reading the current category, and writing it
  42. // back unchanged.
  43. //
  44. // Requires Windows but does not require admin or the wintun driver. Skips if
  45. // no network connections are available (unlikely outside of an isolated
  46. // container).
  47. func Test_NLM_round_trip(t *testing.T) {
  48. deinit, err := coInit()
  49. if err != nil {
  50. t.Fatalf("coInit: %v", err)
  51. }
  52. defer deinit()
  53. nlm, err := createNetworkListManager()
  54. if err != nil {
  55. t.Fatalf("createNetworkListManager: %v", err)
  56. }
  57. defer nlm.Release()
  58. enum, err := nlm.GetNetworkConnections()
  59. if err != nil {
  60. t.Fatalf("GetNetworkConnections: %v", err)
  61. }
  62. defer enum.Release()
  63. saw := 0
  64. for {
  65. conn, err := enum.Next()
  66. if err != nil {
  67. t.Fatalf("EnumNetworkConnections.Next: %v", err)
  68. }
  69. if conn == nil {
  70. break
  71. }
  72. saw++
  73. if _, err := conn.GetAdapterId(); err != nil {
  74. conn.Release()
  75. t.Fatalf("INetworkConnection.GetAdapterId: %v", err)
  76. }
  77. net, err := conn.GetNetwork()
  78. conn.Release()
  79. if err != nil {
  80. t.Fatalf("INetworkConnection.GetNetwork: %v", err)
  81. }
  82. cat, err := net.GetCategory()
  83. if err != nil {
  84. net.Release()
  85. t.Fatalf("INetwork.GetCategory: %v", err)
  86. }
  87. // Set to the current value so the host's NLM state is unchanged but
  88. // SetCategory's vtable slot is still validated end-to-end.
  89. if err := net.SetCategory(cat); err != nil {
  90. net.Release()
  91. t.Fatalf("INetwork.SetCategory(%v): %v", cat, err)
  92. }
  93. net.Release()
  94. }
  95. if saw == 0 {
  96. t.Skip("no NLM network connections available; skipping round-trip")
  97. }
  98. }