You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafficcontrol.apache.org by GitBox <gi...@apache.org> on 2022/05/25 15:50:34 UTC

[GitHub] [trafficcontrol] ocket8888 commented on a diff in pull request #6851: Refactor Servers Test

ocket8888 commented on code in PR #6851:
URL: https://github.com/apache/trafficcontrol/pull/6851#discussion_r881793648


##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)

Review Comment:
   This should use `ServerV3`, so it's testing the latest minor version of the API and not pinned to 3.0, since that's what the client will actually use.



##########
traffic_ops/testing/api/v4/servers_test.go:
##########
@@ -16,1437 +16,643 @@ package v4
 */
 
 import (
-	"fmt"
+	"encoding/json"
 	"net/http"
 	"net/url"
-	"reflect"
 	"strconv"
 	"strings"
 	"testing"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 	client "github.com/apache/trafficcontrol/traffic_ops/v4-client"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileID(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-		GetServersForNonExistentDeliveryService(t)
-		CUDServerWithLocks(t)
-		GetTestPaginationSupportServers(t)
-	})
-}
-
-func CUDServerWithLocks(t *testing.T) {
-	resp, _, err := TOSession.GetTenants(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not GET tenants: %v", err)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatalf("didn't get any tenant in response")
-	}
-
-	// Create a new user with operations level privileges
-	user1 := tc.UserV4{
-		Username:             "lock_user1",
-		RegistrationSent:     new(time.Time),
-		LocalPassword:        util.StrPtr("test_pa$$word"),
-		ConfirmLocalPassword: util.StrPtr("test_pa$$word"),
-		Role:                 "operations",
-	}
-	user1.Email = util.StrPtr("lockuseremail@domain.com")
-	user1.TenantID = resp.Response[0].ID
-	user1.FullName = util.StrPtr("firstName LastName")
-	_, _, err = TOSession.CreateUser(user1, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create test user with username: %s", user1.Username)
-	}
-	defer ForceDeleteTestUsersByUsernames(t, []string{"lock_user1"})
-
-	// Establish a session with the newly created non admin level user
-	userSession, _, err := client.LoginWithAgent(Config.TrafficOps.URL, user1.Username, *user1.LocalPassword, true, "to-api-v4-client-tests", false, toReqTimeout)
-	if err != nil {
-		t.Fatalf("could not login with user lock_user1: %v", err)
-	}
-	if len(testData.Servers) == 0 {
-		t.Fatalf("no servers to run the test on, quitting")
-	}
-
-	server := testData.Servers[0]
-	server.HostName = util.StrPtr("cdn_locks_test_server")
-	server.Interfaces = []tc.ServerInterfaceInfoV40{
-		{
-			ServerInterfaceInfo: tc.ServerInterfaceInfo{
-				IPAddresses: []tc.ServerIPAddress{
-					{
-						Address:        "123.32.43.21",
-						Gateway:        util.StrPtr("100.100.100.100"),
-						ServiceAddress: true,
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V4TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {tomorrow}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"hostName": {"atlanta-edge-01"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cachegroupName": {"topology-mid-cg-01"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments", "test-mso-org-01"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILENAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"profileName": {"EDGE1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"status": {"REPORTED"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"topology": {"mso-topology"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1", "test-mso-org-01"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"type": {"EDGE"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+				"EMPTY RESPONSE when INVALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {"999999"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(0)),
+				},
+				"FIRST RESULT when LIMIT=1": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("limit")),
+				},
+				"SECOND RESULT when LIMIT=1 OFFSET=1": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "offset": {"1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("offset")),
+				},
+				"SECOND RESULT when LIMIT=1 PAGE=2": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "page": {"2"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("page")),
+				},
+				"BAD REQUEST when INVALID LIMIT parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"-2"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID OFFSET parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "offset": {"0"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID PAGE parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "page": {"0"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILENAMES": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileNames": []string{""}}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileNames":   []string{"EDGE1"},
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
 					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY ORG SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-mso-org-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-mso-org-01")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileNames": []string{"MID1"},
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileNames": []string{"CDN2_MID"},
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestOpts:  client.RequestOptions{Header: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}}},
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {currentTimeRFC}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
 				},
-				MaxBandwidth: util.Uint64Ptr(2500),
-				Monitor:      true,
-				MTU:          util.Uint64Ptr(1500),
-				Name:         "cdn_locks_interfaceName",
 			},
-			RouterHostName: "router1",
-			RouterPortName: "9090",
-		},
-	}
-	// Create a lock for this user
-	_, _, err = userSession.CreateCDNLock(tc.CDNLock{
-		CDN:     *server.CDNName,
-		Message: util.StrPtr("test lock"),
-		Soft:    util.BoolPtr(false),
-	}, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldn't create cdn lock: %v", err)
-	}
-	// Try to create a new server on a CDN that another user has a hard lock on -> this should fail
-	_, reqInf, err := TOSession.CreateServer(server, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while creating a new server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while creating a new server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to create a new profile on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.CreateServer(server, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while creating a new server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", *server.HostName)
-	servers, _, err := userSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("couldn't get server: %v", err)
-	}
-	if len(servers.Response) != 1 {
-		t.Fatal("couldn't get exactly one server in the response, quitting")
-	}
-	serverID := servers.Response[0].ID
-	// Try to update a server on a CDN that another user has a hard lock on -> this should fail
-	servers.Response[0].DomainName = util.StrPtr("changed_domain_name")
-	_, reqInf, err = TOSession.UpdateServer(*serverID, servers.Response[0], client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while updating a server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while updating a server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to update a server on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.UpdateServer(*serverID, servers.Response[0], client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while updating a server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	// Try to delete a server on a CDN that another user has a hard lock on -> this should fail
-	_, reqInf, err = TOSession.DeleteServer(*serverID, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while deleting a server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while deleting a server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to delete a server on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.DeleteServer(*serverID, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while deleting a server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	// Delete the lock
-	_, _, err = userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: url.Values{"cdn": []string{*server.CDNName}}})
-	if err != nil {
-		t.Errorf("expected no error while deleting other user's lock using admin endpoint, but got %v", err)
-	}
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("name", cdnName)
-	cdns, _, err := TOSession.GetCDNs(opts)
-	if err != nil {
-		t.Fatalf("unable to get CDN '%s': %v - alerts: %+v", cdnName, err, cdns.Alerts)
-	}
-	if len(cdns.Response) < 1 {
-		t.Fatalf("Expected exactly one CDN to exist with name '%s', found: %d", cdnName, len(cdns.Response))
-	}
-	cdnID := cdns.Response[0].ID
-
-	serverOpts := client.NewRequestOptions()
-	serverOpts.QueryParameters.Add("cachegroupName", cacheGroupName)
-	serverOpts.QueryParameters.Add("topology", topologyName)
-	serverOpts.QueryParameters.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServers(serverOpts)
-	if err != nil {
-		t.Fatalf("getting server from CDN '%s', from Cache Group '%s', and in Topology '%s': %v - alerts: %+v", cdnName, cacheGroupName, topologyName, err, servers.Alerts)
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	if server.ID == nil || server.CDNID == nil || len(server.ProfileNames) == 0 || server.CachegroupID == nil || server.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined ID and/or CDN ID and/or Profile Names and/or Cache Group ID and/or Host Name")
-	}
-
-	_, reqInf, err := TOSession.DeleteServer(*server.ID, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	opts.QueryParameters.Set("name", "cdn1")
-	cdns, _, err = TOSession.GetCDNs(opts)
-	if err != nil {
-		t.Fatalf("unable to get CDN 'cdn1': %v - alerts: %+v", err, cdns.Alerts)
-	}
-	if len(cdns.Response) < 1 {
-		t.Fatalf("Expected exactly one CDN to exist with name 'cdn1', found: %d", len(cdns.Response))
-	}
-	newCDNID := cdns.Response[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	opts.QueryParameters.Set("name", "MID1")
-	profiles, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Errorf("unable to get Profile 'MID1': %v - alerts: %+v", err, profiles.Alerts)
-	}
-	if len(profiles.Response) != 1 {
-		t.Fatalf("Expected exactly one Profile to exist with name 'MID1', found: %d", len(profiles.Response))
-	}
-	newProfileID := profiles.Response[0].ID
-	oldProfileName := server.ProfileNames[0]
-
-	opts.QueryParameters.Set("id", strconv.Itoa(newProfileID))
-	nps, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Fatalf("failed to query profiles: %v", err)
-	}
-	if len(nps.Response) != 1 {
-		t.Fatalf("Expected exactly one Profile to exist, found: %d", len(profiles.Response))
-	}
-	server.ProfileNames = []string{nps.Response[0].Name}
-	opts.QueryParameters.Del("id")
-
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileNames = []string{oldProfileName}
-
-	opts.QueryParameters.Set("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %v - alerts: %+v", moveToCacheGroup, err, cgs.Alerts)
-	}
-	if len(cgs.Response) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs.Response))
-	}
-	if cgs.Response[0].ID == nil {
-		t.Fatalf("Traffic Ops responded with Cache Group '%s' that had null or undefined ID", moveToCacheGroup)
-	}
-
-	alerts, _, err := TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different Cache Group: %v - alerts: %+v", *server.HostName, err, alerts.Alerts)
-	}
-
-	*server.CachegroupID = *cgs.Response[0].ID
-	alerts, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %v - alerts: %+v", *server.ID, reqInf.StatusCode, err, alerts.Alerts)
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by hostname '%s': %v - alerts %+v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil || remoteServer.HostName == nil || remoteServer.StatusLastUpdated == nil {
-		t.Fatalf("Traffic Ops returned a representation for server '%s' with null or undefined ID and/or Host Name and/or Status Last Updated time", hostName)
-	}
-	id := fmt.Sprintf("%v", *remoteServer.ID)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatuses(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot get Statuses: %v - alerts: %+v", err, statuses.Alerts)
-	}
-	for _, status := range statuses.Response {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - alerts: %+v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("id", id)
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server #%s by ID: %v - alerts %+v", id, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot update Server #%d (hostname '%s'): %v - alerts %+v", *remoteServer.ID, hostName, err, alerts.Alerts)
-	}
-
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot update Server by ID %d (hostname '%s'): %v - alerts: %+v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server by ID %d: %v - alerts: %+v", *remoteServer.ID, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-}
-
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Add("hostName", hostName)
-	opts.Header = header
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by hostname '%s': %v - alerts: %+v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null or undefined ID for server '%s'", hostName)
-	}
 
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV4{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServers(testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServer(server, testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServer(testCase.EndpointId(), server, testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServer(testCase.EndpointId(), testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	opts.QueryParameters = nil
-	_, reqInf, err := TOSession.UpdateServer(*remoteServer.ID, remoteServer, opts)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
-	}
+	})
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	opts := client.NewRequestOptions()
-	opts.Header = header
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileNames":
+					assert.Exactly(t, expected, server.ProfileNames, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileNames)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
 		}
 	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
+}
 
-	opts.Header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostname string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("hostName", hostname)
+		servers, _, err := TOSession.GetServers(opts)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-
-	opts := client.NewRequestOptions()
-	opts.Header.Set(rfc.IfModifiedSince, timestamp)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostnames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostnames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServer(server, client.RequestOptions{})
-		if err != nil {
-			t.Errorf("could not create server '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		for _, server := range serverResp {
+			if server.Type == tc.CacheTypeMid.String() {
+				t.Errorf("Expected to find no %s-typed servers but found server %s", tc.CacheTypeMid, *server.HostName)
+			}
 		}
 	}
 }
 
-func CreateTestBlankFields(t *testing.T) {
-	serverResp, _, err := TOSession.GetServers(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldnt get servers: %v - alerts: %+v", err, serverResp.Alerts)
-	}
-	if len(serverResp.Response) < 1 {
-		t.Fatal("expected at least one server")
-	}
-	server := serverResp.Response[0]
-	if server.ID == nil {
-		t.Fatal("Traffic Ops returned a representation for a servver with null or undefined ID")
-	}
-	originalHost := server.HostName
-
-	server.HostName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Error("should not be able to update server with blank HostName")
-	}
+func validateServerPagination(paginationParam string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		paginationResp := resp.([]tc.ServerV40)
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("orderby", "id")
+		respBase, _, err := TOSession.GetServers(opts)
+		assert.RequireNoError(t, err, "Cannot get Servers: %v - alerts: %+v", err, respBase.Alerts)
 
-	server.HostName = originalHost
-	server.DomainName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Error("should not be able to update server with blank DomainName")
+		ds := respBase.Response
+		assert.RequireGreaterOrEqual(t, len(ds), 3, "Need at least 3 Servers in Traffic Ops to test pagination support, found: %d", len(ds))
+		switch paginationParam {
+		case "limit:":
+			assert.Exactly(t, ds[:1], paginationResp, "expected GET Servers with limit = 1 to return first result")
+		case "offset":
+			assert.Exactly(t, ds[1:2], paginationResp, "expected GET Servers with limit = 1, offset = 1 to return second result")
+		case "page":
+			assert.Exactly(t, ds[1:2], paginationResp, "expected GET Servers with limit = 1, page = 2 to return second result")
+		}
 	}
 }
 
-// This test will break if the structure of the test data servers collection
-// is changed at all.
-func CreateTestServerWithoutProfileID(t *testing.T) {
-	if len(testData.Servers) < 20 {
-		t.Fatal("Need at least 20 servers to test creating a server without a Profile")
-	}
-	testServer := testData.Servers[19]
-	if testServer.HostName == nil {
-		t.Fatal("Found a server in the test data with null or undefined Host Name")
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", *testServer.HostName)
-
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by Host Name '%s': %v - alerts: %+v", *testServer.HostName, err, resp.Alerts)
-	}
-
-	server := resp.Response[0]
-	if len(server.ProfileNames) == 0 || server.ID == nil || server.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation of a server with null or undefined ID and/or Profile and/or Host Name")
-	}
-	originalProfile := server.ProfileNames
-	delResp, _, err := TOSession.DeleteServer(*server.ID, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot delete Server by ID %d: %v - %v", *server.ID, err, delResp)
-	}
-
-	server.ProfileNames = []string{""}
-	_, reqInfo, _ := TOSession.CreateServer(server, client.RequestOptions{})
-	if reqInfo.StatusCode != 400 {
-		t.Fatalf("Expected status code: %v but got: %v", "400", reqInfo.StatusCode)
-	}
-
-	//Reverting it back for further tests
-	server.ProfileNames = originalProfile
-	response, _, err := TOSession.CreateServer(server, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create server: %v - alerts: %+v", err, response.Alerts)
-	}
+func generateServer(t *testing.T, requestServer map[string]interface{}) map[string]interface{} {
+	// map for the most basic Server a user can create
+	genericServer := map[string]interface{}{
+		"cdnId":        GetCDNId(t, "cdn1"),
+		"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+		"domainName":   "localhost",
+		"hostName":     "testserver",
+		"interfaces": []map[string]interface{}{{
+			"ipAddresses": []map[string]interface{}{{
+				"address":        "127.0.0.1",
+				"serviceAddress": true,
+			}},
+			"name": "eth0",
+		}},
+		"physLocationId": GetPhysLocationId(t, "Denver")(),
+		"profileNames":   []string{"EDGE1"},
+		"statusId":       GetStatusId(t, "REPORTED")(),
+		"typeId":         GetTypeId(t, "EDGE"),
+	}
+
+	for k, v := range requestServer {
+		genericServer[k] = v
+	}
+	return genericServer
 }
 
-func GetTestServers(t *testing.T) {
-	opts := client.NewRequestOptions()
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, _, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Errorf("cannot get Server by Host Name '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
-		} else if resp.Summary.Count != 1 {
-			t.Errorf("incorrect server count, expected: 1, actual: %d", resp.Summary.Count)
-		}
+func GetServerId(t *testing.T, hostName string) func() int {

Review Comment:
   func `GetServerId` should be `GetServerID`



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)

Review Comment:
   Also there are a lot of dereferences here with no `nil` checks, which could crash the test if Traffic Ops gives bad responses.



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostNames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServerWithHdr(server, nil)
-		t.Log("Response: ", *server.HostName, " ", resp)
-		if err != nil {
-			t.Errorf("could not CREATE servers: %v", err)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for _, server := range serverResp {
+			if server.Type == tc.CacheTypeMid.String() {
+				t.Errorf("Expected to find no %s-typed servers but found server %s", tc.CacheTypeMid, *server.HostName)
+			}
 		}
 	}
 }
 
