ocket8888 commented on a change in pull request #4916:
URL: https://github.com/apache/trafficcontrol/pull/4916#discussion_r466680721



##########
File path: lib/go-tc/servers_test.go
##########
@@ -56,3 +59,1323 @@ func ExampleLegacyInterfaceDetails_ToInterfaces() {
        //      addr=::14/64, gateway=::15, service address=false
        //
 }
+
+func ExampleLegacyInterfaceDetails_String() {
+       ipv4 := "192.0.2.0"
+       ipv6 := "2001:DB8::/64"
+       name := "test"
+       mtu := 9000
+
+       lid := LegacyInterfaceDetails{
+               InterfaceMtu:  &mtu,
+               InterfaceName: &name,
+               IP6Address:    &ipv6,
+               IP6Gateway:    nil,
+               IPAddress:     &ipv4,
+               IPGateway:     nil,
+               IPNetmask:     nil,
+       }
+
+       fmt.Println(lid.String())
+
+       // Output: LegacyInterfaceDetails(InterfaceMtu=9000, 
InterfaceName='test', IP6Address='2001:DB8::/64', IP6Gateway=nil, 
IPAddress='192.0.2.0', IPGateway=nil, IPNetmask=nil)
+}
+
+type interfaceTest struct {
+       ExpectedIPv4        string
+       ExpectedIPv4Gateway string
+       ExpectedIPv6        string
+       ExpectedIPv6Gateway string
+       ExpectedMTU         *uint64
+       ExpectedName        string
+       ExpectedNetmask     string
+       Interfaces          []ServerInterfaceInfo
+}
+
+// tests a set of interfaces' conversion to legacy format against expected
+// values.
+// Note: This doesn't distinguish between nil and pointer-to-empty-string 
values
+// when a value is not expected. That's because all ATC components treat null
+// and empty-string values the same, so it's not important which is returned by
+// the conversion process (and in fact expecting one or the other could
+// potentially break some applications).
+func testInfs(expected interfaceTest, t *testing.T) {
+       lid, err := InterfaceInfoToLegacyInterfaces(expected.Interfaces)
+       if err != nil {
+               t.Fatalf("Unexpected error: %v", err)
+       }
+
+       if lid.InterfaceName == nil {
+               t.Error("Unexpectedly nil Interface Name")
+       } else if *lid.InterfaceName != expected.ExpectedName {
+               t.Errorf("Incorrect Interface Name; want: '%s', got: '%s'", 
expected.ExpectedName, *lid.InterfaceName)
+       }
+
+       if expected.ExpectedMTU != nil {
+               if lid.InterfaceMtu == nil {
+                       t.Error("Unexpectedly nil Interface MTU")
+               } else if uint64(*lid.InterfaceMtu) != *expected.ExpectedMTU {
+                       t.Errorf("Incorrect Interface MTU; want: %d, got: %d", 
*expected.ExpectedMTU, *lid.InterfaceMtu)
+               }
+       } else if lid.InterfaceMtu != nil {
+               t.Error("Unexpectedly non-nil Interface MTU")
+       }
+
+       if expected.ExpectedIPv4 != "" {
+               if lid.IPAddress == nil {
+                       t.Error("Unexpectedly nil IPv4 Address")
+               } else if *lid.IPAddress != expected.ExpectedIPv4 {
+                       t.Errorf("Incorrect IPv4 Address; want: '%s', got: 
'%s'", expected.ExpectedIPv4, *lid.IPAddress)
+               }
+       } else if lid.IPAddress != nil && *lid.IPAddress != "" {
+               t.Error("Unexpectedly non-empty IPv4 Address")
+       }
+
+       if expected.ExpectedIPv4Gateway != "" {
+               if lid.IPGateway == nil {
+                       t.Error("Unexpectedly nil IPv4 Gateway")
+               } else if *lid.IPGateway != expected.ExpectedIPv4Gateway {
+                       t.Errorf("Incorrect IPv4 Gateway; want: '%s', got: 
'%s'", expected.ExpectedIPv4Gateway, *lid.IPGateway)
+               }
+       } else if lid.IPGateway != nil && *lid.IPGateway != "" {
+               t.Error("Unexpectedly non-empty IPv4 Gateway")
+       }
+
+       if expected.ExpectedNetmask != "" {
+               if lid.IPNetmask == nil {
+                       t.Error("Unexpectedly nil IPv4 Netmask")
+               } else if *lid.IPNetmask != expected.ExpectedNetmask {
+                       t.Errorf("Incorrect IPv4 Netmask; want: '%s', got: 
'%s'", expected.ExpectedNetmask, *lid.IPNetmask)
+               }
+       } else if lid.IPNetmask != nil && *lid.IPNetmask != "" {
+               t.Error("Unexpectedly non-empty IPv4 Netmask")
+       }
+
+       if expected.ExpectedIPv6 != "" {
+               if lid.IP6Address == nil {
+                       t.Error("Unexpectedly nil IPv6 Address")
+               } else if *lid.IP6Address != expected.ExpectedIPv6 {
+                       t.Errorf("Incorrect IPv6 Address; want: '%s', got: 
'%s'", expected.ExpectedIPv6, *lid.IP6Address)
+               }
+       } else if lid.IP6Address != nil && *lid.IP6Address != "" {
+               t.Error("Unexpectedly non-empty IPv6 Address")
+       }
+
+       if expected.ExpectedIPv6Gateway != "" {
+               if lid.IP6Gateway == nil {
+                       t.Error("Unexpectedly nil IPv6 Gateway")
+               } else if *lid.IP6Gateway != expected.ExpectedIPv6Gateway {
+                       t.Errorf("Incorrect IPv6 Gateway; want: '%s', got: 
'%s'", expected.ExpectedIPv6Gateway, *lid.IP6Gateway)
+               }
+       } else if lid.IP6Gateway != nil && *lid.IP6Gateway != "" {
+               t.Error("Unexpectedly non-empty IPv6 Gateway")
+       }
+}
+
+func TestInterfaceInfoToLegacyInterfaces(t *testing.T) {
+       var mtu uint64 = 9000
+       ipv4Gateway := "192.0.2.2"
+       ipv6Gateway := "2001:DB8::2"
+
+       cases := map[string]interfaceTest{
+               "single interface, IPv4 only, no gateway, MTU, or netmask": 
interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: "",
+                       ExpectedIPv6:        "",
+                       ExpectedIPv6Gateway: "",
+                       ExpectedMTU:         nil,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  nil,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "single interface, IPv4 only, no gateway or netmask": 
interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: "",
+                       ExpectedIPv6:        "",
+                       ExpectedIPv6Gateway: "",
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  &mtu,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "single interface, IPv4 only, no netmask": interfaceTest{ // 
Final Destination
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: ipv4Gateway,
+                       ExpectedIPv6:        "",
+                       ExpectedIPv6Gateway: "",
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  &mtu,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0",
+                                                       Gateway:        
&ipv4Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "single interface, IPv4 only": interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: ipv4Gateway,
+                       ExpectedIPv6:        "",
+                       ExpectedIPv6Gateway: "",
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "255.255.255.0",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  &mtu,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0/24",
+                                                       Gateway:        
&ipv4Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "single interface, no gateway, MTU, or netmask": interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: "",
+                       ExpectedIPv6:        "2001:DB8::1",
+                       ExpectedIPv6Gateway: "",
+                       ExpectedMTU:         nil,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  nil,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: true,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::1",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "single interface": interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: ipv4Gateway,
+                       ExpectedIPv6:        "2001:DB8::1",
+                       ExpectedIPv6Gateway: ipv6Gateway,
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "255.255.255.0",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  &mtu,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0/24",
+                                                       Gateway:        
&ipv4Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::1",
+                                                       Gateway:        
&ipv6Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "single interface, extra IP addresses": interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: ipv4Gateway,
+                       ExpectedIPv6:        "2001:DB8::1",
+                       ExpectedIPv6Gateway: ipv6Gateway,
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "255.255.255.0",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  &mtu,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.1/5",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0/24",
+                                                       Gateway:        
&ipv4Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::2",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::1",
+                                                       Gateway:        
&ipv6Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.2/20",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                       },
+                               },
+                       },
+               },
+               "multiple interfaces, IPv4 only, no netmask": interfaceTest{
+                       ExpectedIPv4:        "192.0.2.1",
+                       ExpectedIPv4Gateway: ipv4Gateway,
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "",
+                       ExpectedIPv6:        "",
+                       ExpectedIPv6Gateway: "",
+                       Interfaces: []ServerInterfaceInfo{
+                               {
+                                       IPAddresses: []ServerIPAddress{
+                                               {
+                                                       Address:        
"192.0.2.1",
+                                                       Gateway:        
&ipv4Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                                       MaxBandwidth: nil,
+                                       Monitor:      true,
+                                       MTU:          &mtu,
+                                       Name:         "test",
+                               },
+                               {
+                                       IPAddresses: []ServerIPAddress{
+                                               {
+                                                       Address:        
"192.0.2.2",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                       },
+                                       MaxBandwidth: nil,
+                                       Monitor:      false,
+                                       MTU:          &mtu,
+                                       Name:         "invalid",
+                               },
+                       },
+               },
+               "multiple interfaces": interfaceTest{
+                       ExpectedIPv4:        "192.0.2.0",
+                       ExpectedIPv4Gateway: ipv4Gateway,
+                       ExpectedIPv6:        "2001:DB8::1",
+                       ExpectedIPv6Gateway: ipv6Gateway,
+                       ExpectedMTU:         &mtu,
+                       ExpectedName:        "test",
+                       ExpectedNetmask:     "255.255.255.0",
+                       Interfaces: []ServerInterfaceInfo{
+                               ServerInterfaceInfo{
+                                       MTU:  nil,
+                                       Name: "invalid1",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.1/5",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::2",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                       },
+                               },
+                               ServerInterfaceInfo{
+                                       MTU:  &mtu,
+                                       Name: "test",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.0/24",
+                                                       Gateway:        
&ipv4Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::1",
+                                                       Gateway:        
&ipv6Gateway,
+                                                       ServiceAddress: true,
+                                               },
+                                       },
+                               },
+                               ServerInterfaceInfo{
+                                       MTU:  nil,
+                                       Name: "invalid2",
+                                       IPAddresses: []ServerIPAddress{
+                                               ServerIPAddress{
+                                                       Address:        
"192.0.2.2/7",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                               ServerIPAddress{
+                                                       Address:        
"2001:DB8::3/12",
+                                                       Gateway:        nil,
+                                                       ServiceAddress: false,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       for description, test := range cases {
+               t.Run(description, func(t *testing.T) { testInfs(test, t) })
+       }
+}
+
+func TestServer_ToNullable(t *testing.T) {
+       fqdn := "testFQDN"
+       srv := Server{
+               Cachegroup:       "testCachegroup",
+               CachegroupID:     42,
+               CDNID:            43,
+               CDNName:          "testCDNName",
+               DeliveryServices: map[string][]string{"test": 
[]string{"quest"}},
+               DomainName:       "testDomainName",
+               FQDN:             &fqdn,
+               FqdnTime:         time.Now(),
+               GUID:             "testGUID",
+               HostName:         "testHostName",
+               HTTPSPort:        -1,
+               ID:               44,
+               ILOIPAddress:     "testILOIPAddress",
+               ILOIPGateway:     "testILOIPGateway",
+               ILOIPNetmask:     "testILOIPNetmask",
+               ILOPassword:      "testILOPassword",
+               ILOUsername:      "testILOUsername",
+               InterfaceMtu:     -2,
+               InterfaceName:    "testInterfaceName",
+               IP6Address:       "testIP6Address",
+               IP6IsService:     true,
+               IP6Gateway:       "testIP6Gateway",
+               IPAddress:        "testIPAddress",
+               IPIsService:      false,
+               IPGateway:        "testIPGateway",
+               IPNetmask:        "testIPNetmask",
+               LastUpdated:      TimeNoMod(Time{Time: 
time.Now().Add(time.Minute), Valid: true}),
+               MgmtIPAddress:    "testMgmtIPAddress",
+               MgmtIPGateway:    "testMgmtIPGateway",
+               MgmtIPNetmask:    "testMgmtIPNetmask",
+               OfflineReason:    "testOfflineReason",
+               PhysLocation:     "testPhysLocation",
+               PhysLocationID:   45,
+               Profile:          "testProfile",
+               ProfileDesc:      "testProfileDesc",
+               ProfileID:        46,
+               Rack:             "testRack",
+               RevalPending:     true,
+               RouterHostName:   "testRouterHostName",
+               RouterPortName:   "testRouterPortName",
+               Status:           "testStatus",
+               StatusID:         47,
+               TCPPort:          -3,
+               Type:             "testType",
+               TypeID:           48,
+               UpdPending:       false,
+               XMPPID:           "testXMPPID",
+               XMPPPasswd:       "testXMPPasswd",
+       }
+
+       nullable := srv.ToNullable()
+
+       if nullable.Cachegroup == nil {
+               t.Error("nullable conversion gave nil Cachegroup")
+       } else if *nullable.Cachegroup != srv.Cachegroup {
+               t.Errorf("Incorrect Cachegroup after nullable conversion; want: 
'%s', got: '%s'", srv.Cachegroup, *nullable.Cachegroup)
+       }
+
+       if nullable.CachegroupID == nil {
+               t.Error("nullable conversion gave nil CachegroupID")
+       } else if *nullable.CachegroupID != srv.CachegroupID {
+               t.Errorf("Incorrect CachegroupID after nullable conversion; 
want: %d, got: %d", srv.CachegroupID, *nullable.CachegroupID)
+       }
+
+       if nullable.CDNID == nil {
+               t.Error("nullable conversion gave nil CDNID")
+       } else if *nullable.CDNID != srv.CDNID {
+               t.Errorf("Incorrect CDNID after nullable conversion; want: %d, 
got: %d", srv.CDNID, *nullable.CDNID)
+       }
+
+       if nullable.CDNName == nil {
+               t.Error("nullable conversion gave nil CDNName")
+       } else if *nullable.CDNName != srv.CDNName {
+               t.Errorf("Incorrect CDNName after nullable conversion; want: 
'%s', got: '%s'", srv.CDNName, *nullable.CDNName)
+       }
+
+       if nullable.DeliveryServices == nil {
+               t.Error("nullable conversion gave nil DeliveryServices")
+       } else if len(*nullable.DeliveryServices) != len(srv.DeliveryServices) {
+               t.Errorf("Incorrect number of DeliveryServices after nullable 
conversion; want: %d, got: %d", len(srv.DeliveryServices), 
len(*nullable.DeliveryServices))
+       } else {
+               for k, v := range srv.DeliveryServices {
+                       nullableV, ok := (*nullable.DeliveryServices)[k]
+                       if !ok {
+                               t.Errorf("Missing Delivery Service '%s' after 
nullable conversion", k)
+                               continue
+                       }
+                       if len(nullableV) != len(v) {
+                               t.Errorf("Delivery Service '%s' has incorrect 
length after nullable conversion; want: %d, got: %d", k, len(v), len(nullableV))
+                       }
+                       for i, ds := range v {
+                               nullableDS := nullableV[i]
+                               if nullableDS != ds {
+                                       t.Errorf("Incorrect value at position 
%d in Delivery Service '%s' after nullable conversion; want: '%s', got: '%s'", 
i, k, ds, nullableDS)
+                               }
+                       }
+               }
+       }
+
+       if nullable.DomainName == nil {
+               t.Error("nullable conversion gave nil DomainName")
+       } else if *nullable.DomainName != srv.DomainName {
+               t.Errorf("Incorrect DomainName after nullable conversion; want: 
'%s', got: '%s'", srv.DomainName, *nullable.DomainName)
+       }
+
+       if nullable.FQDN == nil {
+               t.Error("nullable conversion gave nil FQDN")
+       } else if *nullable.FQDN != fqdn {
+               t.Errorf("Incorrect FQDN after nullable conversion; want: '%s', 
got: '%s'", fqdn, *nullable.FQDN)
+       }
+
+       if nullable.FqdnTime != srv.FqdnTime {
+               t.Errorf("Incorrect FqdnTime after nullable conversion; want: 
'%s', got: '%s'", srv.FqdnTime, nullable.FqdnTime)
+       }
+
+       if nullable.GUID == nil {
+               t.Error("nullable conversion gave nil GUID")
+       } else if *nullable.GUID != srv.GUID {
+               t.Errorf("Incorrect GUID after nullable conversion; want: '%s', 
got: '%s'", srv.GUID, *nullable.GUID)
+       }
+
+       if nullable.HostName == nil {
+               t.Error("nullable conversion gave nil HostName")
+       } else if *nullable.HostName != srv.HostName {
+               t.Errorf("Incorrect HostName after nullable conversion; want: 
'%s', got: '%s'", srv.HostName, *nullable.HostName)
+       }
+
+       if nullable.HTTPSPort == nil {
+               t.Error("nullable conversion gave nil HTTPSPort")
+       } else if *nullable.HTTPSPort != srv.HTTPSPort {
+               t.Errorf("Incorrect HTTPSPort after nullable conversion; want: 
%d, got: %d", srv.HTTPSPort, *nullable.HTTPSPort)
+       }
+
+       if nullable.ID == nil {
+               t.Error("nullable conversion gave nil ID")
+       } else if *nullable.ID != srv.ID {
+               t.Errorf("Incorrect ID after nullable conversion; want: %d, 
got: %d", srv.ID, *nullable.ID)
+       }
+
+       if nullable.ILOIPAddress == nil {
+               t.Error("nullable conversion gave nil ILOIPAddress")
+       } else if *nullable.ILOIPAddress != srv.ILOIPAddress {
+               t.Errorf("Incorrect ILOIPAddress after nullable conversion; 
want: '%s', got: '%s'", srv.ILOIPAddress, *nullable.ILOIPAddress)
+       }
+
+       if nullable.ILOIPGateway == nil {
+               t.Error("nullable conversion gave nil ILOIPGateway")
+       } else if *nullable.ILOIPGateway != srv.ILOIPGateway {
+               t.Errorf("Incorrect ILOIPGateway after nullable conversion; 
want: '%s', got: '%s'", srv.ILOIPGateway, *nullable.ILOIPGateway)
+       }
+
+       if nullable.ILOIPNetmask == nil {
+               t.Error("nullable conversion gave nil ILOIPNetmask")
+       } else if *nullable.ILOIPNetmask != srv.ILOIPNetmask {
+               t.Errorf("Incorrect ILOIPNetmask after nullable conversion; 
want: '%s', got: '%s'", srv.ILOIPNetmask, *nullable.ILOIPNetmask)
+       }
+
+       if nullable.ILOPassword == nil {
+               t.Error("nullable conversion gave nil ILOPassword")
+       } else if *nullable.ILOPassword != srv.ILOPassword {
+               t.Errorf("Incorrect ILOPassword after nullable conversion; 
want: '%s', got: '%s'", srv.ILOPassword, *nullable.ILOPassword)
+       }
+
+       if nullable.ILOUsername == nil {
+               t.Error("nullable conversion gave nil ILOUsername")
+       } else if *nullable.ILOUsername != srv.ILOUsername {
+               t.Errorf("Incorrect ILOUsername after nullable conversion; 
want: '%s', got: '%s'", srv.ILOUsername, *nullable.ILOUsername)
+       }
+
+       if nullable.InterfaceMtu == nil {
+               t.Error("nullable conversion gave nil InterfaceMtu")
+       } else if *nullable.InterfaceMtu != srv.InterfaceMtu {
+               t.Errorf("Incorrect InterfaceMtu after nullable conversion; 
want: %d, got: %d", srv.InterfaceMtu, *nullable.InterfaceMtu)
+       }
+
+       if nullable.InterfaceName == nil {
+               t.Error("nullable conversion gave nil InterfaceName")
+       } else if *nullable.InterfaceName != srv.InterfaceName {
+               t.Errorf("Incorrect InterfaceName after nullable conversion; 
want: '%s', got: '%s'", srv.InterfaceName, *nullable.InterfaceName)
+       }
+
+       if nullable.IP6Address == nil {
+               t.Error("nullable conversion gave nil IP6Address")
+       } else if *nullable.IP6Address != srv.IP6Address {
+               t.Errorf("Incorrect IP6Address after nullable conversion; want: 
'%s', got: '%s'", srv.IP6Address, *nullable.IP6Address)
+       }
+
+       if nullable.IP6IsService == nil {
+               t.Error("nullable conversion gave nil IP6IsService")
+       } else if *nullable.IP6IsService != srv.IP6IsService {
+               t.Errorf("Incorrect IP6IsService after nullable conversion; 
want: %t, got: %t", srv.IP6IsService, *nullable.IP6IsService)
+       }
+
+       if nullable.IP6Gateway == nil {
+               t.Error("nullable conversion gave nil IP6Gateway")
+       } else if *nullable.IP6Gateway != srv.IP6Gateway {
+               t.Errorf("Incorrect IP6Gateway after nullable conversion; want: 
'%s', got: '%s'", srv.IP6Gateway, *nullable.IP6Gateway)
+       }
+
+       if nullable.IPAddress == nil {
+               t.Error("nullable conversion gave nil IPAddress")
+       } else if *nullable.IPAddress != srv.IPAddress {
+               t.Errorf("Incorrect IPAddress after nullable conversion; want: 
'%s', got: '%s'", srv.IPAddress, *nullable.IPAddress)
+       }
+
+       if nullable.IPIsService == nil {
+               t.Error("nullable conversion gave nil IPIsService")
+       } else if *nullable.IPIsService != srv.IPIsService {
+               t.Errorf("Incorrect IPIsService after nullable conversion; 
want: %t, got: %t", srv.IPIsService, *nullable.IPIsService)
+       }
+
+       if nullable.IPGateway == nil {
+               t.Error("nullable conversion gave nil IPGateway")
+       } else if *nullable.IPGateway != srv.IPGateway {
+               t.Errorf("Incorrect IPGateway after nullable conversion; want: 
'%s', got: '%s'", srv.IPGateway, *nullable.IPGateway)
+       }
+
+       if nullable.IPNetmask == nil {
+               t.Error("nullable conversion gave nil IPNetmask")
+       } else if *nullable.IPNetmask != srv.IPNetmask {
+               t.Errorf("Incorrect IPNetmask after nullable conversion; want: 
'%s', got: '%s'", srv.IPNetmask, *nullable.IPNetmask)
+       }
+
+       if nullable.LastUpdated == nil {
+               t.Error("nullable conversion gave nil LastUpdated")
+       } else if *nullable.LastUpdated != srv.LastUpdated {
+               t.Errorf("Incorrect LastUpdated after nullable conversion; 
want: '%s', got: '%s'", srv.LastUpdated, *nullable.LastUpdated)
+       }
+
+       if nullable.MgmtIPAddress == nil {
+               t.Error("nullable conversion gave nil MgmtIPAddress")
+       } else if *nullable.MgmtIPAddress != srv.MgmtIPAddress {
+               t.Errorf("Incorrect MgmtIPAddress after nullable conversion; 
want: '%s', got: '%s'", srv.MgmtIPAddress, *nullable.MgmtIPAddress)
+       }
+
+       if nullable.MgmtIPGateway == nil {
+               t.Error("nullable conversion gave nil MgmtIPGateway")
+       } else if *nullable.MgmtIPGateway != srv.MgmtIPGateway {
+               t.Errorf("Incorrect MgmtIPGateway after nullable conversion; 
want: '%s', got: '%s'", srv.MgmtIPGateway, *nullable.MgmtIPGateway)
+       }
+
+       if nullable.MgmtIPNetmask == nil {
+               t.Error("nullable conversion gave nil MgmtIPNetmask")
+       } else if *nullable.MgmtIPNetmask != srv.MgmtIPNetmask {
+               t.Errorf("Incorrect MgmtIPNetmask after nullable conversion; 
want: '%s', got: '%s'", srv.MgmtIPNetmask, *nullable.MgmtIPNetmask)
+       }
+
+       if nullable.OfflineReason == nil {
+               t.Error("nullable conversion gave nil OfflineReason")
+       } else if *nullable.OfflineReason != srv.OfflineReason {
+               t.Errorf("Incorrect OfflineReason after nullable conversion; 
want: '%s', got: '%s'", srv.OfflineReason, *nullable.OfflineReason)
+       }
+
+       if nullable.PhysLocation == nil {
+               t.Error("nullable conversion gave nil PhysLocation")
+       } else if *nullable.PhysLocation != srv.PhysLocation {
+               t.Errorf("Incorrect PhysLocation after nullable conversion; 
want: '%s', got: '%s'", srv.PhysLocation, *nullable.PhysLocation)
+       }
+
+       if nullable.PhysLocationID == nil {
+               t.Error("nullable conversion gave nil PhysLocationID")
+       } else if *nullable.PhysLocationID != srv.PhysLocationID {
+               t.Errorf("Incorrect PhysLocationID after nullable conversion; 
want: %d, got: %d", srv.PhysLocationID, *nullable.PhysLocationID)
+       }
+
+       if nullable.Profile == nil {
+               t.Error("nullable conversion gave nil Profile")
+       } else if *nullable.Profile != srv.Profile {
+               t.Errorf("Incorrect Profile after nullable conversion; want: 
'%s', got: '%s'", srv.Profile, *nullable.Profile)
+       }
+
+       if nullable.ProfileDesc == nil {
+               t.Error("nullable conversion gave nil ProfileDesc")
+       } else if *nullable.ProfileDesc != srv.ProfileDesc {
+               t.Errorf("Incorrect ProfileDesc after nullable conversion; 
want: '%s', got: '%s'", srv.ProfileDesc, *nullable.ProfileDesc)
+       }
+
+       if nullable.ProfileID == nil {
+               t.Error("nullable conversion gave nil ProfileID")
+       } else if *nullable.ProfileID != srv.ProfileID {
+               t.Errorf("Incorrect ProfileID after nullable conversion; want: 
%d, got: %d", srv.ProfileID, *nullable.ProfileID)
+       }
+
+       if nullable.Rack == nil {
+               t.Error("nullable conversion gave nil Rack")
+       } else if *nullable.Rack != srv.Rack {
+               t.Errorf("Incorrect Rack after nullable conversion; want: '%s', 
got: '%s'", srv.Rack, *nullable.Rack)
+       }
+
+       if nullable.RevalPending == nil {
+               t.Error("nullable conversion gave nil RevalPending")
+       } else if *nullable.RevalPending != srv.RevalPending {
+               t.Errorf("Incorrect RevalPending after nullable conversion; 
want: %t, got: %t", srv.RevalPending, *nullable.RevalPending)
+       }
+
+       if nullable.RouterHostName == nil {
+               t.Error("nullable conversion gave nil RouterHostName")
+       } else if *nullable.RouterHostName != srv.RouterHostName {
+               t.Errorf("Incorrect RouterHostName after nullable conversion; 
want: '%s', got: '%s'", srv.RouterHostName, *nullable.RouterHostName)
+       }
+
+       if nullable.RouterPortName == nil {
+               t.Error("nullable conversion gave nil RouterPortName")
+       } else if *nullable.RouterPortName != srv.RouterPortName {
+               t.Errorf("Incorrect RouterPortName after nullable conversion; 
want: '%s', got: '%s'", srv.RouterPortName, *nullable.RouterPortName)
+       }
+
+       if nullable.Status == nil {
+               t.Error("nullable conversion gave nil Status")
+       } else if *nullable.Status != srv.Status {
+               t.Errorf("Incorrect Status after nullable conversion; want: 
'%s', got: '%s'", srv.Status, *nullable.Status)
+       }
+
+       if nullable.StatusID == nil {
+               t.Error("nullable conversion gave nil StatusID")
+       } else if *nullable.StatusID != srv.StatusID {
+               t.Errorf("Incorrect StatusID after nullable conversion; want: 
%d, got: %d", srv.StatusID, *nullable.StatusID)
+       }
+
+       if nullable.TCPPort == nil {
+               t.Error("nullable conversion gave nil TCPPort")
+       } else if *nullable.TCPPort != srv.TCPPort {
+               t.Errorf("Incorrect TCPPort after nullable conversion; want: 
%d, got: %d", srv.TCPPort, *nullable.TCPPort)
+       }
+
+       if nullable.Type != srv.Type {
+               t.Errorf("Incorrect Type after nullable conversion; want: '%s', 
got: '%s'", srv.Type, nullable.Type)
+       }
+
+       if nullable.TypeID == nil {
+               t.Error("nullable conversion gave nil TypeID")
+       } else if *nullable.TypeID != srv.TypeID {
+               t.Errorf("Incorrect TypeID after nullable conversion; want: %d, 
got: %d", srv.TypeID, *nullable.TypeID)
+       }
+
+       if nullable.UpdPending == nil {
+               t.Error("nullable conversion gave nil UpdPending")
+       } else if *nullable.UpdPending != srv.UpdPending {
+               t.Errorf("Incorrect UpdPending after nullable conversion; want: 
%t, got: %t", srv.UpdPending, *nullable.UpdPending)
+       }
+
+       if nullable.XMPPID == nil {
+               t.Error("nullable conversion gave nil XMPPID")
+       } else if *nullable.XMPPID != srv.XMPPID {
+               t.Errorf("Incorrect XMPPID after nullable conversion; want: 
'%s', got: '%s'", srv.XMPPID, *nullable.XMPPID)
+       }
+
+       if nullable.XMPPPasswd == nil {
+               t.Error("nullable conversion gave nil XMPPPasswd")
+       } else if *nullable.XMPPPasswd != srv.XMPPPasswd {
+               t.Errorf("Incorrect XMPPPasswd after nullable conversion; want: 
'%s', got: '%s'", srv.XMPPPasswd, *nullable.XMPPPasswd)
+       }
+}
+
+func TestServerNullableV2_Upgrade(t *testing.T) {
+       fqdn := "testFQDN"
+       srv := Server{
+               Cachegroup:       "testCachegroup",
+               CachegroupID:     42,
+               CDNID:            43,
+               CDNName:          "testCDNName",
+               DeliveryServices: map[string][]string{"test": 
[]string{"quest"}},
+               DomainName:       "testDomainName",
+               FQDN:             &fqdn,
+               FqdnTime:         time.Now(),
+               GUID:             "testGUID",
+               HostName:         "testHostName",
+               HTTPSPort:        -1,
+               ID:               44,
+               ILOIPAddress:     "testILOIPAddress",
+               ILOIPGateway:     "testILOIPGateway",
+               ILOIPNetmask:     "testILOIPNetmask",
+               ILOPassword:      "testILOPassword",
+               ILOUsername:      "testILOUsername",
+               InterfaceMtu:     2,
+               InterfaceName:    "testInterfaceName",
+               IP6Address:       "::1/64",
+               IP6IsService:     true,
+               IP6Gateway:       "::2",
+               IPAddress:        "0.0.0.1",
+               IPIsService:      false,
+               IPGateway:        "0.0.0.2",
+               IPNetmask:        "255.255.255.0",
+               LastUpdated:      TimeNoMod(Time{Time: 
time.Now().Add(time.Minute), Valid: true}),
+               MgmtIPAddress:    "testMgmtIPAddress",
+               MgmtIPGateway:    "testMgmtIPGateway",
+               MgmtIPNetmask:    "testMgmtIPNetmask",
+               OfflineReason:    "testOfflineReason",
+               PhysLocation:     "testPhysLocation",
+               PhysLocationID:   45,
+               Profile:          "testProfile",
+               ProfileDesc:      "testProfileDesc",
+               ProfileID:        46,
+               Rack:             "testRack",
+               RevalPending:     true,
+               RouterHostName:   "testRouterHostName",
+               RouterPortName:   "testRouterPortName",
+               Status:           "testStatus",
+               StatusID:         47,
+               TCPPort:          -3,
+               Type:             "testType",
+               TypeID:           48,
+               UpdPending:       false,
+               XMPPID:           "testXMPPID",
+               XMPPPasswd:       "testXMPPasswd",
+       }
+
+       // this is so much easier than double the lines to manually construct a
+       // nullable v2 server
+       nullable := srv.ToNullable()
+
+       upgraded, err := nullable.Upgrade()
+       if err != nil {
+               t.Fatalf("Unexpected error upgrading server: %v", err)
+       }
+
+       if nullable.Cachegroup == nil {
+               t.Error("Unexpectedly nil Cachegroup in nullable-converted 
server")
+       } else if upgraded.Cachegroup == nil {
+               t.Error("upgraded conversion gave nil Cachegroup")
+       } else if *upgraded.Cachegroup != *nullable.Cachegroup {
+               t.Errorf("Incorrect Cachegroup after upgraded conversion; want: 
'%s', got: '%s'", *nullable.Cachegroup, *upgraded.Cachegroup)
+       }
+
+       if nullable.CachegroupID == nil {
+               t.Error("Unexpectedly nil CachegroupID in nullable-converted 
server")
+       } else if upgraded.CachegroupID == nil {
+               t.Error("upgraded conversion gave nil CachegroupID")
+       } else if *upgraded.CachegroupID != *nullable.CachegroupID {
+               t.Errorf("Incorrect CachegroupID after upgraded conversion; 
want: %d, got: %d", *nullable.CachegroupID, *upgraded.CachegroupID)
+       }
+
+       if nullable.CDNID == nil {
+               t.Error("Unexpectedly nil CDNID in nullable-converted server")
+       } else if upgraded.CDNID == nil {
+               t.Error("upgraded conversion gave nil CDNID")
+       } else if *upgraded.CDNID != *nullable.CDNID {
+               t.Errorf("Incorrect CDNID after upgraded conversion; want: %d, 
got: %d", *nullable.CDNID, *upgraded.CDNID)
+       }
+
+       if nullable.CDNName == nil {
+               t.Error("Unexpectedly nil CDNName in nullable-converted server")
+       } else if upgraded.CDNName == nil {
+               t.Error("upgraded conversion gave nil CDNName")
+       } else if *upgraded.CDNName != *nullable.CDNName {
+               t.Errorf("Incorrect CDNName after upgraded conversion; want: 
'%s', got: '%s'", *nullable.CDNName, *upgraded.CDNName)
+       }
+
+       if nullable.DeliveryServices == nil {
+               t.Error("Unexpectedly nil DeliveryServices in 
nullable-converted server")
+       } else if upgraded.DeliveryServices == nil {
+               t.Error("upgraded conversion gave nil DeliveryServices")
+       } else if len(*upgraded.DeliveryServices) != 
len(*nullable.DeliveryServices) {
+               t.Errorf("Incorrect number of DeliveryServices after upgraded 
conversion; want: %d, got: %d", len(*nullable.DeliveryServices), 
len(*upgraded.DeliveryServices))
+       } else {
+               for k, v := range *nullable.DeliveryServices {
+                       upgradedV, ok := (*upgraded.DeliveryServices)[k]
+                       if !ok {
+                               t.Errorf("Missing Delivery Service '%s' after 
upgraded conversion", k)
+                               continue
+                       }
+                       if len(upgradedV) != len(v) {
+                               t.Errorf("Delivery Service '%s' has incorrect 
length after upgraded conversion; want: %d, got: %d", k, len(v), len(upgradedV))
+                       }
+                       for i, ds := range v {
+                               upgradedDS := upgradedV[i]
+                               if upgradedDS != ds {
+                                       t.Errorf("Incorrect value at position 
%d in Delivery Service '%s' after upgraded conversion; want: '%s', got: '%s'", 
i, k, ds, upgradedDS)
+                               }
+                       }
+               }
+       }
+
+       if nullable.DomainName == nil {
+               t.Error("Unexpectedly nil DomainName in nullable-converted 
server")
+       } else if upgraded.DomainName == nil {
+               t.Error("upgraded conversion gave nil DomainName")
+       } else if *upgraded.DomainName != *nullable.DomainName {
+               t.Errorf("Incorrect DomainName after upgraded conversion; want: 
'%s', got: '%s'", *nullable.DomainName, *upgraded.DomainName)
+       }
+
+       if nullable.FQDN == nil {
+               t.Error("Unexpectedly nil FQDN in nullable-converted server")
+       } else if upgraded.FQDN == nil {
+               t.Error("upgraded conversion gave nil FQDN")
+       } else if *upgraded.FQDN != fqdn {
+               t.Errorf("Incorrect FQDN after upgraded conversion; want: '%s', 
got: '%s'", fqdn, *upgraded.FQDN)
+       }
+
+       if upgraded.FqdnTime != nullable.FqdnTime {
+               t.Errorf("Incorrect FqdnTime after upgraded conversion; want: 
'%s', got: '%s'", nullable.FqdnTime, upgraded.FqdnTime)
+       }
+
+       if nullable.GUID == nil {
+               t.Error("Unexpectedly nil GUID in nullable-converted server")
+       } else if upgraded.GUID == nil {
+               t.Error("upgraded conversion gave nil GUID")
+       } else if *upgraded.GUID != *nullable.GUID {
+               t.Errorf("Incorrect GUID after upgraded conversion; want: '%s', 
got: '%s'", *nullable.GUID, *upgraded.GUID)
+       }
+
+       if nullable.HostName == nil {
+               t.Error("Unexpectedly nil HostName in nullable-converted 
server")
+       } else if upgraded.HostName == nil {
+               t.Error("upgraded conversion gave nil HostName")
+       } else if *upgraded.HostName != *nullable.HostName {
+               t.Errorf("Incorrect HostName after upgraded conversion; want: 
'%s', got: '%s'", *nullable.HostName, *upgraded.HostName)
+       }
+
+       if nullable.HTTPSPort == nil {
+               t.Error("Unexpectedly nil HTTPSPort in nullable-converted 
server")
+       } else if upgraded.HTTPSPort == nil {
+               t.Error("upgraded conversion gave nil HTTPSPort")
+       } else if *upgraded.HTTPSPort != *nullable.HTTPSPort {
+               t.Errorf("Incorrect HTTPSPort after upgraded conversion; want: 
%d, got: %d", *nullable.HTTPSPort, *upgraded.HTTPSPort)
+       }
+
+       if nullable.ID == nil {
+               t.Error("Unexpectedly nil ID in nullable-converted server")
+       } else if upgraded.ID == nil {
+               t.Error("upgraded conversion gave nil ID")
+       } else if *upgraded.ID != *nullable.ID {
+               t.Errorf("Incorrect ID after upgraded conversion; want: %d, 
got: %d", *nullable.ID, *upgraded.ID)
+       }
+
+       if nullable.ILOIPAddress == nil {
+               t.Error("Unexpectedly nil ILOIPAddress in nullable-converted 
server")
+       } else if upgraded.ILOIPAddress == nil {
+               t.Error("upgraded conversion gave nil ILOIPAddress")
+       } else if *upgraded.ILOIPAddress != *nullable.ILOIPAddress {
+               t.Errorf("Incorrect ILOIPAddress after upgraded conversion; 
want: '%s', got: '%s'", *nullable.ILOIPAddress, *upgraded.ILOIPAddress)
+       }
+
+       if nullable.ILOIPGateway == nil {
+               t.Error("Unexpectedly nil ILOIPGateway in nullable-converted 
server")
+       } else if upgraded.ILOIPGateway == nil {
+               t.Error("upgraded conversion gave nil ILOIPGateway")
+       } else if *upgraded.ILOIPGateway != *nullable.ILOIPGateway {
+               t.Errorf("Incorrect ILOIPGateway after upgraded conversion; 
want: '%s', got: '%s'", *nullable.ILOIPGateway, *upgraded.ILOIPGateway)
+       }
+
+       if nullable.ILOIPNetmask == nil {
+               t.Error("Unexpectedly nil ILOIPNetmask in nullable-converted 
server")
+       } else if upgraded.ILOIPNetmask == nil {
+               t.Error("upgraded conversion gave nil ILOIPNetmask")
+       } else if *upgraded.ILOIPNetmask != *nullable.ILOIPNetmask {
+               t.Errorf("Incorrect ILOIPNetmask after upgraded conversion; 
want: '%s', got: '%s'", *nullable.ILOIPNetmask, *upgraded.ILOIPNetmask)
+       }
+
+       if nullable.ILOPassword == nil {
+               t.Error("Unexpectedly nil ILOPassword in nullable-converted 
server")
+       } else if upgraded.ILOPassword == nil {
+               t.Error("upgraded conversion gave nil ILOPassword")
+       } else if *upgraded.ILOPassword != *nullable.ILOPassword {
+               t.Errorf("Incorrect ILOPassword after upgraded conversion; 
want: '%s', got: '%s'", *nullable.ILOPassword, *upgraded.ILOPassword)
+       }
+
+       if nullable.ILOUsername == nil {
+               t.Error("Unexpectedly nil ILOUsername in nullable-converted 
server")
+       } else if upgraded.ILOUsername == nil {
+               t.Error("upgraded conversion gave nil ILOUsername")
+       } else if *upgraded.ILOUsername != *nullable.ILOUsername {
+               t.Errorf("Incorrect ILOUsername after upgraded conversion; 
want: '%s', got: '%s'", *nullable.ILOUsername, *upgraded.ILOUsername)
+       }
+
+       checkInterfaces := true
+       if nullable.InterfaceMtu == nil {
+               t.Error("Unexpectedly nil InterfaceMtu in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.InterfaceName == nil {
+               t.Error("Unexpectedly nil InterfaceName in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IP6Address == nil {
+               t.Error("Unexpectedly nil IP6Address in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IP6IsService == nil {
+               t.Error("Unexpectedly nil IP6IsService in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IP6Gateway == nil {
+               t.Error("Unexpectedly nil IP6Gateway in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IPAddress == nil {
+               t.Error("Unexpectedly nil IPAddress in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IPIsService == nil {
+               t.Error("Unexpectedly nil IPIsService in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IPGateway == nil {
+               t.Error("Unexpectedly nil IPGateway in nullable-converted 
server")
+               checkInterfaces = false
+       }
+       if nullable.IPNetmask == nil {
+               t.Error("Unexpectedly nil IPNetmask in nullable-converted 
server")
+               checkInterfaces = false
+       }
+
+       if checkInterfaces {
+               infLen := len(upgraded.Interfaces)
+               if infLen < 1 {

Review comment:
       we could, but one of those cases is recoverable, whereas the other is 
not. IDK if it necessarily holds, though that the tests in the recoverable case 
are any use. I thought so, but I could see why you wouldn't.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to