package kyoketsu import ( "encoding/json" "fmt" "log" "net" "os" "testing" ) type IpAddresses struct { Addrs []string `json:"addresses"` } func LoadTestAddresses(loc string) map[string]struct{} { b, err := os.ReadFile(loc) if err != nil { log.Fatal("Test setup failed.\n", err) } var addr IpAddresses addrmap := map[string]struct{}{} err = json.Unmarshal(b, &addr) if err != nil { log.Fatal("test setup failed.\n", err) } for i := range addr.Addrs { addrmap[addr.Addrs[i]] = struct{}{} } return addrmap } // Testing the addres recursion function to return all IPs in the target address subnet // All test cases use a select sort to assert that all addresses in the test data are in the return func TestAddressRecurse(t *testing.T) { type TestCase struct { Name string TestData string InputAddr string InputMask int ShouldFail bool } tc := []TestCase{ TestCase{ Name: "Passing testcase with valid IP address, returns all addresses.", TestData: "../test/local_ips.json", InputAddr: "192.168.50.50", InputMask: 24, }, TestCase{ Name: "Passing testcase with valid IP address that belongs to a /16 subnet", TestData: "../test/slash16_ips.json", InputAddr: "10.252.1.1", InputMask: 16, }, } for i := range tc { addr, network, err := net.ParseCIDR(fmt.Sprintf("%s/%v", tc[i].InputAddr, tc[i].InputMask)) if err != nil { t.Errorf("Test case: '%s' failed! Reason: %s", tc[i].Name, err) } got := &IpSubnetMapper{} got.Mask = tc[i].InputMask got.NetworkAddr = addr.Mask(network.Mask) got.Current = addr.Mask(network.Mask) addressRecurse(got, 65535) want := LoadTestAddresses(tc[i].TestData) for x := range got.Ipv4s { gotip := got.Ipv4s[x] _, ok := want[gotip.String()] if !ok { t.Errorf("Test '%s' failed! Address: %s was not found in the test data: %s\n", tc[i].Name, gotip.String(), tc[i].TestData) } } log.Printf("Nice! Test: '%s' passed!\n", tc[i].Name) } } // Testing the function to retrieve the next network address func TestGetNextAddr(t *testing.T) { type TestCase struct { Name string Input string Wants string ShouldFail bool } tc := []TestCase{ TestCase{ Name: "Passing test case, function returns the next address", Input: "10.252.1.1", Wants: "10.252.1.2", ShouldFail: false, }, TestCase{ Name: "Failing test case, function returns the wrong address", Input: "10.252.1.1", Wants: "10.252.1.4", ShouldFail: true, }, } for i := range tc { got := getNextAddr(tc[i].Input) if got != tc[i].Wants { if !tc[i].ShouldFail { t.Errorf("Test: '%s' failed! Return: %s\nTest expected: %s\nTest Should fail: %v\n", tc[i].Name, got, tc[i].Wants, tc[i].ShouldFail) } } } } func TestGetNetwork(t *testing.T) { type TestCase struct { Name string InputAddr string InputMask int Expects string ShouldFail bool } tc := []TestCase{ TestCase{ Name: "Passing test, function returns the correct network given the CIDR mask", InputAddr: "192.168.50.35", InputMask: 24, Expects: "192.168.50.0", ShouldFail: false, }, TestCase{ Name: "Passing test, function returns the correct network given the CIDR mask (Larger network, /16 CIDR)", InputAddr: "10.252.47.200", InputMask: 16, Expects: "10.252.0.0", ShouldFail: false, }, } for i := range tc { got := getNetwork(tc[i].InputAddr, tc[i].InputMask) if got != tc[i].Expects { if !tc[i].ShouldFail { t.Errorf("Test: '%s' failed! Returned: %s\nExpected: %s\nShould fail: %v", tc[i].Name, got, tc[i].Expects, tc[i].ShouldFail) } } } }