-func CreateTestBlankFields(t *testing.T) {
-	serverResp, _, err := TOSession.GetServersWithHdr(nil, nil)
-	if err != nil {
-		t.Fatalf("couldnt get servers: %v", err)
-	}
-	if len(serverResp.Response) < 1 {
-		t.Fatal("expected at least one server")
-	}
-	server := serverResp.Response[0]
-	originalHost := server.HostName
-
-	server.HostName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatal("should not be able to update server with blank HostName")
-	}
-
-	server.HostName = originalHost
-	server.DomainName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatal("should not be able to update server with blank DomainName")
-	}
+func generateServer(t *testing.T, requestServer map[string]interface{}) map[string]interface{} {
+	// map for the most basic Server a user can create
+	genericServer := map[string]interface{}{
+		"cdnId":        GetCDNId(t, "cdn1"),
+		"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+		"domainName":   "localhost",
+		"hostName":     "testserver",
+		"interfaces": []map[string]interface{}{{
+			"ipAddresses": []map[string]interface{}{{
+				"address":        "127.0.0.1",
+				"serviceAddress": true,
+			}},
+			"name": "eth0",
+		}},
+		"physLocationId": GetPhysLocationId(t, "Denver")(),
+		"profileId":      GetProfileId(t, "EDGE1"),
+		"statusId":       GetStatusId(t, "REPORTED")(),
+		"typeId":         GetTypeId(t, "EDGE"),
+	}
+
+	for k, v := range requestServer {
+		genericServer[k] = v
+	}
+	return genericServer
 }
