//go:build linux // +build linux package network import ( "context" "os" "path/filepath" "testing" "time" ) func Test_GenerateResolvConfContent(t *testing.T) { type testcase struct { name string searches []string servers []string options []string expectedContent string expectErr bool } testcases := []*testcase{ { name: "Empty", }, { name: "MaxSearches", searches: []string{"1", "2", "3", "4", "5", "6", "7"}, expectErr: true, }, { name: "ValidSearches", searches: []string{"a.com", "b.com"}, expectedContent: "search a.com b.com\n", }, { name: "ValidServers", servers: []string{"8.8.8.8", "8.8.4.4"}, expectedContent: "nameserver 8.8.8.8\nnameserver 8.8.4.4\n", }, { name: "ValidOptions", options: []string{"timeout:30", "inet6"}, expectedContent: "options timeout:30 inet6\n", }, { name: "All", searches: []string{"a.com", "b.com"}, servers: []string{"8.8.8.8", "8.8.4.4"}, options: []string{"timeout:30", "inet6"}, expectedContent: "search a.com b.com\nnameserver 8.8.8.8\nnameserver 8.8.4.4\noptions timeout:30 inet6\n", }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { c, err := GenerateResolvConfContent(context.Background(), tc.searches, tc.servers, tc.options) if tc.expectErr && err == nil { t.Fatal("expected err got nil") } else if !tc.expectErr && err != nil { t.Fatalf("expected no error got %v:", err) } if c != tc.expectedContent { t.Fatalf("expected content: %q got: %q", tc.expectedContent, c) } }) } } func Test_MergeValues(t *testing.T) { type testcase struct { name string first []string second []string expected []string } testcases := []*testcase{ { name: "BothEmpty", }, { name: "FirstEmpty", second: []string{"a", "b"}, expected: []string{"a", "b"}, }, { name: "SecondEmpty", first: []string{"a", "b"}, expected: []string{"a", "b"}, }, { name: "AllUnique", first: []string{"a", "c", "d"}, second: []string{"b", "e"}, expected: []string{"a", "c", "d", "b", "e"}, }, { name: "NonUnique", first: []string{"a", "c", "d"}, second: []string{"a", "b", "c", "d"}, expected: []string{"a", "c", "d", "b"}, }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { m := MergeValues(tc.first, tc.second) if len(m) != len(tc.expected) { t.Fatalf("expected %d entries got: %d", len(tc.expected), len(m)) } for i := 0; i < len(tc.expected); i++ { if tc.expected[i] != m[i] { t.Logf("%v :: %v", tc.expected, m) t.Fatalf("expected value: %q at index: %d got: %q", tc.expected[i], i, m[i]) } } }) } } func Test_GenerateEtcHostsContent(t *testing.T) { type testcase struct { name string hostname string expectedContent string } testcases := []*testcase{ { name: "Net BIOS Name", hostname: "Test", expectedContent: `127.0.0.1 localhost 127.0.0.1 Test # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters `, }, { name: "FQDN", hostname: "test.rules.domain.com", expectedContent: `127.0.0.1 localhost 127.0.0.1 test.rules.domain.com test # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters `, }, } for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { c := GenerateEtcHostsContent(context.Background(), tc.hostname) if c != tc.expectedContent { t.Fatalf("expected content: %q got: %q", tc.expectedContent, c) } }) } } // create a test os.DirEntry so we can return back a value to ReadDir type testDirEntry struct { FileName string IsDirectory bool } func (t *testDirEntry) Name() string { return t.FileName } func (t *testDirEntry) Type() os.FileMode { if t.IsDirectory { return os.ModeDir } return 0 } func (t *testDirEntry) IsDir() bool { return t.IsDirectory } func (t *testDirEntry) Info() (os.FileInfo, error) { return nil, nil } var _ = (os.DirEntry)(&testDirEntry{}) func Test_InstanceIDToName(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() vmBusGUID := "1111-2222-3333-4444" testIfName := "test-eth0" vmbusWaitForDevicePath = func(_ context.Context, vmBusGUIDPattern string) (string, error) { vmBusPath := filepath.Join("/sys/bus/vmbus/devices", vmBusGUIDPattern) return vmBusPath, nil } storageWaitForFileMatchingPattern = func(_ context.Context, pattern string) (string, error) { return pattern, nil } ioReadDir = func(dirname string) ([]os.DirEntry, error) { info := &testDirEntry{ FileName: testIfName, IsDirectory: false, } return []os.DirEntry{info}, nil } actualIfName, err := InstanceIDToName(ctx, vmBusGUID, false) if err != nil { t.Fatalf("expected no error, instead got %v", err) } if actualIfName != testIfName { t.Fatalf("expected to get %v ifname, instead got %v", testIfName, actualIfName) } } func Test_InstanceIDToName_VPCI(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() vmBusGUID := "1111-2222-3333-4444" testIfName := "test-eth0-vpci" pciFindDeviceFullPath = func(_ context.Context, vmBusGUID string) (string, error) { return filepath.Join("/sys/bus/vmbus/devices", vmBusGUID), nil } storageWaitForFileMatchingPattern = func(_ context.Context, pattern string) (string, error) { return pattern, nil } ioReadDir = func(dirname string) ([]os.DirEntry, error) { info := &testDirEntry{ FileName: testIfName, IsDirectory: false, } return []os.DirEntry{info}, nil } actualIfName, err := InstanceIDToName(ctx, vmBusGUID, true) if err != nil { t.Fatalf("expected no error, instead got %v", err) } if actualIfName != testIfName { t.Fatalf("expected to get %v ifname, instead got %v", testIfName, actualIfName) } }