-func CreateTestServerWithoutProfileId(t *testing.T) {
-	params := url.Values{}
-	servers := testData.Servers[19]
-	params.Set("hostName", *servers.HostName)
 
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by name '%s': %v - %v", *servers.HostName, err, resp.Alerts)
-	}
-
-	server := resp.Response[0]
-	originalProfile := *server.Profile
-	delResp, _, err := TOSession.DeleteServerByID(*server.ID)
-	if err != nil {
-		t.Fatalf("cannot DELETE Server by ID %d: %v - %v", *server.ID, err, delResp)
-	}
-
-	*server.Profile = ""
-	server.ProfileID = nil
-	response, reqInfo, errs := TOSession.CreateServerWithHdr(server, nil)
-	t.Log("Response: ", *server.HostName, " ", response)
-	if reqInfo.StatusCode != 400 {
-		t.Fatalf("Expected status code: %v but got: %v", "400", reqInfo.StatusCode)
-	}
-
-	//Reverting it back for further tests
-	*server.Profile = originalProfile
-	response, _, errs = TOSession.CreateServerWithHdr(server, nil)
-	t.Log("Response: ", *server.HostName, " ", response)
-	if errs != nil {
-		t.Fatalf("could not CREATE servers: %v", errs)
+func GetServerId(t *testing.T, hostName string) func() int {
+	return func() int {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		serversResp, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.RequireNoError(t, err, "Get Servers Request failed with error:", err)
+		assert.RequireEqual(t, 1, len(serversResp.Response), "Expected response object length 1, but got %d", len(serversResp.Response))
+		assert.RequireNotNil(t, serversResp.Response[0].ID, "Expected id to not be nil")
+		return *serversResp.Response[0].ID
 	}
 }
 
-func GetTestServers(t *testing.T) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-		if err != nil {
-			t.Errorf("cannot GET Server by name '%s': %v - %v", *server.HostName, err, resp.Alerts)
-		} else if resp.Summary.Count != 1 {
-			t.Errorf("incorrect server count, expected: 1, actual: %d", resp.Summary.Count)
-
-		}
+func GetStatusId(t *testing.T, name string) func() int {
+	return func() int {
+		statusResp, _, err := TOSession.GetStatusByNameWithHdr(name, nil)
+		assert.NoError(t, err, "Get Statuses Request failed with error:", err)
+		assert.Equal(t, 1, len(statusResp), "Expected response object length 1, but got %d", len(statusResp))
+		assert.NotNil(t, statusResp[0].ID, "Expected id to not be nil")
+		return statusResp[0].ID
 	}
 }
 
-func GetTestServersDetails(t *testing.T) {
-
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.GetServerDetailsByHostNameWithHdr(*server.HostName, nil)
-		if err != nil {
-			t.Errorf("cannot GET Server Details by name: %v - %v", err, resp)
-		}
+func GetPhysLocationId(t *testing.T, name string) func() int {
+	return func() int {
+		physLocResp, _, err := TOSession.GetPhysLocationByNameWithHdr(name, nil)
+		assert.NoError(t, err, "Get PhysLocation Request failed with error:", err)
+		assert.Equal(t, 1, len(physLocResp), "Expected response object length 1, but got %d", len(physLocResp))
+		assert.NotNil(t, physLocResp[0].ID, "Expected id to not be nil")
+		return physLocResp[0].ID
 	}
 }
 
-func GetTestServersQueryParameters(t *testing.T) {
-	dses, _, err := TOSession.GetDeliveryServicesV30WithHdr(nil, url.Values{"xmlId": []string{"ds1"}})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v", err)
-	}
-	if len(dses) < 1 {
-		t.Fatal("Failed to get at least one Delivery Service")
-	}
+func UpdateTestServerStatusLastUpdated(t *testing.T) {
+	const hostName = "atl-edge-01"
 
-	ds := dses[0]
-	if ds.ID == nil {
-		t.Fatal("Got Delivery Service with nil ID")
-	}
-
-	AssignTestDeliveryService(t)
 	params := url.Values{}
-	params.Add("dsId", strconv.Itoa(*ds.ID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("Failed to get server by Delivery Service ID: %v", err)
-	}
-	if len(servers.Response) != 3 {
-		t.Fatalf("expected to get 3 servers for Delivery Service: %d, actual: %d", *ds.ID, len(servers.Response))
-	}
-
-	currentTime := time.Now().UTC().Add(5 * time.Second)
-	timestamp := currentTime.Format(time.RFC1123)
-	var header http.Header
-	header = make(map[string][]string)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	_, reqInf, _ := TOSession.GetServersWithHdr(&params, header)
-	if reqInf.StatusCode != http.StatusNotModified {
-		t.Errorf("Expected a status code of 304, got %v", reqInf.StatusCode)
-	}
-
-	dses, _, err = TOSession.GetDeliveryServicesV30WithHdr(nil, nil)
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v", err)
-	}
-
-	foundTopDs := false
-	const (
-		topDsXmlId = "ds-top"
-		topology   = "mso-topology"
-	)
-	for _, ds = range dses {
-		if ds.XMLID == nil || *ds.XMLID != topDsXmlId {
-			continue
-		}
-		foundTopDs = true
-		break
-	}
-	if !foundTopDs {
-		t.Fatalf("unable to find deliveryservice %s", topDsXmlId)
-	}
-
-	/* Create a deliveryservice server assignment that should not show up in the
-	 * client.GetServersWithHdr() response because ds-top is topology-based
-	 */
-	const otherServerHostname = "topology-edge-02"
-	serverResponse, _, err := TOSession.GetServersWithHdr(&url.Values{"hostName": []string{otherServerHostname}}, nil)
-	if err != nil {
-		t.Fatalf("getting server by hostname %s: %s", otherServerHostname, err)
-	}
-	if len(serverResponse.Response) != 1 {
-		t.Fatalf("unable to find server with hostname %s", otherServerHostname)
-	}
-	otherServer := serverResponse.Response[0]
-
-	dsTopologyField, dsFirstHeaderRewriteField, innerHeaderRewriteField, lastHeaderRewriteField := *ds.Topology, *ds.FirstHeaderRewrite, *ds.InnerHeaderRewrite, *ds.LastHeaderRewrite
-	ds.Topology, ds.FirstHeaderRewrite, ds.InnerHeaderRewrite, ds.LastHeaderRewrite = nil, nil, nil, nil
-	ds, _, err = TOSession.UpdateDeliveryServiceV30WithHdr(*ds.ID, ds, nil)
-	if err != nil {
-		t.Fatalf("unable to temporary remove topology-related fields from deliveryservice %s: %s", topDsXmlId, err)
-	}
-	_, _, err = TOSession.CreateDeliveryServiceServers(*ds.ID, []int{*otherServer.ID}, false)
-	if err != nil {
-		t.Fatalf("unable to assign server %s to deliveryservice %s: %s", *otherServer.HostName, topDsXmlId, err)
-	}
-	ds.Topology, ds.FirstHeaderRewrite, ds.InnerHeaderRewrite, ds.LastHeaderRewrite = &dsTopologyField, &dsFirstHeaderRewriteField, &innerHeaderRewriteField, &lastHeaderRewriteField
-	ds, _, err = TOSession.UpdateDeliveryServiceV30WithHdr(*ds.ID, ds, nil)
-	if err != nil {
-		t.Fatalf("unable to re-add topology-related fields to deliveryservice %s: %s", topDsXmlId, err)
-	}
-
-	params.Set("dsId", strconv.Itoa(*ds.ID))
-	expectedHostnames := map[string]bool{
-		"edge1-cdn1-cg3":                 false,
-		"edge2-cdn1-cg3":                 false,
-		"atlanta-mid-01":                 false,
-		"atlanta-mid-16":                 false,
-		"edgeInCachegroup3":              false,
-		"midInSecondaryCachegroupInCDN1": false,
-	}
-	response, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %s", topDsXmlId, err)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s: %s", topDsXmlId, err)
-	}
-	for _, server := range response.Response {
-		if _, exists := expectedHostnames[*server.HostName]; !exists {
-			t.Fatalf("expected hostnames %v, actual %s", expectedHostnames, *server.HostName)
-		}
-		expectedHostnames[*server.HostName] = true
-	}
-	var notInResponse []string
-	for hostName, inResponse := range expectedHostnames {
-		if !inResponse {
-			notInResponse = append(notInResponse, hostName)
-		}
-	}
-	if len(notInResponse) != 0 {
-		t.Fatalf("%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
-	}
-	const originHostname = "denver-mso-org-01"
-	if _, _, err = TOSession.AssignServersToDeliveryService([]string{originHostname}, topDsXmlId); err != nil {
-		t.Fatalf("assigning origin server %s to delivery service %s: %s", originHostname, topDsXmlId, err.Error())
-	}
-	response, _, err = TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %s", topDsXmlId, err)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s: %s", topDsXmlId, err)
-	}
-	containsOrigin := false
-	for _, server := range response.Response {
-		if *server.HostName != originHostname {
-			continue
-		}
-		containsOrigin = true
-		break
-	}
-	if !containsOrigin {
-		t.Fatalf("did not find origin server %s when querying servers by dsId after assigning %s to delivery service %s", originHostname, originHostname, topDsXmlId)
-	}
-
-	const topDsWithNoMids = "ds-based-top-with-no-mids"
-	dses, _, err = TOSession.GetDeliveryServicesV30WithHdr(nil, url.Values{"xmlId": []string{topDsWithNoMids}})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v", err)
-	}
-	if len(dses) < 1 {
-		t.Fatal("Failed to get at least one Delivery Service")
-	}
-
-	ds = dses[0]
-	if ds.ID == nil {
-		t.Fatal("Got Delivery Service with nil ID")
-	}
-	params.Set("dsId", strconv.Itoa(*ds.ID))
-
-	response, _, err = TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %s", topDsWithNoMids, err)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s: %s", topDsWithNoMids, err)
-	}
-	for _, server := range response.Response {
-		if tc.CacheTypeFromString(server.Type) == tc.CacheTypeMid {
-			t.Fatalf("Expected to find no %s-typed servers when querying servers by the ID for Delivery Service with XMLID %s but found %s-typed server %s", tc.CacheTypeMid, topDsWithNoMids, tc.CacheTypeMid, *server.HostName)
-		}
-	}
-
-	params.Del("dsId")
-	params.Add("topology", topology)
-	expectedHostnames = map[string]bool{
-		originHostname:                   false,
-		"denver-mso-org-02":              false,
-		"edge1-cdn1-cg3":                 false,
-		"edge2-cdn1-cg3":                 false,
-		"atlanta-mid-01":                 false,
-		"atlanta-mid-16":                 false,
-		"atlanta-mid-17":                 false,
-		"edgeInCachegroup3":              false,
-		"midInParentCachegroup":          false,
-		"midInSecondaryCachegroup":       false,
-		"midInSecondaryCachegroupInCDN1": false,
-	}
-	response, _, err = TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("Failed to get servers belonging to cachegroups in topology %s: %s", topology, err)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers belonging to cachegroups in topology %s: %s", topology, err)
-	}
-	for _, server := range response.Response {
-		if _, exists := expectedHostnames[*server.HostName]; !exists {
-			t.Fatalf("expected hostnames %v, actual %s", expectedHostnames, *server.HostName)
-		}
-		expectedHostnames[*server.HostName] = true
-	}
-	notInResponse = []string{}
-	for hostName, inResponse := range expectedHostnames {
-		if !inResponse {
-			notInResponse = append(notInResponse, hostName)
-		}
-	}
-	if len(notInResponse) != 0 {
-		t.Fatalf("%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
-	}
-	params.Del("topology")
-
-	resp, _, err := TOSession.GetServersWithHdr(nil, nil)
-	if err != nil {
-		t.Fatalf("Failed to get servers: %v", err)
-	}
-
-	if len(resp.Response) < 1 {
-		t.Fatalf("Failed to get at least one server")
-	}
-
-	s := resp.Response[0]
-
-	params.Add("type", s.Type)
-	if _, _, err := TOSession.GetServersWithHdr(&params, nil); err != nil {
-		t.Errorf("Error getting servers by type: %v", err)
-	}
-	params.Del("type")
-
-	if s.CachegroupID == nil {
-		t.Error("Found server with no Cache Group ID")
-	} else {
-		params.Add("cachegroup", strconv.Itoa(*s.CachegroupID))
-		if _, _, err := TOSession.GetServersWithHdr(&params, nil); err != nil {
-			t.Errorf("Error getting servers by Cache Group ID: %v", err)
-		}
-		params.Del("cachegroup")
-	}
-
-	if s.Status == nil {
-		t.Error("Found server with no status")
-	} else {
-		params.Add("status", *s.Status)
-		if _, _, err := TOSession.GetServersWithHdr(&params, nil); err != nil {
-			t.Errorf("Error getting servers by status: %v", err)
-		}
-		params.Del("status")
-	}
-
-	if s.ProfileID == nil {
-		t.Error("Found server with no Profile ID")
-	} else {
-		params.Add("profileId", strconv.Itoa(*s.ProfileID))
-		if _, _, err := TOSession.GetServersWithHdr(&params, nil); err != nil {
-			t.Errorf("Error getting servers by Profile ID: %v", err)
-		}
-		params.Del("profileId")
-	}
+	params.Set("hostName", hostName)
+	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
+	assert.RequireNoError(t, err, "Cannot get Server by hostname '%s': %v - alerts %+v", hostName, err, resp.Alerts)
+	assert.RequireGreaterOrEqual(t, len(resp.Response), 1, "Expected at least one server to exist by hostname '%s'", hostName)
+	assert.RequireNotNil(t, resp.Response[0].StatusLastUpdated, "Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
+	originalServer := resp.Response[0]
 
-	cgs, _, err := TOSession.GetCacheGroupsNullableWithHdr(nil)
-	if err != nil {
-		t.Fatalf("Failed to get Cache Groups: %v", err)
-	}
-	if len(cgs) < 1 {
-		t.Fatal("Failed to get at least one Cache Group")
-	}
-	if cgs[0].ID == nil {
-		t.Fatal("Cache Group found with no ID")
-	}
+	// Perform an update with no changes to status
+	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*originalServer.ID, originalServer, nil)
+	assert.RequireNoError(t, err, "Cannot UPDATE Server by ID %d (hostname '%s'): %v - alerts: %+v", *originalServer.ID, hostName, err, alerts)
 
-	params.Add("parentCacheGroup", strconv.Itoa(*cgs[0].ID))
-	if _, _, err = TOSession.GetServersWithHdr(&params, nil); err != nil {
-		t.Errorf("Error getting servers by parentCacheGroup: %v", err)
-	}
-	params.Del("parentCacheGroup")
-}
+	resp, _, err = TOSession.GetServersWithHdr(&params, nil)
+	assert.RequireNoError(t, err, "Cannot get Server by hostname '%s': %v - alerts %+v", hostName, err, resp.Alerts)
+	assert.RequireGreaterOrEqual(t, len(resp.Response), 1, "Expected at least one server to exist by hostname '%s'", hostName)
+	respServer := resp.Response[0]
+	assert.RequireNotNil(t, respServer.StatusLastUpdated, "Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
+	assert.Equal(t, *originalServer.StatusLastUpdated, *respServer.StatusLastUpdated, "Since status didnt change, no change in 'StatusLastUpdated' time was expected. "+
+		"old value: %v, new value: %v", *originalServer.StatusLastUpdated, *respServer.StatusLastUpdated)
 
-func UniqueIPProfileTestServers(t *testing.T) {
-	serversResp, _, err := TOSession.GetServersWithHdr(nil, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(serversResp.Response) < 1 {
-		t.Fatal("expected more than 0 servers")
-	}
-	xmppId := "unique"
-	var server tc.ServerV30
-	if len(serversResp.Response) == 0 {
-		t.Fatalf("no servers in response, quitting")
-	}
-	server = serversResp.Response[0]
+	// Changing the status, perform an update and make sure that statusLastUpdated changed
+	newStatusID := GetStatusId(t, "ONLINE")()
+	originalServer.StatusID = &newStatusID
 
-	_, _, err = TOSession.CreateServerWithHdr(tc.ServerV30{
-		CommonServerProperties: tc.CommonServerProperties{
-			Cachegroup: server.Cachegroup,
-			CDNName:    server.CDNName,
-			DomainName: util.StrPtr("mydomain"),
-			FQDN:       util.StrPtr("myfqdn"),
-			FqdnTime:   time.Time{},
-			HostName:   util.StrPtr("myhostname"),
-			HTTPSPort:  util.IntPtr(443),
-			LastUpdated: &tc.TimeNoMod{
-				Time:  time.Time{},
-				Valid: false,
-			},
-			PhysLocation: server.PhysLocation,
-			Profile:      server.Profile,
-			StatusID:     server.StatusID,
-			Type:         server.Type,
-			UpdPending:   util.BoolPtr(false),
-			XMPPID:       &xmppId,
-		},
-		Interfaces: server.Interfaces,
-	}, nil)
+	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*originalServer.ID, originalServer, nil)
+	assert.RequireNoError(t, err, "Cannot UPDATE Server by ID %d (hostname '%s'): %v - alerts: %+v", *originalServer.ID, hostName, err, alerts)
 
-	if err == nil {
-		t.Error("expected an error when updating a server with an ipaddress that already exists on another server with the same profile")
-		// Cleanup, don't want to break other tests
-		pathParams := url.Values{}
-		pathParams.Add("xmppid", xmppId)
-		server, _, err := TOSession.GetServersWithHdr(&pathParams, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
-		_, _, err = TOSession.DeleteServerByID(*server.Response[0].ID)
-		if err != nil {
-			t.Fatalf("unable to delete server: %v", err)
-		}
-	}
-
-	var changed bool
-	for i, interf := range server.Interfaces {
-		if interf.Monitor {
-			for j, ip := range interf.IPAddresses {
-				if ip.ServiceAddress {
-					server.Interfaces[i].IPAddresses[j].Address = "127.0.0.5/24"
-					changed = true
-				}
-			}
-		}
-	}
-	if !changed {
-		t.Fatal("did not find ip address to update")
-	}
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("expected update to pass: %s", err)
-	}
+	resp, _, err = TOSession.GetServersWithHdr(&params, nil)
+	assert.RequireNoError(t, err, "Cannot get Server by hostname '%s': %v - alerts %+v", hostName, err, resp.Alerts)
+	assert.RequireGreaterOrEqual(t, len(resp.Response), 1, "Expected at least one server to exist by hostname '%s'", hostName)
+	respServer = resp.Response[0]
+	assert.RequireNotNil(t, respServer.StatusLastUpdated, "Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
+	assert.NotEqual(t, *originalServer.StatusLastUpdated, *respServer.StatusLastUpdated, "Since status changed, expected 'StatusLastUpdated' to change. "+
+		"old value: %v, new value: %v", *originalServer.StatusLastUpdated, *respServer.StatusLastUpdated)
 }
 
-func UpdateTestServers(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
+func UpdateDSGetServerDSID(t *testing.T) {
+	const hostName = "atlanta-edge-14"
+	const xmlId = "ds3"
+	var topology = "mso-topology"
+	var firstHeaderRewrite = "first header rewrite"
+	var innerHeaderRewrite = "inner header rewrite"
+	var lastHeaderRewrite = "last header rewrite"
 
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
 	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	originalHostname := *resp.Response[0].HostName
-	originalXMPIDD := *resp.Response[0].XMPPID
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-	updatedXMPPID := "change-it"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	// Retrieve the server to check rack, interfaceName, hostName values were updated
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-	infs = respServer.Interfaces
-	found := false
-	for _, inf = range infs {
-		if inf.Name == updatedServerInterface {
-			found = true
-			break
-		}
-	}
-	if !found {
-		t.Errorf("Expected server '%s' to have an interface named '%s' after update", hostName, updatedServerInterface)
-		t.Logf("Actual interfaces: %+v", infs)
-	}
-
-	if respServer.Rack == nil {
-		t.Errorf("results do not match actual: null, expected: '%s'", updatedServerRack)
-	} else if *respServer.Rack != updatedServerRack {
-		t.Errorf("results do not match actual: '%s', expected: '%s'", *respServer.Rack, updatedServerRack)
-	}
-
-	if remoteServer.TypeID == nil {
-		t.Fatalf("Cannot test server type change update; server '%s' had nil type ID", hostName)
-	}
-
-	//Check change in hostname with no change to xmppid
-	if originalHostname == *respServer.HostName && originalXMPIDD == *respServer.XMPPID {
-		t.Errorf("HostName didn't change. Expected: #{updatedHostName}, actual: #{originalHostname}")
-	}
-
-	//Check to verify XMPPID never gets updated
-	remoteServer.XMPPID = &updatedXMPPID
-	al, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil && reqInf.StatusCode != http.StatusBadRequest {
-		t.Logf("error making sure that XMPPID does not get updated, %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, al)
-	}
+	params.Set("dsId", strconv.Itoa(GetDeliveryServiceId(t, xmlId)()))
+	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+	assert.RequireNoError(t, err, "Failed to get Servers: %v - alerts: %+v", err, servers.Alerts)
+	assert.RequireGreaterOrEqual(t, len(servers.Response), 1, "Failed to get at least one Server")
+	assert.RequireEqual(t, hostName, *servers.Response[0].HostName, "Expected delivery service assignment between xmlId: %v and server: %v. Got server: %v", xmlId, hostName, servers.Response[0].HostName)
 
-	//Change back hostname and xmppid to its original name for other tests to pass
-	remoteServer.HostName = &originalHostname
-	remoteServer.XMPPID = &originalXMPIDD
-	alert, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alert)
-	}
-	resp, _, err = TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by hostName: %v - %v", originalHostname, err)
-	}
+	dses, _, err := TOSession.GetDeliveryServiceByXMLIDNullableWithHdr(xmlId, nil)
+	assert.RequireNoError(t, err, "Failed to get Delivery Services: %v", err)
+	assert.RequireEqual(t, len(dses), 1, "Failed to get at least one Delivery Service")
+	ds := dses[0]
 
-	// Assign server to DS and then attempt to update to a different type
-	dses, _, err := TOSession.GetDeliveryServicesNullableWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot GET DeliveryServices: %v", err)
-	}
-	if len(dses) < 1 {
-		t.Fatal("GET DeliveryServices returned no dses, must have at least 1 to test invalid type server update")
-	}
+	ds.Topology = &topology
+	ds.FirstHeaderRewrite = &firstHeaderRewrite
+	ds.InnerHeaderRewrite = &innerHeaderRewrite
+	ds.LastHeaderRewrite = &lastHeaderRewrite
+	ds.EdgeHeaderRewrite = nil
+	ds.MidHeaderRewrite = nil
 
-	serverTypes, _, err := TOSession.GetTypesWithHdr(nil, "server")
-	if err != nil {
-		t.Fatalf("cannot GET Server Types: %v", err)
-	}
-	if len(serverTypes) < 2 {
-		t.Fatal("GET Server Types returned less then 2 types, must have at least 2 to test invalid type server update")
-	}
-	for _, t := range serverTypes {
-		if t.ID != *remoteServer.TypeID {
-			remoteServer.TypeID = &t.ID
-			break
-		}
-	}
+	_, _, err = TOSession.UpdateDeliveryServiceV30WithHdr(*ds.ID, ds, nil)
+	assert.RequireNoError(t, err, "Unable to add topology-related fields to deliveryservice %s: %v", xmlId, err)
 
-	// Assign server to DS
-	_, _, err = TOSession.CreateDeliveryServiceServers(*dses[0].ID, []int{*remoteServer.ID}, true)
-	if err != nil {
-		t.Fatalf("POST delivery service servers: %v", err)
+	params.Set("dsId", strconv.Itoa(*ds.ID))
+	servers, _, err = TOSession.GetServersWithHdr(&params, nil)
+	assert.RequireNoError(t, err, "Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %v - alerts: %+v", xmlId, err, servers.Alerts)
+	assert.RequireGreaterOrEqual(t, len(servers.Response), 1, "Expected at least one server")
+	for _, server := range servers.Response {
+		assert.NotEqual(t, hostName, *server.HostName, "Server: %v was not expected to be returned.")
 	}
+}
 
-	// Attempt Update - should fail
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err == nil {
-		t.Errorf("expected error when updating Server Type of a server assigned to DSes")
-	} else {
-		t.Logf("type change update alerts: %+v", alerts)
+func CreateTestServers(t *testing.T) {
+	for _, server := range testData.Servers {
+		resp, _, err := TOSession.CreateServerWithHdr(server, nil)
+		assert.RequireNoError(t, err, "Could not create server '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
 	}
 }
 
 func DeleteTestServers(t *testing.T) {
-	params := url.Values{}
-
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-
-		params.Set("hostName", *server.HostName)
-
-		resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-		if err != nil {
-			t.Errorf("cannot GET Server by hostname '%s': %v - %v", *server.HostName, err, resp.Alerts)
-			continue
-		}
-		if len(resp.Response) > 0 {
-			if len(resp.Response) > 1 {
-				t.Errorf("Expected exactly one server by hostname '%s' - actual: %d", *server.HostName, len(resp.Response))
-				t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-			}
-			respServer := resp.Response[0]
-
-			if respServer.ID == nil {
-				t.Errorf("Server '%s' had nil ID", *server.HostName)
-				continue
-			}
-
-			delResp, _, err := TOSession.DeleteServerByID(*respServer.ID)
-			if err != nil {
-				t.Errorf("cannot DELETE Server by ID %d: %v - %v", *respServer.ID, err, delResp)
-				continue
-			}
-
-			// Retrieve the Server to see if it got deleted
-			resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-			if err != nil {
-				t.Errorf("error deleting Server hostname '%s': %v - %v", *server.HostName, err, resp.Alerts)
-			}
-			if len(resp.Response) > 0 {
-				t.Errorf("expected Server hostname: %s to be deleted", *server.HostName)
-			}
-		}
+	servers, _, err := TOSession.GetServersWithHdr(nil, nil)
+	assert.NoError(t, err, "Cannot get Servers: %v - alerts: %+v", err, servers.Alerts)
+
+	for _, server := range servers.Response {
+		delResp, _, err := TOSession.DeleteServerByID(*server.ID)
+		assert.NoError(t, err, "Could not delete Server: %v - alerts: %+v", err, delResp.Alerts)
+		// Retrieve Server to see if it got deleted
+		params := url.Values{}
+		params.Set("id", strconv.Itoa(*server.ID))
+		getServer, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error deleting Server for '%s' : %v - alerts: %+v", *server.HostName, err, getServer.Alerts)
+		assert.Equal(t, 0, len(getServer.Response), "Expected Server '%s' to be deleted", *server.HostName)

Review Comment:
   these lines will segfault if Traffic Ops returns a server with a `null` or undefined `hostName`



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}

Review Comment:
   should use `ServerV3`



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),

Review Comment:
   Is this the function you meant to use? I thought you got rid of `getServerID` in favor of `GetServerId` *(sic)*



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostNames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServerWithHdr(server, nil)
-		t.Log("Response: ", *server.HostName, " ", resp)
-		if err != nil {
-			t.Errorf("could not CREATE servers: %v", err)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for _, server := range serverResp {
+			if server.Type == tc.CacheTypeMid.String() {
+				t.Errorf("Expected to find no %s-typed servers but found server %s", tc.CacheTypeMid, *server.HostName)

Review Comment:
   this will segfault if Traffic Ops responds with a `null` or undefined `hostName`



##########
traffic_ops/testing/api/v3/tc-fixtures.json:
##########
@@ -1543,6 +1543,10 @@
         {
             "xmlId": "test-ds-server-assignments",
             "serverNames": ["test-ds-server-assignments"]
+        },
+        {
+            "xmlId": "ds3",
+            "serverNames": ["atlanta-edge-14"]

Review Comment:
   why'd you add this?



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)

Review Comment:
   All of these format strings use `%v` to format everything - the most specific formatting parameter possible should be used i.e. `%d` for integers, `%s` for strings etc. because %v can be used print practically anything so people wind up printing things they don't mean to, like pointer addresses instead of the value to which they point.



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}

Review Comment:
   This will panic if `hostName` was `null` or not defined in the response



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)

Review Comment:
   Should use `ServerV3`.



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostNames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServerWithHdr(server, nil)
-		t.Log("Response: ", *server.HostName, " ", resp)
-		if err != nil {
-			t.Errorf("could not CREATE servers: %v", err)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for _, server := range serverResp {
+			if server.Type == tc.CacheTypeMid.String() {
+				t.Errorf("Expected to find no %s-typed servers but found server %s", tc.CacheTypeMid, *server.HostName)
+			}
 		}
 	}
 }
 
-func CreateTestBlankFields(t *testing.T) {
-	serverResp, _, err := TOSession.GetServersWithHdr(nil, nil)
-	if err != nil {
-		t.Fatalf("couldnt get servers: %v", err)
-	}
-	if len(serverResp.Response) < 1 {
-		t.Fatal("expected at least one server")
-	}
-	server := serverResp.Response[0]
-	originalHost := server.HostName
-
-	server.HostName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatal("should not be able to update server with blank HostName")
-	}
-
-	server.HostName = originalHost
-	server.DomainName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatal("should not be able to update server with blank DomainName")
-	}
+func generateServer(t *testing.T, requestServer map[string]interface{}) map[string]interface{} {
+	// map for the most basic Server a user can create
+	genericServer := map[string]interface{}{
+		"cdnId":        GetCDNId(t, "cdn1"),
+		"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+		"domainName":   "localhost",
+		"hostName":     "testserver",
+		"interfaces": []map[string]interface{}{{
+			"ipAddresses": []map[string]interface{}{{
+				"address":        "127.0.0.1",
+				"serviceAddress": true,
+			}},
+			"name": "eth0",
+		}},
+		"physLocationId": GetPhysLocationId(t, "Denver")(),
+		"profileId":      GetProfileId(t, "EDGE1"),
+		"statusId":       GetStatusId(t, "REPORTED")(),
+		"typeId":         GetTypeId(t, "EDGE"),
+	}
+
+	for k, v := range requestServer {
+		genericServer[k] = v
+	}
+	return genericServer
 }
-func CreateTestServerWithoutProfileId(t *testing.T) {
-	params := url.Values{}
-	servers := testData.Servers[19]
-	params.Set("hostName", *servers.HostName)
 
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by name '%s': %v - %v", *servers.HostName, err, resp.Alerts)
-	}
-
-	server := resp.Response[0]
-	originalProfile := *server.Profile
-	delResp, _, err := TOSession.DeleteServerByID(*server.ID)
-	if err != nil {
-		t.Fatalf("cannot DELETE Server by ID %d: %v - %v", *server.ID, err, delResp)
-	}
-
-	*server.Profile = ""
-	server.ProfileID = nil
-	response, reqInfo, errs := TOSession.CreateServerWithHdr(server, nil)
-	t.Log("Response: ", *server.HostName, " ", response)
-	if reqInfo.StatusCode != 400 {
-		t.Fatalf("Expected status code: %v but got: %v", "400", reqInfo.StatusCode)
-	}
-
-	//Reverting it back for further tests
-	*server.Profile = originalProfile
-	response, _, errs = TOSession.CreateServerWithHdr(server, nil)
-	t.Log("Response: ", *server.HostName, " ", response)
-	if errs != nil {
-		t.Fatalf("could not CREATE servers: %v", errs)
+func GetServerId(t *testing.T, hostName string) func() int {
+	return func() int {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		serversResp, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.RequireNoError(t, err, "Get Servers Request failed with error:", err)
+		assert.RequireEqual(t, 1, len(serversResp.Response), "Expected response object length 1, but got %d", len(serversResp.Response))
+		assert.RequireNotNil(t, serversResp.Response[0].ID, "Expected id to not be nil")
+		return *serversResp.Response[0].ID
 	}
 }
 
-func GetTestServers(t *testing.T) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-		if err != nil {
-			t.Errorf("cannot GET Server by name '%s': %v - %v", *server.HostName, err, resp.Alerts)
-		} else if resp.Summary.Count != 1 {
-			t.Errorf("incorrect server count, expected: 1, actual: %d", resp.Summary.Count)
-
-		}
+func GetStatusId(t *testing.T, name string) func() int {
+	return func() int {
+		statusResp, _, err := TOSession.GetStatusByNameWithHdr(name, nil)
+		assert.NoError(t, err, "Get Statuses Request failed with error:", err)
+		assert.Equal(t, 1, len(statusResp), "Expected response object length 1, but got %d", len(statusResp))
+		assert.NotNil(t, statusResp[0].ID, "Expected id to not be nil")
+		return statusResp[0].ID
 	}
 }
 
-func GetTestServersDetails(t *testing.T) {
-
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.GetServerDetailsByHostNameWithHdr(*server.HostName, nil)
-		if err != nil {
-			t.Errorf("cannot GET Server Details by name: %v - %v", err, resp)
-		}
+func GetPhysLocationId(t *testing.T, name string) func() int {
+	return func() int {
+		physLocResp, _, err := TOSession.GetPhysLocationByNameWithHdr(name, nil)
+		assert.NoError(t, err, "Get PhysLocation Request failed with error:", err)
+		assert.Equal(t, 1, len(physLocResp), "Expected response object length 1, but got %d", len(physLocResp))
+		assert.NotNil(t, physLocResp[0].ID, "Expected id to not be nil")

Review Comment:
   An `int` can never be `nil`; this assertion is unnecessary



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})

Review Comment:
   nit: you know exactly how big this map needs to be, so it could be allocated immediately instead of as-needed during iteration of the response.



##########
traffic_ops/testing/api/v4/servers_test.go:
##########
@@ -16,1437 +16,643 @@ package v4
 */
 
 import (
-	"fmt"
+	"encoding/json"
 	"net/http"
 	"net/url"
-	"reflect"
 	"strconv"
 	"strings"
 	"testing"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 	client "github.com/apache/trafficcontrol/traffic_ops/v4-client"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileID(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-		GetServersForNonExistentDeliveryService(t)
-		CUDServerWithLocks(t)
-		GetTestPaginationSupportServers(t)
-	})
-}
-
-func CUDServerWithLocks(t *testing.T) {
-	resp, _, err := TOSession.GetTenants(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not GET tenants: %v", err)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatalf("didn't get any tenant in response")
-	}
-
-	// Create a new user with operations level privileges
-	user1 := tc.UserV4{
-		Username:             "lock_user1",
-		RegistrationSent:     new(time.Time),
-		LocalPassword:        util.StrPtr("test_pa$$word"),
-		ConfirmLocalPassword: util.StrPtr("test_pa$$word"),
-		Role:                 "operations",
-	}
-	user1.Email = util.StrPtr("lockuseremail@domain.com")
-	user1.TenantID = resp.Response[0].ID
-	user1.FullName = util.StrPtr("firstName LastName")
-	_, _, err = TOSession.CreateUser(user1, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create test user with username: %s", user1.Username)
-	}
-	defer ForceDeleteTestUsersByUsernames(t, []string{"lock_user1"})
-
-	// Establish a session with the newly created non admin level user
-	userSession, _, err := client.LoginWithAgent(Config.TrafficOps.URL, user1.Username, *user1.LocalPassword, true, "to-api-v4-client-tests", false, toReqTimeout)
-	if err != nil {
-		t.Fatalf("could not login with user lock_user1: %v", err)
-	}
-	if len(testData.Servers) == 0 {
-		t.Fatalf("no servers to run the test on, quitting")
-	}
-
-	server := testData.Servers[0]
-	server.HostName = util.StrPtr("cdn_locks_test_server")
-	server.Interfaces = []tc.ServerInterfaceInfoV40{
-		{
-			ServerInterfaceInfo: tc.ServerInterfaceInfo{
-				IPAddresses: []tc.ServerIPAddress{
-					{
-						Address:        "123.32.43.21",
-						Gateway:        util.StrPtr("100.100.100.100"),
-						ServiceAddress: true,
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V4TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {tomorrow}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"hostName": {"atlanta-edge-01"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cachegroupName": {"topology-mid-cg-01"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments", "test-mso-org-01"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILENAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"profileName": {"EDGE1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"status": {"REPORTED"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"topology": {"mso-topology"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1", "test-mso-org-01"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"type": {"EDGE"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+				"EMPTY RESPONSE when INVALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {"999999"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(0)),
+				},
+				"FIRST RESULT when LIMIT=1": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("limit")),
+				},
+				"SECOND RESULT when LIMIT=1 OFFSET=1": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "offset": {"1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("offset")),
+				},
+				"SECOND RESULT when LIMIT=1 PAGE=2": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "page": {"2"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("page")),
+				},
+				"BAD REQUEST when INVALID LIMIT parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"-2"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID OFFSET parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "offset": {"0"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID PAGE parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "page": {"0"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILENAMES": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileNames": []string{""}}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileNames":   []string{"EDGE1"},
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
 					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY ORG SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-mso-org-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-mso-org-01")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileNames": []string{"MID1"},
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileNames": []string{"CDN2_MID"},
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestOpts:  client.RequestOptions{Header: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}}},
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {currentTimeRFC}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
 				},
-				MaxBandwidth: util.Uint64Ptr(2500),
-				Monitor:      true,
-				MTU:          util.Uint64Ptr(1500),
-				Name:         "cdn_locks_interfaceName",
 			},
-			RouterHostName: "router1",
-			RouterPortName: "9090",
-		},
-	}
-	// Create a lock for this user
-	_, _, err = userSession.CreateCDNLock(tc.CDNLock{
-		CDN:     *server.CDNName,
-		Message: util.StrPtr("test lock"),
-		Soft:    util.BoolPtr(false),
-	}, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldn't create cdn lock: %v", err)
-	}
-	// Try to create a new server on a CDN that another user has a hard lock on -> this should fail
-	_, reqInf, err := TOSession.CreateServer(server, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while creating a new server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while creating a new server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to create a new profile on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.CreateServer(server, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while creating a new server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", *server.HostName)
-	servers, _, err := userSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("couldn't get server: %v", err)
-	}
-	if len(servers.Response) != 1 {
-		t.Fatal("couldn't get exactly one server in the response, quitting")
-	}
-	serverID := servers.Response[0].ID
-	// Try to update a server on a CDN that another user has a hard lock on -> this should fail
-	servers.Response[0].DomainName = util.StrPtr("changed_domain_name")
-	_, reqInf, err = TOSession.UpdateServer(*serverID, servers.Response[0], client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while updating a server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while updating a server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to update a server on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.UpdateServer(*serverID, servers.Response[0], client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while updating a server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	// Try to delete a server on a CDN that another user has a hard lock on -> this should fail
-	_, reqInf, err = TOSession.DeleteServer(*serverID, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while deleting a server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while deleting a server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to delete a server on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.DeleteServer(*serverID, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while deleting a server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	// Delete the lock
-	_, _, err = userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: url.Values{"cdn": []string{*server.CDNName}}})
-	if err != nil {
-		t.Errorf("expected no error while deleting other user's lock using admin endpoint, but got %v", err)
-	}
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("name", cdnName)
-	cdns, _, err := TOSession.GetCDNs(opts)
-	if err != nil {
-		t.Fatalf("unable to get CDN '%s': %v - alerts: %+v", cdnName, err, cdns.Alerts)
-	}
-	if len(cdns.Response) < 1 {
-		t.Fatalf("Expected exactly one CDN to exist with name '%s', found: %d", cdnName, len(cdns.Response))
-	}
-	cdnID := cdns.Response[0].ID
-
-	serverOpts := client.NewRequestOptions()
-	serverOpts.QueryParameters.Add("cachegroupName", cacheGroupName)
-	serverOpts.QueryParameters.Add("topology", topologyName)
-	serverOpts.QueryParameters.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServers(serverOpts)
-	if err != nil {
-		t.Fatalf("getting server from CDN '%s', from Cache Group '%s', and in Topology '%s': %v - alerts: %+v", cdnName, cacheGroupName, topologyName, err, servers.Alerts)
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	if server.ID == nil || server.CDNID == nil || len(server.ProfileNames) == 0 || server.CachegroupID == nil || server.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined ID and/or CDN ID and/or Profile Names and/or Cache Group ID and/or Host Name")
-	}
-
-	_, reqInf, err := TOSession.DeleteServer(*server.ID, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	opts.QueryParameters.Set("name", "cdn1")
-	cdns, _, err = TOSession.GetCDNs(opts)
-	if err != nil {
-		t.Fatalf("unable to get CDN 'cdn1': %v - alerts: %+v", err, cdns.Alerts)
-	}
-	if len(cdns.Response) < 1 {
-		t.Fatalf("Expected exactly one CDN to exist with name 'cdn1', found: %d", len(cdns.Response))
-	}
-	newCDNID := cdns.Response[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	opts.QueryParameters.Set("name", "MID1")
-	profiles, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Errorf("unable to get Profile 'MID1': %v - alerts: %+v", err, profiles.Alerts)
-	}
-	if len(profiles.Response) != 1 {
-		t.Fatalf("Expected exactly one Profile to exist with name 'MID1', found: %d", len(profiles.Response))
-	}
-	newProfileID := profiles.Response[0].ID
-	oldProfileName := server.ProfileNames[0]
-
-	opts.QueryParameters.Set("id", strconv.Itoa(newProfileID))
-	nps, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Fatalf("failed to query profiles: %v", err)
-	}
-	if len(nps.Response) != 1 {
-		t.Fatalf("Expected exactly one Profile to exist, found: %d", len(profiles.Response))
-	}
-	server.ProfileNames = []string{nps.Response[0].Name}
-	opts.QueryParameters.Del("id")
-
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileNames = []string{oldProfileName}
-
-	opts.QueryParameters.Set("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %v - alerts: %+v", moveToCacheGroup, err, cgs.Alerts)
-	}
-	if len(cgs.Response) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs.Response))
-	}
-	if cgs.Response[0].ID == nil {
-		t.Fatalf("Traffic Ops responded with Cache Group '%s' that had null or undefined ID", moveToCacheGroup)
-	}
-
-	alerts, _, err := TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different Cache Group: %v - alerts: %+v", *server.HostName, err, alerts.Alerts)
-	}
-
-	*server.CachegroupID = *cgs.Response[0].ID
-	alerts, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %v - alerts: %+v", *server.ID, reqInf.StatusCode, err, alerts.Alerts)
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by hostname '%s': %v - alerts %+v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil || remoteServer.HostName == nil || remoteServer.StatusLastUpdated == nil {
-		t.Fatalf("Traffic Ops returned a representation for server '%s' with null or undefined ID and/or Host Name and/or Status Last Updated time", hostName)
-	}
-	id := fmt.Sprintf("%v", *remoteServer.ID)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatuses(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot get Statuses: %v - alerts: %+v", err, statuses.Alerts)
-	}
-	for _, status := range statuses.Response {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - alerts: %+v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("id", id)
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server #%s by ID: %v - alerts %+v", id, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot update Server #%d (hostname '%s'): %v - alerts %+v", *remoteServer.ID, hostName, err, alerts.Alerts)
-	}
-
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot update Server by ID %d (hostname '%s'): %v - alerts: %+v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server by ID %d: %v - alerts: %+v", *remoteServer.ID, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-}
-
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Add("hostName", hostName)
-	opts.Header = header
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by hostname '%s': %v - alerts: %+v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null or undefined ID for server '%s'", hostName)
-	}
 
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV4{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServers(testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServer(server, testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServer(testCase.EndpointId(), server, testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServer(testCase.EndpointId(), testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	opts.QueryParameters = nil
-	_, reqInf, err := TOSession.UpdateServer(*remoteServer.ID, remoteServer, opts)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
-	}
+	})
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	opts := client.NewRequestOptions()
-	opts.Header = header
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileNames":
+					assert.Exactly(t, expected, server.ProfileNames, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileNames)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
 		}
 	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
+}
 
-	opts.Header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostname string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("hostName", hostname)
+		servers, _, err := TOSession.GetServers(opts)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-
-	opts := client.NewRequestOptions()
-	opts.Header.Set(rfc.IfModifiedSince, timestamp)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostnames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostnames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServer(server, client.RequestOptions{})
-		if err != nil {
-			t.Errorf("could not create server '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		for _, server := range serverResp {
+			if server.Type == tc.CacheTypeMid.String() {
+				t.Errorf("Expected to find no %s-typed servers but found server %s", tc.CacheTypeMid, *server.HostName)
+			}
 		}
 	}
 }
 
-func CreateTestBlankFields(t *testing.T) {
-	serverResp, _, err := TOSession.GetServers(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldnt get servers: %v - alerts: %+v", err, serverResp.Alerts)
-	}
-	if len(serverResp.Response) < 1 {
-		t.Fatal("expected at least one server")
-	}
-	server := serverResp.Response[0]
-	if server.ID == nil {
-		t.Fatal("Traffic Ops returned a representation for a servver with null or undefined ID")
-	}
-	originalHost := server.HostName
-
-	server.HostName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Error("should not be able to update server with blank HostName")
-	}
+func validateServerPagination(paginationParam string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		paginationResp := resp.([]tc.ServerV40)
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("orderby", "id")
+		respBase, _, err := TOSession.GetServers(opts)
+		assert.RequireNoError(t, err, "Cannot get Servers: %v - alerts: %+v", err, respBase.Alerts)
 
-	server.HostName = originalHost
-	server.DomainName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Error("should not be able to update server with blank DomainName")
+		ds := respBase.Response
+		assert.RequireGreaterOrEqual(t, len(ds), 3, "Need at least 3 Servers in Traffic Ops to test pagination support, found: %d", len(ds))
+		switch paginationParam {
+		case "limit:":
+			assert.Exactly(t, ds[:1], paginationResp, "expected GET Servers with limit = 1 to return first result")
+		case "offset":
+			assert.Exactly(t, ds[1:2], paginationResp, "expected GET Servers with limit = 1, offset = 1 to return second result")
+		case "page":
+			assert.Exactly(t, ds[1:2], paginationResp, "expected GET Servers with limit = 1, page = 2 to return second result")
+		}
 	}
 }
 
-// This test will break if the structure of the test data servers collection
-// is changed at all.
-func CreateTestServerWithoutProfileID(t *testing.T) {
-	if len(testData.Servers) < 20 {
-		t.Fatal("Need at least 20 servers to test creating a server without a Profile")
-	}
-	testServer := testData.Servers[19]
-	if testServer.HostName == nil {
-		t.Fatal("Found a server in the test data with null or undefined Host Name")
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", *testServer.HostName)
-
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by Host Name '%s': %v - alerts: %+v", *testServer.HostName, err, resp.Alerts)
-	}
-
-	server := resp.Response[0]
-	if len(server.ProfileNames) == 0 || server.ID == nil || server.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation of a server with null or undefined ID and/or Profile and/or Host Name")
-	}
-	originalProfile := server.ProfileNames
-	delResp, _, err := TOSession.DeleteServer(*server.ID, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot delete Server by ID %d: %v - %v", *server.ID, err, delResp)
-	}
-
-	server.ProfileNames = []string{""}
-	_, reqInfo, _ := TOSession.CreateServer(server, client.RequestOptions{})
-	if reqInfo.StatusCode != 400 {
-		t.Fatalf("Expected status code: %v but got: %v", "400", reqInfo.StatusCode)
-	}
-
-	//Reverting it back for further tests
-	server.ProfileNames = originalProfile
-	response, _, err := TOSession.CreateServer(server, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create server: %v - alerts: %+v", err, response.Alerts)
-	}
+func generateServer(t *testing.T, requestServer map[string]interface{}) map[string]interface{} {
+	// map for the most basic Server a user can create
+	genericServer := map[string]interface{}{
+		"cdnId":        GetCDNId(t, "cdn1"),
+		"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+		"domainName":   "localhost",
+		"hostName":     "testserver",
+		"interfaces": []map[string]interface{}{{
+			"ipAddresses": []map[string]interface{}{{
+				"address":        "127.0.0.1",
+				"serviceAddress": true,
+			}},
+			"name": "eth0",
+		}},
+		"physLocationId": GetPhysLocationId(t, "Denver")(),
+		"profileNames":   []string{"EDGE1"},
+		"statusId":       GetStatusId(t, "REPORTED")(),
+		"typeId":         GetTypeId(t, "EDGE"),
+	}
+
+	for k, v := range requestServer {
+		genericServer[k] = v
+	}
+	return genericServer
 }
 
-func GetTestServers(t *testing.T) {
-	opts := client.NewRequestOptions()
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, _, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Errorf("cannot get Server by Host Name '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
-		} else if resp.Summary.Count != 1 {
-			t.Errorf("incorrect server count, expected: 1, actual: %d", resp.Summary.Count)
-		}
+func GetServerId(t *testing.T, hostName string) func() int {
+	return func() int {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("hostName", hostName)
+		serversResp, _, err := TOSession.GetServers(opts)
+		assert.RequireNoError(t, err, "Get Servers Request failed with error:", err)
+		assert.RequireEqual(t, 1, len(serversResp.Response), "Expected response object length 1, but got %d", len(serversResp.Response))
+		assert.RequireNotNil(t, serversResp.Response[0].ID, "Expected id to not be nil")
+		return *serversResp.Response[0].ID
 	}
 }
 
-func GetTestServersQueryParameters(t *testing.T) {
-	dses, _, err := TOSession.GetDeliveryServices(client.RequestOptions{QueryParameters: url.Values{"xmlId": []string{"ds1"}}})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v - alerts: %+v", err, dses.Alerts)
-	}
-	if len(dses.Response) < 1 {
-		t.Fatal("Failed to get at least one Delivery Service")
-	}
-
-	ds := dses.Response[0]
-	if ds.ID == nil {
-		t.Fatal("Traffic Ops returned a representation of a Delivery Service with null or undefined ID")
-	}
-
-	AssignTestDeliveryService(t)
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("dsId", strconv.Itoa(*ds.ID))
-	servers, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get server by Delivery Service ID: %v - alerts: %+v", err, servers.Alerts)
-	}
-	if len(servers.Response) != 3 {
-		t.Fatalf("expected to get 3 servers for Delivery Service: %d, actual: %d", *ds.ID, len(servers.Response))
-	}
-
-	currentTime := time.Now().UTC().Add(5 * time.Second)
-	timestamp := currentTime.Format(time.RFC1123)
-
-	opts.Header.Set(rfc.IfModifiedSince, timestamp)
-	_, reqInf, _ := TOSession.GetServers(opts)
-	if reqInf.StatusCode != http.StatusNotModified {
-		t.Errorf("Expected a status code of 304, got %v", reqInf.StatusCode)
-	}
-
-	dses, _, err = TOSession.GetDeliveryServices(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v - alerts: %+v", err, dses.Alerts)
-	}
-
-	foundTopDs := false
-	const (
-		topDSXmlID = "ds-top"
-		topology   = "mso-topology"
-	)
-	for _, ds = range dses.Response {
-		if ds.XMLID == nil || ds.ID == nil {
-			t.Error("Traffic Ops returned a representation of a Delivery Service that had a null or undefined XMLID and/or ID")
-			continue
-		}
-		if *ds.XMLID != topDSXmlID {
-			continue
-		}
-		if ds.Topology == nil || ds.FirstHeaderRewrite == nil || ds.InnerHeaderRewrite == nil || ds.LastHeaderRewrite == nil {
-			t.Errorf("Traffic Ops returned a representation of Delivery Service '%s' that had a null or undefined Topology and/or First Header Rewrite text and/or Inner Header Rewrite text and/or Last Header Rewrite text", topDSXmlID)
-			continue
-		}
-		foundTopDs = true
-		break
-	}
-	if !foundTopDs {
-		t.Fatalf("unable to find deliveryservice %s", topDSXmlID)
-	}
-
-	/* Create a deliveryservice server assignment that should not show up in the
-	 * client.GetServers( response because ds-top is topology-based
-	 */
-	const otherServerHostname = "topology-edge-02"
-	serverResponse, _, err := TOSession.GetServers(client.RequestOptions{QueryParameters: url.Values{"hostName": []string{otherServerHostname}}})
-	if err != nil {
-		t.Fatalf("getting server by Host Name %s: %v - alerts: %+v", otherServerHostname, err, serverResponse.Alerts)
-	}
-	if len(serverResponse.Response) != 1 {
-		t.Fatalf("unable to find server with hostname %s", otherServerHostname)
-	}
-	otherServer := serverResponse.Response[0]
-	if otherServer.ID == nil || otherServer.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation of a Server that had a null or undefined ID and/or Host Name")
-	}
-
-	dsTopologyField, dsFirstHeaderRewriteField, innerHeaderRewriteField, lastHeaderRewriteField := *ds.Topology, *ds.FirstHeaderRewrite, *ds.InnerHeaderRewrite, *ds.LastHeaderRewrite
-	ds.Topology, ds.FirstHeaderRewrite, ds.InnerHeaderRewrite, ds.LastHeaderRewrite = nil, nil, nil, nil
-	updResp, _, err := TOSession.UpdateDeliveryService(*ds.ID, ds, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to temporary remove topology-related fields from deliveryservice '%s': %v - alerts: %+v", topDSXmlID, err, updResp.Alerts)
-	}
-	if len(updResp.Response) != 1 {
-		t.Fatalf("Expected updating a Delivery Service to update exactly one Delivery Service, but Traffic Ops indicates that %d were updated", len(updResp.Response))
-	}
-	ds = updResp.Response[0]
-	if ds.ID == nil {
-		t.Fatal("Traffic Ops returned a representation of a Delivery Service that had null or undefined ID")
-	}
-	assignResp, _, err := TOSession.CreateDeliveryServiceServers(*ds.ID, []int{*otherServer.ID}, false, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to assign server '%s' to Delivery Service '%s': %v - alerts: %+v", *otherServer.HostName, topDSXmlID, err, assignResp.Alerts)
-	}
-	ds.Topology, ds.FirstHeaderRewrite, ds.InnerHeaderRewrite, ds.LastHeaderRewrite = &dsTopologyField, &dsFirstHeaderRewriteField, &innerHeaderRewriteField, &lastHeaderRewriteField
-	updResp, _, err = TOSession.UpdateDeliveryService(*ds.ID, ds, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to re-add topology-related fields to deliveryservice %s: %v - alerts: %+v", topDSXmlID, err, updResp.Alerts)
-	}
-
-	opts.Header = nil
-	opts.QueryParameters.Set("dsId", strconv.Itoa(*ds.ID))
-	expectedHostnames := map[string]bool{
-		"edge1-cdn1-cg3":                 false,
-		"edge2-cdn1-cg3":                 false,
-		"atlanta-mid-01":                 false,
-		"atlanta-mid-16":                 false,
-		"edgeInCachegroup3":              false,
-		"midInSecondaryCachegroupInCDN1": false,
-	}
-	response, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %v - alerts: %+v", topDSXmlID, err, response.Alerts)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s", topDSXmlID)
-	}
-	for _, server := range response.Response {
-		if server.HostName == nil {
-			t.Fatal("Traffic Ops responded with a representation for a server with null or undefined Host Name")
-		}
-		if _, exists := expectedHostnames[*server.HostName]; !exists {
-			t.Fatalf("expected hostnames %v, actual %s", expectedHostnames, *server.HostName)
-		}
-		expectedHostnames[*server.HostName] = true
-	}
-	var notInResponse []string
-	for hostName, inResponse := range expectedHostnames {
-		if !inResponse {
-			notInResponse = append(notInResponse, hostName)
-		}
-	}
-	if len(notInResponse) != 0 {
-		t.Fatalf("%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
-	}
-	const originHostname = "denver-mso-org-01"
-	if resp, _, err := TOSession.AssignServersToDeliveryService([]string{originHostname}, topDSXmlID, client.RequestOptions{}); err != nil {
-		t.Fatalf("assigning origin server '%s' to Delivery Service '%s': %v - alerts: %+v", originHostname, topDSXmlID, err, resp.Alerts)
-	}
-	response, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %v - alerts: %+v", topDSXmlID, err, response.Alerts)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s", topDSXmlID)
-	}
-	containsOrigin := false
-	for _, server := range response.Response {
-		if server.HostName == nil || *server.HostName != originHostname {
-			continue
-		}
-		containsOrigin = true
-		break
-	}
-	if !containsOrigin {
-		t.Fatalf("did not find origin server %s when querying servers by dsId after assigning %s to delivery service %s", originHostname, originHostname, topDSXmlID)
-	}
-
-	const topDsWithNoMids = "ds-based-top-with-no-mids"
-	dses, _, err = TOSession.GetDeliveryServices(client.RequestOptions{QueryParameters: url.Values{"xmlId": []string{topDsWithNoMids}}})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v - alerts: %+v", err, dses.Alerts)
-	}
-	if len(dses.Response) < 1 {
-		t.Fatal("Failed to get at least one Delivery Service")
-	}
-
-	ds = dses.Response[0]
-	if ds.ID == nil {
-		t.Fatal("Got Delivery Service with nil ID")
-	}
-	opts.QueryParameters.Set("dsId", strconv.Itoa(*ds.ID))
-
-	response, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %s", topDsWithNoMids, err)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s: %s", topDsWithNoMids, err)
-	}
-	for _, server := range response.Response {
-		if server.HostName == nil {
-			t.Fatal("Traffic Ops returned a server with null or undefined Host Name")
-		}
-		if server.Type == tc.CacheTypeMid.String() {
-			t.Fatalf("Expected to find no %s-typed servers when querying servers by the ID for Delivery Service with XMLID %s but found %s-typed server %s", tc.CacheTypeMid, topDsWithNoMids, tc.CacheTypeMid, *server.HostName)
-		}
-	}
-
-	opts.QueryParameters.Del("dsId")
-	opts.QueryParameters.Set("topology", topology)
-	expectedHostnames = map[string]bool{
-		originHostname:                   false,
-		"denver-mso-org-02":              false,
-		"edge1-cdn1-cg3":                 false,
-		"edge2-cdn1-cg3":                 false,
-		"atlanta-mid-01":                 false,
-		"atlanta-mid-16":                 false,
-		"atlanta-mid-17":                 false,
-		"edgeInCachegroup3":              false,
-		"midInParentCachegroup":          false,
-		"midInSecondaryCachegroup":       false,
-		"midInSecondaryCachegroupInCDN1": false,
-		"test-mso-org-01":                false,
-	}
-	response, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers belonging to Cache Groups in Topology %s: %v - alerts: %+v", topology, err, response.Alerts)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers belonging to Cache Groups in Topology %s:", topology)
-	}
-	for _, server := range response.Response {
-		if server.HostName == nil {
-			t.Fatal("Traffic Ops returned a server with null or undefined Host Name")
-		}
-		if _, exists := expectedHostnames[*server.HostName]; !exists {
-			t.Fatalf("expected hostnames %v, actual %s", expectedHostnames, *server.HostName)
-		}
-		expectedHostnames[*server.HostName] = true
-	}
-	notInResponse = []string{}
-	for hostName, inResponse := range expectedHostnames {
-		if !inResponse {
-			notInResponse = append(notInResponse, hostName)
-		}
-	}
-	if len(notInResponse) != 0 {
-		t.Fatalf("%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
-	}
-	opts.QueryParameters.Del("topology")
-
-	resp, _, err := TOSession.GetServers(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("Failed to get servers: %v - alerts: %+v", err, resp.Alerts)
-	}
-
-	if len(resp.Response) < 1 {
-		t.Fatal("Failed to get at least one server")
-	}
-
-	s := resp.Response[0]
-
-	opts.QueryParameters.Set("type", s.Type)
-	if resp, _, err := TOSession.GetServers(opts); err != nil {
-		t.Errorf("Error getting servers by Type: %v - alerts: %+v", err, resp.Alerts)
-	}
-	opts.QueryParameters.Del("type")
-
-	if s.CachegroupID == nil {
-		t.Error("Found server with no Cache Group ID")
-	} else {
-		opts.QueryParameters.Add("cachegroup", strconv.Itoa(*s.CachegroupID))
-		if resp, _, err := TOSession.GetServers(opts); err != nil {
-			t.Errorf("Error getting servers by Cache Group ID: %v - alerts: %+v", err, resp.Alerts)
-		}
-		opts.QueryParameters.Del("cachegroup")
-	}
-
-	if s.Status == nil {
-		t.Error("Found server with no status")
-	} else {
-		opts.QueryParameters.Add("status", *s.Status)
-		if resp, _, err := TOSession.GetServers(opts); err != nil {
-			t.Errorf("Error getting servers by status: %v - alerts: %+v", err, resp.Alerts)
-		}
-		opts.QueryParameters.Del("status")
-	}
-
-	opts.QueryParameters.Add("name", s.ProfileNames[0])
-	pr, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Fatalf("failed to query profile: %v", err)
-	}
-	if len(pr.Response) != 1 {
-		t.Error("Found server with no Profile ID")
-	} else {
-		profileName := pr.Response[0].Name
-		opts.QueryParameters.Add("profileName", profileName)
-		if resp, _, err := TOSession.GetServers(opts); err != nil {
-			t.Errorf("Error getting servers by Profile ID: %v - alerts: %+v", err, resp.Alerts)
-		}
-		opts.QueryParameters.Del("profileName")
-	}
-
-	cgs, _, err := TOSession.GetCacheGroups(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("Failed to get Cache Groups: %v", err)
-	}
-	if len(cgs.Response) < 1 {
-		t.Fatal("Failed to get at least one Cache Group")
-	}
-	if cgs.Response[0].ID == nil {
-		t.Fatal("Cache Group found with no ID")
-	}
-
-	opts.QueryParameters.Add("parentCacheGroup", strconv.Itoa(*cgs.Response[0].ID))
-	if resp, _, err = TOSession.GetServers(opts); err != nil {
-		t.Errorf("Error getting servers by parent Cache Group: %v - alerts: %+v", err, resp.Alerts)
+func GetStatusId(t *testing.T, name string) func() int {

Review Comment:
   func `GetStatusId` should be `GetStatusID`



##########
traffic_ops/testing/api/v3/servers_test.go:
##########
@@ -26,1017 +26,562 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServersDetails(t)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileId(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-	})
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	cdnID := cdns[0].ID
-	params := url.Values{}
-	params.Add("cachegroupName", cacheGroupName)
-	params.Add("topology", topologyName)
-	params.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("getting server from cdn %s from cachegroup %s in topology %s: %s", cdnName, cacheGroupName, topologyName, err.Error())
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	_, reqInf, err := TOSession.DeleteServerByID(*server.ID)
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	cdns, _, err = TOSession.GetCDNByNameWithHdr("cdn1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET CDN: %v", err)
-	}
-	newCDNID := cdns[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	profiles, _, err := TOSession.GetProfileByNameWithHdr("MID1", nil)
-	if err != nil {
-		t.Fatalf("unable to GET profile: %v", err)
-	}
-	newProfile := profiles[0].ID
-	oldProfile := *server.ProfileID
-	server.ProfileID = &newProfile
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileID = &oldProfile
-
-	params = url.Values{}
-	params.Add("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroupsByQueryParamsWithHdr(params, nil)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %s", moveToCacheGroup, err.Error())
-	}
-	if len(cgs) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs))
-	}
-
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different cachegroup: %s", *server.HostName, err.Error())
-	}
-
-	*server.CachegroupID = *cgs[0].ID
-	_, _, err = TOSession.UpdateServerByIDWithHdr(*server.ID, server, nil)
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, nil)
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatusesWithHdr(nil)
-	if err != nil {
-		t.Fatalf("cannot get statuses: %v", err.Error())
-	}
-	for _, status := range statuses {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V3TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {tomorrow}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"hostName": {"atlanta-edge-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cachegroupName": {"topology-mid-cg-01"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILEID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"profileId": {strconv.Itoa(GetProfileId(t, "EDGE1"))}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"status": {"REPORTED"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"topology": {"mso-topology"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"type": {"EDGE"}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestParams: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILEID": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileId": nil}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileId":      GetProfileId(t, "EDGE1"),
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
+					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileId":    GetProfileId(t, "MID1"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileId":    GetProfileId(t, "CDN2_MID"),
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:     GetServerId(t, "atlanta-edge-01"),
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestHeaders: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+					Expectations:   utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    getServerID(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession:  TOSession,
+					RequestHeaders: http.Header{rfc.IfModifiedSince: {currentTimeRFC}},
+					Expectations:   utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
 
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, nil)
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - %v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServersWithHdr(&idParam, nil)
-	if err != nil {
-		t.Errorf("cannot GET Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV30{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServersWithHdr(&testCase.RequestParams, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServerWithHdr(server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServerByIDWithHdr(testCase.EndpointId(), server, testCase.RequestHeaders)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServerByID(testCase.EndpointId())
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
+	})
 }
 
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	params := url.Values{}
-	params.Add("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServersWithHdr(&params, header)
-
-	if err != nil {
-		t.Fatalf("cannot GET Server by hostname '%s': %v - %v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null ID for server '%s'", hostName)
-	}
-
-	// Creating idParam to get server when hostname changes.
-	id := fmt.Sprintf("%v", *resp.Response[0].ID)
-	idParam := url.Values{}
-	idParam.Add("id", id)
-
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
-
-	_, reqInf, err := TOSession.UpdateServerByIDWithHdr(*remoteServer.ID, remoteServer, header)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileID":
+					assert.Exactly(t, expected, server.ProfileID, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileID)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
+		}
 	}
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-		}
-	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostName string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		params := url.Values{}
+		params.Set("hostName", hostName)
+		servers, _, err := TOSession.GetServersWithHdr(&params, nil)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	var header http.Header
-	header = make(map[string][]string)
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-	header.Set(rfc.IfModifiedSince, timestamp)
-	params := url.Values{}
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		params.Set("hostName", *server.HostName)
-		_, reqInf, err := TOSession.GetServersWithHdr(&params, header)
-		if err != nil {
-			t.Fatalf("Expected no error, but got %v", err.Error())
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostNames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostNames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServerWithHdr(server, nil)
-		t.Log("Response: ", *server.HostName, " ", resp)
-		if err != nil {
-			t.Errorf("could not CREATE servers: %v", err)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV30)

Review Comment:
   should use `ServerV3`



##########
traffic_ops/testing/api/v4/servers_test.go:
##########
@@ -16,1437 +16,643 @@ package v4
 */
 
 import (
-	"fmt"
+	"encoding/json"
 	"net/http"
 	"net/url"
-	"reflect"
 	"strconv"
 	"strings"
 	"testing"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 	client "github.com/apache/trafficcontrol/traffic_ops/v4-client"
 )
 
 func TestServers(t *testing.T) {
-	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices}, func() {
-		GetTestServersIMS(t)
-		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestServers(t)
-		UpdateTestServersWithHeaders(t, header)
-		GetTestServers(t)
-		GetTestServersIMSAfterChange(t, header)
-		GetTestServersQueryParameters(t)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestServersWithHeaders(t, header)
-		CreateTestBlankFields(t)
-		CreateTestServerWithoutProfileID(t)
-		UniqueIPProfileTestServers(t)
-		UpdateTestServerStatus(t)
-		LastServerInTopologyCacheGroup(t)
-		GetServersForNonExistentDeliveryService(t)
-		CUDServerWithLocks(t)
-		GetTestPaginationSupportServers(t)
-	})
-}
-
-func CUDServerWithLocks(t *testing.T) {
-	resp, _, err := TOSession.GetTenants(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not GET tenants: %v", err)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatalf("didn't get any tenant in response")
-	}
-
-	// Create a new user with operations level privileges
-	user1 := tc.UserV4{
-		Username:             "lock_user1",
-		RegistrationSent:     new(time.Time),
-		LocalPassword:        util.StrPtr("test_pa$$word"),
-		ConfirmLocalPassword: util.StrPtr("test_pa$$word"),
-		Role:                 "operations",
-	}
-	user1.Email = util.StrPtr("lockuseremail@domain.com")
-	user1.TenantID = resp.Response[0].ID
-	user1.FullName = util.StrPtr("firstName LastName")
-	_, _, err = TOSession.CreateUser(user1, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create test user with username: %s", user1.Username)
-	}
-	defer ForceDeleteTestUsersByUsernames(t, []string{"lock_user1"})
-
-	// Establish a session with the newly created non admin level user
-	userSession, _, err := client.LoginWithAgent(Config.TrafficOps.URL, user1.Username, *user1.LocalPassword, true, "to-api-v4-client-tests", false, toReqTimeout)
-	if err != nil {
-		t.Fatalf("could not login with user lock_user1: %v", err)
-	}
-	if len(testData.Servers) == 0 {
-		t.Fatalf("no servers to run the test on, quitting")
-	}
-
-	server := testData.Servers[0]
-	server.HostName = util.StrPtr("cdn_locks_test_server")
-	server.Interfaces = []tc.ServerInterfaceInfoV40{
-		{
-			ServerInterfaceInfo: tc.ServerInterfaceInfo{
-				IPAddresses: []tc.ServerIPAddress{
-					{
-						Address:        "123.32.43.21",
-						Gateway:        util.StrPtr("100.100.100.100"),
-						ServiceAddress: true,
+	WithObjs(t, []TCObj{CDNs, Types, Tenants, Users, Parameters, Profiles, Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, ServiceCategories, DeliveryServices, DeliveryServiceServerAssignments}, func() {
+
+		currentTime := time.Now().UTC().Add(-15 * time.Second)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+		tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+		methodTests := utils.V4TestCase{
+			"GET": {
+				"NOT MODIFIED when NO CHANGES made": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {tomorrow}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID HOSTNAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"hostName": {"atlanta-edge-01"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						validateServerFields(map[string]interface{}{"HostName": "atlanta-edge-01"})),
+				},
+				"OK when VALID CACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cachegroup": {strconv.Itoa(GetCacheGroupId(t, "cachegroup1")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CachegroupID": GetCacheGroupId(t, "cachegroup1")()})),
+				},
+				"OK when VALID CACHEGROUPNAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cachegroupName": {"topology-mid-cg-01"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Cachegroup": "topology-mid-cg-01"})),
+				},
+				"OK when VALID CDN parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"cdn": {strconv.Itoa(GetCDNId(t, "cdn2"))}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"CDNID": GetCDNId(t, "cdn2")})),
+				},
+				"OK when VALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "test-ds-server-assignments")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"test-ds-server-assignments", "test-mso-org-01"})),
+				},
+				"OK when VALID PARENTCACHEGROUP parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"parentCacheGroup": {strconv.Itoa(GetCacheGroupId(t, "parentCachegroup")())}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID PROFILENAME parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"profileName": {"EDGE1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1)),
+				},
+				"OK when VALID STATUS parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"status": {"REPORTED"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Status": "REPORTED"})),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"topology": {"mso-topology"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01", "denver-mso-org-02", "edge1-cdn1-cg3", "edge2-cdn1-cg3",
+							"atlanta-mid-01", "atlanta-mid-16", "atlanta-mid-17", "edgeInCachegroup3", "midInParentCachegroup",
+							"midInSecondaryCachegroup", "midInSecondaryCachegroupInCDN1", "test-mso-org-01"})),
+				},
+				"OK when VALID TYPE parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"type": {"EDGE"}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateServerFields(map[string]interface{}{"Type": "EDGE"})),
+				},
+				"VALID SERVER LIST when using TOPOLOGY BASED DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-top")())}}},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						validateExpectedServers([]string{"denver-mso-org-01"})),
+				},
+				"VALID SERVER TYPE when DS TOPOLOGY CONTAINS NO MIDS": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {strconv.Itoa(GetDeliveryServiceId(t, "ds-based-top-with-no-mids")())}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1), validateServerTypeIsNotMid()),
+				},
+				"EMPTY RESPONSE when INVALID DSID parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"dsId": {"999999"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(0)),
+				},
+				"FIRST RESULT when LIMIT=1": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("limit")),
+				},
+				"SECOND RESULT when LIMIT=1 OFFSET=1": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "offset": {"1"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("offset")),
+				},
+				"SECOND RESULT when LIMIT=1 PAGE=2": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "page": {"2"}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), validateServerPagination("page")),
+				},
+				"BAD REQUEST when INVALID LIMIT parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"-2"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID OFFSET parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "offset": {"0"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID PAGE parameter": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "page": {"0"}}},
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"POST": {
+				"BAD REQUEST when BLANK PROFILENAMES": {
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"profileNames": []string{""}}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					EndpointId:    GetServerId(t, "atlanta-edge-03"),
+					ClientSession: TOSession,
+					RequestBody: map[string]interface{}{
+						"id":           GetServerId(t, "atlanta-edge-03")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"domainName":   "updateddomainname",
+						"hostName":     "atl-edge-01",
+						"httpsPort":    8080,
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{
+								{
+									"address":        "2345:1234:12:2::4/64",
+									"gateway":        "2345:1234:12:2::4",
+									"serviceAddress": false,
+								},
+								{
+									"address":        "127.0.0.13/30",
+									"gateway":        "127.0.0.1",
+									"serviceAddress": true,
+								},
+							},
+							"monitor":        true,
+							"mtu":            uint64(1280),
+							"name":           "bond1",
+							"routerHostName": "router5",
+							"routerPort":     "9004",
+						}},
+						"physLocationId": GetPhysLocationId(t, "Denver")(),
+						"profileNames":   []string{"EDGE1"},
+						"rack":           "RR 119.03",
+						"statusId":       GetStatusId(t, "REPORTED")(),
+						"tcpPort":        8080,
+						"typeId":         GetTypeId(t, "EDGE"),
+						"updPending":     true,
 					},
+					Expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+						validateServerFieldsForUpdate("atl-edge-01", map[string]interface{}{
+							"CDNName": "cdn1", "Cachegroup": "cachegroup1", "DomainName": "updateddomainname", "HostName": "atl-edge-01",
+							"HTTPSPort": 8080, "InterfaceName": "bond1", "MTU": uint64(1280), "PhysLocation": "Denver", "Rack": "RR 119.03",
+							"TCPPort": 8080, "TypeID": GetTypeId(t, "EDGE"),
+						})),
+				},
+				"BAD REQUEST when CHANGING XMPPID": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":     GetServerId(t, "atlanta-edge-16")(),
+						"xmppId": "CHANGINGTHIS",
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when UPDATING SERVER TYPE when ASSIGNED to DS": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "test-ds-server-assignments")(),
+						"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+						"typeId":       GetTypeId(t, "MID"),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-ds-server-assignments")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"CONFLICT when UPDATING SERVER STATUS when its the ONLY ORG SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-mso-org-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":       GetServerId(t, "test-mso-org-01")(),
+						"statusId": GetStatusId(t, "ADMIN_DOWN")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+				"BAD REQUEST when UPDATING CDN when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"cdnId":        GetCDNId(t, "cdn1"),
+						"profileNames": []string{"MID1"},
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when UPDATING CACHEGROUP when LAST SERVER IN CACHEGROUP IN TOPOLOGY": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id":           GetServerId(t, "midInTopologyMidCg01")(),
+						"hostName":     "midInTopologyMidCg01",
+						"cdnId":        GetCDNId(t, "cdn2"),
+						"profileNames": []string{"CDN2_MID"},
+						"cachegroupId": GetCacheGroupId(t, "topology-mid-cg-02")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when IPADDRESS EXISTS with SAME PROFILE": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"profileNames": []string{"EDGE1"},
+						"interfaces": []map[string]interface{}{{
+							"ipAddresses": []map[string]interface{}{{
+								"address":        "127.0.0.11/22",
+								"gateway":        "127.0.0.11",
+								"serviceAddress": true,
+							}},
+							"name": "eth1",
+						}},
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK HOSTNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"hostName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when BLANK DOMAINNAME": {
+					EndpointId:    GetServerId(t, "atlanta-edge-16"),
+					ClientSession: TOSession,
+					RequestBody:   generateServer(t, map[string]interface{}{"domainName": ""}),
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}}},
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					EndpointId:    GetServerId(t, "atlanta-edge-01"),
+					ClientSession: TOSession,
+					RequestBody: generateServer(t, map[string]interface{}{
+						"id": GetServerId(t, "atlanta-edge-01")(),
+					}),
+					RequestOpts:  client.RequestOptions{Header: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}}},
+					Expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+			},
+			"DELETE": {
+				"BAD REQUEST when LAST SERVER in CACHE GROUP": {
+					EndpointId:    GetServerId(t, "midInTopologyMidCg01"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"CONFLICT when DELETING SERVER when its the ONLY EDGE SERVER ASSIGNED": {
+					EndpointId:    GetServerId(t, "test-ds-server-assignments"),
+					ClientSession: TOSession,
+					Expectations:  utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusConflict)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					ClientSession: TOSession,
+					RequestOpts:   client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {currentTimeRFC}}},
+					Expectations:  utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
 				},
-				MaxBandwidth: util.Uint64Ptr(2500),
-				Monitor:      true,
-				MTU:          util.Uint64Ptr(1500),
-				Name:         "cdn_locks_interfaceName",
 			},
-			RouterHostName: "router1",
-			RouterPortName: "9090",
-		},
-	}
-	// Create a lock for this user
-	_, _, err = userSession.CreateCDNLock(tc.CDNLock{
-		CDN:     *server.CDNName,
-		Message: util.StrPtr("test lock"),
-		Soft:    util.BoolPtr(false),
-	}, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldn't create cdn lock: %v", err)
-	}
-	// Try to create a new server on a CDN that another user has a hard lock on -> this should fail
-	_, reqInf, err := TOSession.CreateServer(server, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while creating a new server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while creating a new server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to create a new profile on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.CreateServer(server, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while creating a new server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", *server.HostName)
-	servers, _, err := userSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("couldn't get server: %v", err)
-	}
-	if len(servers.Response) != 1 {
-		t.Fatal("couldn't get exactly one server in the response, quitting")
-	}
-	serverID := servers.Response[0].ID
-	// Try to update a server on a CDN that another user has a hard lock on -> this should fail
-	servers.Response[0].DomainName = util.StrPtr("changed_domain_name")
-	_, reqInf, err = TOSession.UpdateServer(*serverID, servers.Response[0], client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while updating a server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while updating a server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to update a server on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.UpdateServer(*serverID, servers.Response[0], client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while updating a server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	// Try to delete a server on a CDN that another user has a hard lock on -> this should fail
-	_, reqInf, err = TOSession.DeleteServer(*serverID, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while deleting a server for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while deleting a server for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
-
-	// Try to delete a server on a CDN that the same user has a hard lock on -> this should succeed
-	_, reqInf, err = userSession.DeleteServer(*serverID, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while deleting a server for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
-
-	// Delete the lock
-	_, _, err = userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: url.Values{"cdn": []string{*server.CDNName}}})
-	if err != nil {
-		t.Errorf("expected no error while deleting other user's lock using admin endpoint, but got %v", err)
-	}
-}
-
-func LastServerInTopologyCacheGroup(t *testing.T) {
-	const cacheGroupName = "topology-mid-cg-01"
-	const moveToCacheGroup = "topology-mid-cg-02"
-	const topologyName = "forked-topology"
-	const cdnName = "cdn2"
-	const expectedLength = 1
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("name", cdnName)
-	cdns, _, err := TOSession.GetCDNs(opts)
-	if err != nil {
-		t.Fatalf("unable to get CDN '%s': %v - alerts: %+v", cdnName, err, cdns.Alerts)
-	}
-	if len(cdns.Response) < 1 {
-		t.Fatalf("Expected exactly one CDN to exist with name '%s', found: %d", cdnName, len(cdns.Response))
-	}
-	cdnID := cdns.Response[0].ID
-
-	serverOpts := client.NewRequestOptions()
-	serverOpts.QueryParameters.Add("cachegroupName", cacheGroupName)
-	serverOpts.QueryParameters.Add("topology", topologyName)
-	serverOpts.QueryParameters.Add("cdn", strconv.Itoa(cdnID))
-	servers, _, err := TOSession.GetServers(serverOpts)
-	if err != nil {
-		t.Fatalf("getting server from CDN '%s', from Cache Group '%s', and in Topology '%s': %v - alerts: %+v", cdnName, cacheGroupName, topologyName, err, servers.Alerts)
-	}
-	if len(servers.Response) != expectedLength {
-		t.Fatalf("expected to get %d server from cdn %s from cachegroup %s in topology %s, got %d servers", expectedLength, cdnName, cacheGroupName, topologyName, len(servers.Response))
-	}
-	server := servers.Response[0]
-	if server.ID == nil || server.CDNID == nil || len(server.ProfileNames) == 0 || server.CachegroupID == nil || server.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined ID and/or CDN ID and/or Profile Names and/or Cache Group ID and/or Host Name")
-	}
-
-	_, reqInf, err := TOSession.DeleteServer(*server.ID, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error deleting server with id %d, received no error", *server.ID)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error deleting server with id %d, got status code %d: %s", *server.ID, reqInf.StatusCode, err.Error())
-	}
-
-	// attempt to move it to another CDN while it's the last server in the cachegroup in its CDN
-	opts.QueryParameters.Set("name", "cdn1")
-	cdns, _, err = TOSession.GetCDNs(opts)
-	if err != nil {
-		t.Fatalf("unable to get CDN 'cdn1': %v - alerts: %+v", err, cdns.Alerts)
-	}
-	if len(cdns.Response) < 1 {
-		t.Fatalf("Expected exactly one CDN to exist with name 'cdn1', found: %d", len(cdns.Response))
-	}
-	newCDNID := cdns.Response[0].ID
-	oldCDNID := *server.CDNID
-	server.CDNID = &newCDNID
-	opts.QueryParameters.Set("name", "MID1")
-	profiles, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Errorf("unable to get Profile 'MID1': %v - alerts: %+v", err, profiles.Alerts)
-	}
-	if len(profiles.Response) != 1 {
-		t.Fatalf("Expected exactly one Profile to exist with name 'MID1', found: %d", len(profiles.Response))
-	}
-	newProfileID := profiles.Response[0].ID
-	oldProfileName := server.ProfileNames[0]
-
-	opts.QueryParameters.Set("id", strconv.Itoa(newProfileID))
-	nps, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Fatalf("failed to query profiles: %v", err)
-	}
-	if len(nps.Response) != 1 {
-		t.Fatalf("Expected exactly one Profile to exist, found: %d", len(profiles.Response))
-	}
-	server.ProfileNames = []string{nps.Response[0].Name}
-	opts.QueryParameters.Del("id")
-
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("changing the CDN of the last server (%s) in a CDN in a cachegroup used by a topology assigned to a delivery service(s) in that CDN - expected: error, actual: nil", *server.HostName)
-	}
-	server.CDNID = &oldCDNID
-	server.ProfileNames = []string{oldProfileName}
-
-	opts.QueryParameters.Set("name", moveToCacheGroup)
-	cgs, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("getting cachegroup with hostname %s: %v - alerts: %+v", moveToCacheGroup, err, cgs.Alerts)
-	}
-	if len(cgs.Response) != expectedLength {
-		t.Fatalf("expected %d cachegroup with hostname %s, received %d cachegroups", expectedLength, moveToCacheGroup, len(cgs.Response))
-	}
-	if cgs.Response[0].ID == nil {
-		t.Fatalf("Traffic Ops responded with Cache Group '%s' that had null or undefined ID", moveToCacheGroup)
-	}
-
-	alerts, _, err := TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("error updating server with hostname %s without moving it to a different Cache Group: %v - alerts: %+v", *server.HostName, err, alerts.Alerts)
-	}
-
-	*server.CachegroupID = *cgs.Response[0].ID
-	alerts, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error moving server with id %s to a different cachegroup, received no error", *server.HostName)
-	}
-	if reqInf.StatusCode < http.StatusBadRequest || reqInf.StatusCode >= http.StatusInternalServerError {
-		t.Fatalf("expected a 400-level error moving server with id %d to a different cachegroup, got status code %d: %v - alerts: %+v", *server.ID, reqInf.StatusCode, err, alerts.Alerts)
-	}
-}
-
-func UpdateTestServerStatus(t *testing.T) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", hostName)
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by hostname '%s': %v - alerts %+v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil || remoteServer.HostName == nil || remoteServer.StatusLastUpdated == nil {
-		t.Fatalf("Traffic Ops returned a representation for server '%s' with null or undefined ID and/or Host Name and/or Status Last Updated time", hostName)
-	}
-	id := fmt.Sprintf("%v", *remoteServer.ID)
-	originalStatusID := 0
-	updatedStatusID := 0
-
-	statuses, _, err := TOSession.GetStatuses(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot get Statuses: %v - alerts: %+v", err, statuses.Alerts)
-	}
-	for _, status := range statuses.Response {
-		if status.Name == "REPORTED" {
-			originalStatusID = status.ID
-		}
-		if status.Name == "ONLINE" {
-			updatedStatusID = status.ID
 		}
-	}
-	// Keeping the status same, perform an update and make sure that statusLastUpdated didnt change
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err := TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot UPDATE Server by ID %d (hostname '%s'): %v - alerts: %+v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("id", id)
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server #%s by ID: %v - alerts %+v", id, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer := resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if !remoteServer.StatusLastUpdated.Equal(*respServer.StatusLastUpdated) {
-		t.Errorf("since status didnt change, no change in 'StatusLastUpdated' time was expected. Difference observer: old value: %v, new value: %v",
-			remoteServer.StatusLastUpdated.String(), respServer.StatusLastUpdated.String())
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &updatedStatusID
-
-	alerts, _, err = TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot update Server #%d (hostname '%s'): %v - alerts %+v", *remoteServer.ID, hostName, err, alerts.Alerts)
-	}
-
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server by ID: %v - %v", *remoteServer.HostName, err)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-
-	// Changing the status, perform an update and make sure that statusLastUpdated changed
-	remoteServer.StatusID = &originalStatusID
-
-	alerts, _, err = TOSession.UpdateServer(*remoteServer.ID, remoteServer, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot update Server by ID %d (hostname '%s'): %v - alerts: %+v", *remoteServer.ID, hostName, err, alerts)
-	}
-
-	resp, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Errorf("cannot get Server by ID %d: %v - alerts: %+v", *remoteServer.ID, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	respServer = resp.Response[0]
-	if respServer.StatusLastUpdated == nil {
-		t.Fatal("Traffic Ops returned a representation for a server with null or undefined Status Last Updated time")
-	}
-
-	if *remoteServer.StatusLastUpdated == *respServer.StatusLastUpdated {
-		t.Errorf("since status was changed, expected to see a time difference between the old and new 'StatusLastUpdated' values, got the same value")
-	}
-}
-
-func UpdateTestServersWithHeaders(t *testing.T, header http.Header) {
-	if len(testData.Servers) < 1 {
-		t.Fatal("Need at least one server to test updating")
-	}
-
-	firstServer := testData.Servers[0]
-	if firstServer.HostName == nil {
-		t.Fatalf("First test server had nil hostname: %+v", firstServer)
-	}
-
-	hostName := *firstServer.HostName
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Add("hostName", hostName)
-	opts.Header = header
-
-	// Retrieve the server by hostname so we can get the id for the Update
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by hostname '%s': %v - alerts: %+v", hostName, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected at least one server to exist by hostname '%s'", hostName)
-	}
-	if len(resp.Response) > 1 {
-		t.Errorf("Expected exactly one server to exist by hostname '%s' - actual: %d", hostName, len(resp.Response))
-		t.Logf("Testing will proceed with server: %+v", resp.Response[0])
-	}
-
-	remoteServer := resp.Response[0]
-	if remoteServer.ID == nil {
-		t.Fatalf("Got null or undefined ID for server '%s'", hostName)
-	}
 
-	infs := remoteServer.Interfaces
-	if len(infs) < 1 {
-		t.Fatalf("Expected server '%s' to have at least one network interface", hostName)
-	}
-	inf := infs[0]
-
-	updatedServerInterface := "bond1"
-	updatedServerRack := "RR 119.03"
-	updatedHostName := "atl-edge-01"
-
-	// update rack, interfaceName and hostName values on server
-	inf.Name = updatedServerInterface
-	infs[0] = inf
-	remoteServer.Interfaces = infs
-	remoteServer.Rack = &updatedServerRack
-	remoteServer.HostName = &updatedHostName
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					server := tc.ServerV4{}
+
+					if testCase.RequestBody != nil {
+						dat, err := json.Marshal(testCase.RequestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &server)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.ClientSession.GetServers(testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.CreateServer(server, testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.UpdateServer(testCase.EndpointId(), server, testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.ClientSession.DeleteServer(testCase.EndpointId(), testCase.RequestOpts)
+							for _, check := range testCase.Expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					}
+				}
+			})
+		}
+		t.Run("DS SERVER ASSIGNMENT REMOVED when DS UPDATED TO USE TOPOLOGY", func(t *testing.T) { UpdateDSGetServerDSID(t) })
+		t.Run("STATUSLASTUPDATED ONLY CHANGES when STATUS CHANGES", func(t *testing.T) { UpdateTestServerStatusLastUpdated(t) })
 
-	opts.QueryParameters = nil
-	_, reqInf, err := TOSession.UpdateServer(*remoteServer.ID, remoteServer, opts)
-	if err == nil {
-		t.Errorf("Expected error about precondition failed, but got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
-	}
+	})
 }
 
-func GetTestServersIMSAfterChange(t *testing.T, header http.Header) {
-	opts := client.NewRequestOptions()
-	opts.Header = header
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusOK {
-			t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
+func validateServerFields(expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		for field, expected := range expectedResp {
+			for _, server := range serverResp {
+				switch field {
+				case "CachegroupID":
+					assert.Equal(t, expected, *server.CachegroupID, "Expected CachegroupID to be %v, but got %v", expected, *server.CachegroupID)
+				case "Cachegroup":
+					assert.Equal(t, expected, *server.Cachegroup, "Expected Cachegroup to be %v, but got %v", expected, *server.Cachegroup)
+				case "CDNName":
+					assert.Equal(t, expected, *server.CDNName, "Expected CDNName to be %v, but got %v", expected, *server.CDNName)
+				case "CDNID":
+					assert.Equal(t, expected, *server.CDNID, "Expected CDNID to be %v, but got %v", expected, *server.CDNID)
+				case "DomainName":
+					assert.Equal(t, expected, *server.DomainName, "Expected DomainName to be %v, but got %v", expected, *server.DomainName)
+				case "HostName":
+					assert.Equal(t, expected, *server.HostName, "Expected HostName to be %v, but got %v", expected, *server.HostName)
+				case "HTTPSPort":
+					assert.Equal(t, expected, *server.HTTPSPort, "Expected HTTPSPort to be %v, but got %v", expected, *server.HTTPSPort)
+				case "InterfaceName":
+					assert.Equal(t, expected, server.Interfaces[0].Name, "Expected InterfaceName to be %v, but got %v", expected, server.Interfaces[0].Name)
+				case "MTU":
+					assert.Equal(t, expected, *server.Interfaces[0].MTU, "Expected MTU to be %v, but got %v", expected, *server.Interfaces[0].MTU)
+				case "PhysLocation":
+					assert.Equal(t, expected, *server.PhysLocation, "Expected PhysLocation to be %v, but got %v", expected, *server.PhysLocation)
+				case "ProfileNames":
+					assert.Exactly(t, expected, server.ProfileNames, "Expected ProfileNames to be %v, but got %v", expected, server.ProfileNames)
+				case "Rack":
+					assert.Equal(t, expected, *server.Rack, "Expected Rack to be %v, but got %v", expected, *server.Rack)
+				case "Status":
+					assert.Equal(t, expected, *server.Status, "Expected Status to be %v, but got %v", expected, *server.Status)
+				case "TCPPort":
+					assert.Equal(t, expected, *server.TCPPort, "Expected TCPPort to be %v, but got %v", expected, *server.TCPPort)
+				case "Type":
+					assert.Equal(t, expected, server.Type, "Expected Type to be %v, but got %v", expected, server.Type)
+				case "TypeID":
+					assert.Equal(t, expected, *server.TypeID, "Expected Type to be %v, but got %v", expected, *server.TypeID)
+				default:
+					t.Errorf("Expected field: %v, does not exist in response", field)
+				}
+			}
 		}
 	}
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
+}
 
-	opts.Header.Set(rfc.IfModifiedSince, timeStr)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
+func validateServerFieldsForUpdate(hostname string, expectedResp map[string]interface{}) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("hostName", hostname)
+		servers, _, err := TOSession.GetServers(opts)
+		assert.NoError(t, err, "Error getting Server: %v - alerts: %+v", err, servers.Alerts)
+		assert.Equal(t, 1, len(servers.Response), "Expected Server one server returned Got: %d", len(servers.Response))
+		validateServerFields(expectedResp)(t, toclientlib.ReqInf{}, servers.Response, tc.Alerts{}, nil)
 	}
 }
 
-func GetTestServersIMS(t *testing.T) {
-	futureTime := time.Now().AddDate(0, 0, 1)
-	timestamp := futureTime.Format(time.RFC1123)
-
-	opts := client.NewRequestOptions()
-	opts.Header.Set(rfc.IfModifiedSince, timestamp)
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, reqInf, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Fatalf("Expected no error, but got: %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
+func validateExpectedServers(expectedHostnames []string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		var notInResponse []string
+		serverMap := make(map[string]struct{})
+		for _, server := range serverResp {
+			serverMap[*server.HostName] = struct{}{}
+		}
+		for _, expected := range expectedHostnames {
+			if _, exists := serverMap[expected]; !exists {
+				notInResponse = append(notInResponse, expected)
+			}
 		}
+		assert.Equal(t, len(notInResponse), 0, "%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
 	}
 }
 
-func CreateTestServers(t *testing.T) {
-	// loop through servers, assign FKs and create
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		resp, _, err := TOSession.CreateServer(server, client.RequestOptions{})
-		if err != nil {
-			t.Errorf("could not create server '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
+func validateServerTypeIsNotMid() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		assert.RequireNotNil(t, resp, "Expected response to not be nil.")
+		serverResp := resp.([]tc.ServerV40)
+		for _, server := range serverResp {
+			if server.Type == tc.CacheTypeMid.String() {
+				t.Errorf("Expected to find no %s-typed servers but found server %s", tc.CacheTypeMid, *server.HostName)
+			}
 		}
 	}
 }
 
-func CreateTestBlankFields(t *testing.T) {
-	serverResp, _, err := TOSession.GetServers(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldnt get servers: %v - alerts: %+v", err, serverResp.Alerts)
-	}
-	if len(serverResp.Response) < 1 {
-		t.Fatal("expected at least one server")
-	}
-	server := serverResp.Response[0]
-	if server.ID == nil {
-		t.Fatal("Traffic Ops returned a representation for a servver with null or undefined ID")
-	}
-	originalHost := server.HostName
-
-	server.HostName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Error("should not be able to update server with blank HostName")
-	}
+func validateServerPagination(paginationParam string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		paginationResp := resp.([]tc.ServerV40)
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("orderby", "id")
+		respBase, _, err := TOSession.GetServers(opts)
+		assert.RequireNoError(t, err, "Cannot get Servers: %v - alerts: %+v", err, respBase.Alerts)
 
-	server.HostName = originalHost
-	server.DomainName = util.StrPtr("")
-	_, _, err = TOSession.UpdateServer(*server.ID, server, client.RequestOptions{})
-	if err == nil {
-		t.Error("should not be able to update server with blank DomainName")
+		ds := respBase.Response
+		assert.RequireGreaterOrEqual(t, len(ds), 3, "Need at least 3 Servers in Traffic Ops to test pagination support, found: %d", len(ds))
+		switch paginationParam {
+		case "limit:":
+			assert.Exactly(t, ds[:1], paginationResp, "expected GET Servers with limit = 1 to return first result")
+		case "offset":
+			assert.Exactly(t, ds[1:2], paginationResp, "expected GET Servers with limit = 1, offset = 1 to return second result")
+		case "page":
+			assert.Exactly(t, ds[1:2], paginationResp, "expected GET Servers with limit = 1, page = 2 to return second result")
+		}
 	}
 }
 
-// This test will break if the structure of the test data servers collection
-// is changed at all.
-func CreateTestServerWithoutProfileID(t *testing.T) {
-	if len(testData.Servers) < 20 {
-		t.Fatal("Need at least 20 servers to test creating a server without a Profile")
-	}
-	testServer := testData.Servers[19]
-	if testServer.HostName == nil {
-		t.Fatal("Found a server in the test data with null or undefined Host Name")
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("hostName", *testServer.HostName)
-
-	resp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("cannot get Server by Host Name '%s': %v - alerts: %+v", *testServer.HostName, err, resp.Alerts)
-	}
-
-	server := resp.Response[0]
-	if len(server.ProfileNames) == 0 || server.ID == nil || server.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation of a server with null or undefined ID and/or Profile and/or Host Name")
-	}
-	originalProfile := server.ProfileNames
-	delResp, _, err := TOSession.DeleteServer(*server.ID, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("cannot delete Server by ID %d: %v - %v", *server.ID, err, delResp)
-	}
-
-	server.ProfileNames = []string{""}
-	_, reqInfo, _ := TOSession.CreateServer(server, client.RequestOptions{})
-	if reqInfo.StatusCode != 400 {
-		t.Fatalf("Expected status code: %v but got: %v", "400", reqInfo.StatusCode)
-	}
-
-	//Reverting it back for further tests
-	server.ProfileNames = originalProfile
-	response, _, err := TOSession.CreateServer(server, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create server: %v - alerts: %+v", err, response.Alerts)
-	}
+func generateServer(t *testing.T, requestServer map[string]interface{}) map[string]interface{} {
+	// map for the most basic Server a user can create
+	genericServer := map[string]interface{}{
+		"cdnId":        GetCDNId(t, "cdn1"),
+		"cachegroupId": GetCacheGroupId(t, "cachegroup1")(),
+		"domainName":   "localhost",
+		"hostName":     "testserver",
+		"interfaces": []map[string]interface{}{{
+			"ipAddresses": []map[string]interface{}{{
+				"address":        "127.0.0.1",
+				"serviceAddress": true,
+			}},
+			"name": "eth0",
+		}},
+		"physLocationId": GetPhysLocationId(t, "Denver")(),
+		"profileNames":   []string{"EDGE1"},
+		"statusId":       GetStatusId(t, "REPORTED")(),
+		"typeId":         GetTypeId(t, "EDGE"),
+	}
+
+	for k, v := range requestServer {
+		genericServer[k] = v
+	}
+	return genericServer
 }
 
-func GetTestServers(t *testing.T) {
-	opts := client.NewRequestOptions()
-	for _, server := range testData.Servers {
-		if server.HostName == nil {
-			t.Errorf("found server with nil hostname: %+v", server)
-			continue
-		}
-		opts.QueryParameters.Set("hostName", *server.HostName)
-		resp, _, err := TOSession.GetServers(opts)
-		if err != nil {
-			t.Errorf("cannot get Server by Host Name '%s': %v - alerts: %+v", *server.HostName, err, resp.Alerts)
-		} else if resp.Summary.Count != 1 {
-			t.Errorf("incorrect server count, expected: 1, actual: %d", resp.Summary.Count)
-		}
+func GetServerId(t *testing.T, hostName string) func() int {
+	return func() int {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("hostName", hostName)
+		serversResp, _, err := TOSession.GetServers(opts)
+		assert.RequireNoError(t, err, "Get Servers Request failed with error:", err)
+		assert.RequireEqual(t, 1, len(serversResp.Response), "Expected response object length 1, but got %d", len(serversResp.Response))
+		assert.RequireNotNil(t, serversResp.Response[0].ID, "Expected id to not be nil")
+		return *serversResp.Response[0].ID
 	}
 }
 
-func GetTestServersQueryParameters(t *testing.T) {
-	dses, _, err := TOSession.GetDeliveryServices(client.RequestOptions{QueryParameters: url.Values{"xmlId": []string{"ds1"}}})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v - alerts: %+v", err, dses.Alerts)
-	}
-	if len(dses.Response) < 1 {
-		t.Fatal("Failed to get at least one Delivery Service")
-	}
-
-	ds := dses.Response[0]
-	if ds.ID == nil {
-		t.Fatal("Traffic Ops returned a representation of a Delivery Service with null or undefined ID")
-	}
-
-	AssignTestDeliveryService(t)
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("dsId", strconv.Itoa(*ds.ID))
-	servers, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get server by Delivery Service ID: %v - alerts: %+v", err, servers.Alerts)
-	}
-	if len(servers.Response) != 3 {
-		t.Fatalf("expected to get 3 servers for Delivery Service: %d, actual: %d", *ds.ID, len(servers.Response))
-	}
-
-	currentTime := time.Now().UTC().Add(5 * time.Second)
-	timestamp := currentTime.Format(time.RFC1123)
-
-	opts.Header.Set(rfc.IfModifiedSince, timestamp)
-	_, reqInf, _ := TOSession.GetServers(opts)
-	if reqInf.StatusCode != http.StatusNotModified {
-		t.Errorf("Expected a status code of 304, got %v", reqInf.StatusCode)
-	}
-
-	dses, _, err = TOSession.GetDeliveryServices(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v - alerts: %+v", err, dses.Alerts)
-	}
-
-	foundTopDs := false
-	const (
-		topDSXmlID = "ds-top"
-		topology   = "mso-topology"
-	)
-	for _, ds = range dses.Response {
-		if ds.XMLID == nil || ds.ID == nil {
-			t.Error("Traffic Ops returned a representation of a Delivery Service that had a null or undefined XMLID and/or ID")
-			continue
-		}
-		if *ds.XMLID != topDSXmlID {
-			continue
-		}
-		if ds.Topology == nil || ds.FirstHeaderRewrite == nil || ds.InnerHeaderRewrite == nil || ds.LastHeaderRewrite == nil {
-			t.Errorf("Traffic Ops returned a representation of Delivery Service '%s' that had a null or undefined Topology and/or First Header Rewrite text and/or Inner Header Rewrite text and/or Last Header Rewrite text", topDSXmlID)
-			continue
-		}
-		foundTopDs = true
-		break
-	}
-	if !foundTopDs {
-		t.Fatalf("unable to find deliveryservice %s", topDSXmlID)
-	}
-
-	/* Create a deliveryservice server assignment that should not show up in the
-	 * client.GetServers( response because ds-top is topology-based
-	 */
-	const otherServerHostname = "topology-edge-02"
-	serverResponse, _, err := TOSession.GetServers(client.RequestOptions{QueryParameters: url.Values{"hostName": []string{otherServerHostname}}})
-	if err != nil {
-		t.Fatalf("getting server by Host Name %s: %v - alerts: %+v", otherServerHostname, err, serverResponse.Alerts)
-	}
-	if len(serverResponse.Response) != 1 {
-		t.Fatalf("unable to find server with hostname %s", otherServerHostname)
-	}
-	otherServer := serverResponse.Response[0]
-	if otherServer.ID == nil || otherServer.HostName == nil {
-		t.Fatal("Traffic Ops returned a representation of a Server that had a null or undefined ID and/or Host Name")
-	}
-
-	dsTopologyField, dsFirstHeaderRewriteField, innerHeaderRewriteField, lastHeaderRewriteField := *ds.Topology, *ds.FirstHeaderRewrite, *ds.InnerHeaderRewrite, *ds.LastHeaderRewrite
-	ds.Topology, ds.FirstHeaderRewrite, ds.InnerHeaderRewrite, ds.LastHeaderRewrite = nil, nil, nil, nil
-	updResp, _, err := TOSession.UpdateDeliveryService(*ds.ID, ds, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to temporary remove topology-related fields from deliveryservice '%s': %v - alerts: %+v", topDSXmlID, err, updResp.Alerts)
-	}
-	if len(updResp.Response) != 1 {
-		t.Fatalf("Expected updating a Delivery Service to update exactly one Delivery Service, but Traffic Ops indicates that %d were updated", len(updResp.Response))
-	}
-	ds = updResp.Response[0]
-	if ds.ID == nil {
-		t.Fatal("Traffic Ops returned a representation of a Delivery Service that had null or undefined ID")
-	}
-	assignResp, _, err := TOSession.CreateDeliveryServiceServers(*ds.ID, []int{*otherServer.ID}, false, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to assign server '%s' to Delivery Service '%s': %v - alerts: %+v", *otherServer.HostName, topDSXmlID, err, assignResp.Alerts)
-	}
-	ds.Topology, ds.FirstHeaderRewrite, ds.InnerHeaderRewrite, ds.LastHeaderRewrite = &dsTopologyField, &dsFirstHeaderRewriteField, &innerHeaderRewriteField, &lastHeaderRewriteField
-	updResp, _, err = TOSession.UpdateDeliveryService(*ds.ID, ds, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to re-add topology-related fields to deliveryservice %s: %v - alerts: %+v", topDSXmlID, err, updResp.Alerts)
-	}
-
-	opts.Header = nil
-	opts.QueryParameters.Set("dsId", strconv.Itoa(*ds.ID))
-	expectedHostnames := map[string]bool{
-		"edge1-cdn1-cg3":                 false,
-		"edge2-cdn1-cg3":                 false,
-		"atlanta-mid-01":                 false,
-		"atlanta-mid-16":                 false,
-		"edgeInCachegroup3":              false,
-		"midInSecondaryCachegroupInCDN1": false,
-	}
-	response, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %v - alerts: %+v", topDSXmlID, err, response.Alerts)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s", topDSXmlID)
-	}
-	for _, server := range response.Response {
-		if server.HostName == nil {
-			t.Fatal("Traffic Ops responded with a representation for a server with null or undefined Host Name")
-		}
-		if _, exists := expectedHostnames[*server.HostName]; !exists {
-			t.Fatalf("expected hostnames %v, actual %s", expectedHostnames, *server.HostName)
-		}
-		expectedHostnames[*server.HostName] = true
-	}
-	var notInResponse []string
-	for hostName, inResponse := range expectedHostnames {
-		if !inResponse {
-			notInResponse = append(notInResponse, hostName)
-		}
-	}
-	if len(notInResponse) != 0 {
-		t.Fatalf("%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
-	}
-	const originHostname = "denver-mso-org-01"
-	if resp, _, err := TOSession.AssignServersToDeliveryService([]string{originHostname}, topDSXmlID, client.RequestOptions{}); err != nil {
-		t.Fatalf("assigning origin server '%s' to Delivery Service '%s': %v - alerts: %+v", originHostname, topDSXmlID, err, resp.Alerts)
-	}
-	response, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %v - alerts: %+v", topDSXmlID, err, response.Alerts)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s", topDSXmlID)
-	}
-	containsOrigin := false
-	for _, server := range response.Response {
-		if server.HostName == nil || *server.HostName != originHostname {
-			continue
-		}
-		containsOrigin = true
-		break
-	}
-	if !containsOrigin {
-		t.Fatalf("did not find origin server %s when querying servers by dsId after assigning %s to delivery service %s", originHostname, originHostname, topDSXmlID)
-	}
-
-	const topDsWithNoMids = "ds-based-top-with-no-mids"
-	dses, _, err = TOSession.GetDeliveryServices(client.RequestOptions{QueryParameters: url.Values{"xmlId": []string{topDsWithNoMids}}})
-	if err != nil {
-		t.Fatalf("Failed to get Delivery Services: %v - alerts: %+v", err, dses.Alerts)
-	}
-	if len(dses.Response) < 1 {
-		t.Fatal("Failed to get at least one Delivery Service")
-	}
-
-	ds = dses.Response[0]
-	if ds.ID == nil {
-		t.Fatal("Got Delivery Service with nil ID")
-	}
-	opts.QueryParameters.Set("dsId", strconv.Itoa(*ds.ID))
-
-	response, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers by Topology-based Delivery Service ID with xmlId %s: %s", topDsWithNoMids, err)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers for Topology-based Delivery Service with xmlId %s: %s", topDsWithNoMids, err)
-	}
-	for _, server := range response.Response {
-		if server.HostName == nil {
-			t.Fatal("Traffic Ops returned a server with null or undefined Host Name")
-		}
-		if server.Type == tc.CacheTypeMid.String() {
-			t.Fatalf("Expected to find no %s-typed servers when querying servers by the ID for Delivery Service with XMLID %s but found %s-typed server %s", tc.CacheTypeMid, topDsWithNoMids, tc.CacheTypeMid, *server.HostName)
-		}
-	}
-
-	opts.QueryParameters.Del("dsId")
-	opts.QueryParameters.Set("topology", topology)
-	expectedHostnames = map[string]bool{
-		originHostname:                   false,
-		"denver-mso-org-02":              false,
-		"edge1-cdn1-cg3":                 false,
-		"edge2-cdn1-cg3":                 false,
-		"atlanta-mid-01":                 false,
-		"atlanta-mid-16":                 false,
-		"atlanta-mid-17":                 false,
-		"edgeInCachegroup3":              false,
-		"midInParentCachegroup":          false,
-		"midInSecondaryCachegroup":       false,
-		"midInSecondaryCachegroupInCDN1": false,
-		"test-mso-org-01":                false,
-	}
-	response, _, err = TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("Failed to get servers belonging to Cache Groups in Topology %s: %v - alerts: %+v", topology, err, response.Alerts)
-	}
-	if len(response.Response) == 0 {
-		t.Fatalf("Did not find any servers belonging to Cache Groups in Topology %s:", topology)
-	}
-	for _, server := range response.Response {
-		if server.HostName == nil {
-			t.Fatal("Traffic Ops returned a server with null or undefined Host Name")
-		}
-		if _, exists := expectedHostnames[*server.HostName]; !exists {
-			t.Fatalf("expected hostnames %v, actual %s", expectedHostnames, *server.HostName)
-		}
-		expectedHostnames[*server.HostName] = true
-	}
-	notInResponse = []string{}
-	for hostName, inResponse := range expectedHostnames {
-		if !inResponse {
-			notInResponse = append(notInResponse, hostName)
-		}
-	}
-	if len(notInResponse) != 0 {
-		t.Fatalf("%d servers missing from the response: %s", len(notInResponse), strings.Join(notInResponse, ", "))
-	}
-	opts.QueryParameters.Del("topology")
-
-	resp, _, err := TOSession.GetServers(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("Failed to get servers: %v - alerts: %+v", err, resp.Alerts)
-	}
-
-	if len(resp.Response) < 1 {
-		t.Fatal("Failed to get at least one server")
-	}
-
-	s := resp.Response[0]
-
-	opts.QueryParameters.Set("type", s.Type)
-	if resp, _, err := TOSession.GetServers(opts); err != nil {
-		t.Errorf("Error getting servers by Type: %v - alerts: %+v", err, resp.Alerts)
-	}
-	opts.QueryParameters.Del("type")
-
-	if s.CachegroupID == nil {
-		t.Error("Found server with no Cache Group ID")
-	} else {
-		opts.QueryParameters.Add("cachegroup", strconv.Itoa(*s.CachegroupID))
-		if resp, _, err := TOSession.GetServers(opts); err != nil {
-			t.Errorf("Error getting servers by Cache Group ID: %v - alerts: %+v", err, resp.Alerts)
-		}
-		opts.QueryParameters.Del("cachegroup")
-	}
-
-	if s.Status == nil {
-		t.Error("Found server with no status")
-	} else {
-		opts.QueryParameters.Add("status", *s.Status)
-		if resp, _, err := TOSession.GetServers(opts); err != nil {
-			t.Errorf("Error getting servers by status: %v - alerts: %+v", err, resp.Alerts)
-		}
-		opts.QueryParameters.Del("status")
-	}
-
-	opts.QueryParameters.Add("name", s.ProfileNames[0])
-	pr, _, err := TOSession.GetProfiles(opts)
-	if err != nil {
-		t.Fatalf("failed to query profile: %v", err)
-	}
-	if len(pr.Response) != 1 {
-		t.Error("Found server with no Profile ID")
-	} else {
-		profileName := pr.Response[0].Name
-		opts.QueryParameters.Add("profileName", profileName)
-		if resp, _, err := TOSession.GetServers(opts); err != nil {
-			t.Errorf("Error getting servers by Profile ID: %v - alerts: %+v", err, resp.Alerts)
-		}
-		opts.QueryParameters.Del("profileName")
-	}
-
-	cgs, _, err := TOSession.GetCacheGroups(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("Failed to get Cache Groups: %v", err)
-	}
-	if len(cgs.Response) < 1 {
-		t.Fatal("Failed to get at least one Cache Group")
-	}
-	if cgs.Response[0].ID == nil {
-		t.Fatal("Cache Group found with no ID")
-	}
-
-	opts.QueryParameters.Add("parentCacheGroup", strconv.Itoa(*cgs.Response[0].ID))
-	if resp, _, err = TOSession.GetServers(opts); err != nil {
-		t.Errorf("Error getting servers by parent Cache Group: %v - alerts: %+v", err, resp.Alerts)
+func GetStatusId(t *testing.T, name string) func() int {
+	return func() int {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("name", name)
+		statusResp, _, err := TOSession.GetStatuses(opts)
+		assert.RequireNoError(t, err, "Get Statuses Request failed with error:", err)
+		assert.RequireEqual(t, 1, len(statusResp.Response), "Expected response object length 1, but got %d", len(statusResp.Response))
+		assert.RequireNotNil(t, statusResp.Response[0].ID, "Expected id to not be nil")
+		return statusResp.Response[0].ID
 	}
-	opts.QueryParameters.Del("parentCacheGroup")
 }
 
-func UniqueIPProfileTestServers(t *testing.T) {
-	serversResp, _, err := TOSession.GetServers(client.RequestOptions{})
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(serversResp.Response) < 1 {
-		t.Fatal("expected more than 0 servers")
-	}
-	xmppID := "unique"
-	var server tc.ServerV40
-	for _, s := range serversResp.Response {
-		if len(s.Interfaces) >= 1 && s.Interfaces[0].Monitor {
-			server = s
-			break
-		}
-	}
-	_, _, err = TOSession.CreateServer(tc.ServerV40{
-		Cachegroup: server.Cachegroup,
-		CDNName:    server.CDNName,
-		DomainName: util.StrPtr("mydomain"),
-		FQDN:       util.StrPtr("myfqdn"),
-		FqdnTime:   time.Time{},
-		HostName:   util.StrPtr("myhostname"),
-		HTTPSPort:  util.IntPtr(443),
-		LastUpdated: &tc.TimeNoMod{
-			Time:  time.Time{},
-			Valid: false,
-		},
-		PhysLocation: server.PhysLocation,
-		ProfileNames: server.ProfileNames,
-		StatusID:     server.StatusID,
-		Type:         server.Type,
-		UpdPending:   util.BoolPtr(false),
-		XMPPID:       &xmppID,
-		Interfaces:   server.Interfaces,
-	}, client.RequestOptions{})
-
-	if err == nil {
-		t.Error("expected an error when updating a server with an ipaddress that already exists on another server with the same profile")
-		// Cleanup, don't want to break other tests
+func GetPhysLocationId(t *testing.T, name string) func() int {

Review Comment:
   func `GetPhysLocationId` should be `GetPhysLocationID` - or better yet, `GetPhysicalLocationID`



-- 
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.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org