This is an automated email from the ASF dual-hosted git repository.

zrhoffman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new a28e152  Refactor cdn locks tests (#6579)
a28e152 is described below

commit a28e1524af7629292f3d0be919b12e32ee089fa6
Author: Eric Holguin <[email protected]>
AuthorDate: Thu Mar 10 13:38:47 2022 -0700

    Refactor cdn locks tests (#6579)
    
    * Initial refactor
    
    * Added prereqs fro cdnlocks test
    
    * Added CDNLock object with create and delete functions
    
    * Added field keys
    
    * Added test and cleaned up code
    
    * Updated cdn lock to hard lock
    
    * Moved cdnlock test to cdnlock_test
    
    * Fix test needing a prereq lock
    
    * Changed user with lock username
    
    * Updated tests to use V4TestCase struct
    
    * Add CreateSession functionality for v3 and v4
    
    * Use new CreateV4Session functionality
    
    * Added test to check get response fields
---
 traffic_ops/testing/api/utils/utils.go             |  15 +
 traffic_ops/testing/api/v4/cachegroups_test.go     |  83 ---
 traffic_ops/testing/api/v4/cdn_locks_test.go       | 700 ++++++++-------------
 traffic_ops/testing/api/v4/tc-fixtures.json        |  41 ++
 traffic_ops/testing/api/v4/traffic_control_test.go |   1 +
 traffic_ops/testing/api/v4/withobjs_test.go        |   2 +
 6 files changed, 323 insertions(+), 519 deletions(-)

diff --git a/traffic_ops/testing/api/utils/utils.go 
b/traffic_ops/testing/api/utils/utils.go
index 9fc854d..b9c4e96 100644
--- a/traffic_ops/testing/api/utils/utils.go
+++ b/traffic_ops/testing/api/utils/utils.go
@@ -22,6 +22,7 @@ import (
        "reflect"
        "sort"
        "testing"
+       "time"
 
        "github.com/apache/trafficcontrol/lib/go-tc"
        "github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
@@ -83,6 +84,20 @@ func Compare(t *testing.T, expected []string, alertsStrs 
[]string) {
        }
 }
 
+// CreateV3Session creates a session for client v4 using the passed in 
username and password.
+func CreateV3Session(t *testing.T, TrafficOpsURL string, username string, 
password string, toReqTimeout int) *v3client.Session {
+       userSession, _, err := v3client.LoginWithAgent(TrafficOpsURL, username, 
password, true, "to-api-v3-client-tests", false, 
time.Second*time.Duration(toReqTimeout))
+       assert.RequireNoError(t, err, "Could not login with user %v: %v", 
username, err)
+       return userSession
+}
+
+// CreateV4Session creates a session for client v4 using the passed in 
username and password.
+func CreateV4Session(t *testing.T, TrafficOpsURL string, username string, 
password string, toReqTimeout int) *v4client.Session {
+       userSession, _, err := v4client.LoginWithAgent(TrafficOpsURL, username, 
password, true, "to-api-v4-client-tests", false, 
time.Second*time.Duration(toReqTimeout))
+       assert.RequireNoError(t, err, "Could not login with user %v: %v", 
username, err)
+       return userSession
+}
+
 // V3TestCase is the type of the V3TestData struct.
 // Uses nested map to represent the method being tested and the test's 
description.
 type V3TestCase map[string]map[string]V3TestData
diff --git a/traffic_ops/testing/api/v4/cachegroups_test.go 
b/traffic_ops/testing/api/v4/cachegroups_test.go
index ea99bc5..dff9c26 100644
--- a/traffic_ops/testing/api/v4/cachegroups_test.go
+++ b/traffic_ops/testing/api/v4/cachegroups_test.go
@@ -25,7 +25,6 @@ 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"
@@ -223,9 +222,6 @@ func TestCacheGroups(t *testing.T) {
                                        Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
                                },
                        },
-                       "CDNLOCK": {
-                               "FORBIDDEN when updating CG when CDN LOCK 
EXISTS": {},
-                       },
                }
 
                for method, testCases := range methodTests {
@@ -286,10 +282,6 @@ func TestCacheGroups(t *testing.T) {
                                                                check(t, 
reqInf, nil, alerts, err)
                                                        }
                                                })
-                                       case "CDNLOCK":
-                                               t.Run(name, func(t *testing.T) {
-                                                       
UpdateCachegroupWithLocks(t)
-                                               })
                                        }
                                }
                        })
@@ -374,81 +366,6 @@ func GetCacheGroupId(t *testing.T, cacheGroupName string) 
func() int {
        }
 }
 
-func UpdateCachegroupWithLocks(t *testing.T) {
-       var cdnName string
-       servers := make([]tc.ServerV40, 0)
-       opts := client.NewRequestOptions()
-       opts.QueryParameters.Add("name", "cachegroup1")
-       cgResp, _, err := TOSession.GetCacheGroups(opts)
-       assert.RequireNoError(t, err, "couldn't get cachegroup: %v", err)
-       assert.RequireEqual(t, 1, len(cgResp.Response), "expected only one 
cachegroup in response, but got %d, quitting", len(cgResp.Response))
-
-       opts.QueryParameters.Del("name")
-       opts.QueryParameters.Add("cachegroupName", "cachegroup1")
-       serversResp, _, err := TOSession.GetServers(opts)
-       assert.RequireNoError(t, err, "couldn't get servers for cachegroup: 
%v", err)
-
-       servers = serversResp.Response
-       assert.RequireGreaterOrEqual(t, len(servers), 1, "couldn't get a 
cachegroup with 1 or more servers assigned, quitting")
-
-       server := servers[0]
-       if server.CDNName != nil {
-               cdnName = *server.CDNName
-       } else if server.CDNID != nil {
-               opts = client.RequestOptions{}
-               opts.QueryParameters.Add("id", strconv.Itoa(*server.CDNID))
-               cdnResp, _, err := TOSession.GetCDNs(opts)
-               assert.RequireNoError(t, err, "couldn't get CDN: %v", err)
-               assert.RequireEqual(t, 1, len(cdnResp.Response), "expected only 
one CDN in response, but got %d", len(cdnResp.Response))
-
-               cdnName = cdnResp.Response[0].Name
-       }
-
-       // 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("[email protected]")
-       user1.TenantID = 1
-       user1.FullName = util.StrPtr("firstName LastName")
-       _, _, err = TOSession.CreateUser(user1, client.RequestOptions{})
-       assert.RequireNoError(t, err, "could not create test user with 
username: %s. err: %v", user1.Username, err)
-
-       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)
-       assert.RequireNoError(t, err, "could not login with user lock_user1: 
%v", err)
-
-       // Create a lock for this user
-       _, _, err = userSession.CreateCDNLock(tc.CDNLock{
-               CDN:     cdnName,
-               Message: util.StrPtr("test lock"),
-               Soft:    util.BoolPtr(false),
-       }, client.RequestOptions{})
-       assert.RequireNoError(t, err, "couldn't create cdn lock: %v", err)
-
-       cg := cgResp.Response[0]
-
-       // Try to update a cachegroup on a CDN that another user has a hard 
lock on -> this should fail
-       cg.ShortName = util.StrPtr("changedShortName")
-       _, reqInf, err := TOSession.UpdateCacheGroup(*cg.ID, cg, 
client.RequestOptions{})
-       assert.Error(t, err, "expected an error while updating a cachegroup for 
a CDN for which a hard lock is held by another user, but got nothing")
-       assert.Equal(t, http.StatusForbidden, reqInf.StatusCode, "expected a 
403 forbidden status while updating a cachegroup for a CDN for which a hard 
lock is held by another user, but got %d", reqInf.StatusCode)
-
-       // Try to update a cachegroup on a CDN that the same user has a hard 
lock on -> this should succeed
-       _, reqInf, err = userSession.UpdateCacheGroup(*cg.ID, cg, 
client.RequestOptions{})
-       assert.NoError(t, err, "expected no error while updating a cachegroup 
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{cdnName}}})
-       assert.NoError(t, err, "expected no error while deleting other user's 
lock using admin endpoint, but got %v", err)
-}
-
 func CreateTestCacheGroups(t *testing.T) {
        for _, cg := range testData.CacheGroups {
 
diff --git a/traffic_ops/testing/api/v4/cdn_locks_test.go 
b/traffic_ops/testing/api/v4/cdn_locks_test.go
index d6f1341..5cd6f3e 100644
--- a/traffic_ops/testing/api/v4/cdn_locks_test.go
+++ b/traffic_ops/testing/api/v4/cdn_locks_test.go
@@ -16,470 +16,298 @@ package v4
 */
 
 import (
+       "encoding/json"
        "net/http"
        "net/url"
-       "strconv"
        "testing"
-       "time"
 
        "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 TestCDNLocks(t *testing.T) {
-       WithObjs(t, []TCObj{Types, CacheGroups, CDNs, Parameters, Profiles, 
Statuses, Divisions, Regions, PhysLocations, Servers, ServerCapabilities, 
ServerServerCapabilitiesForTopologies, Topologies, Tenants, ServiceCategories, 
DeliveryServices, TopologyBasedDeliveryServiceRequiredCapabilities, Roles, 
Users}, func() {
-               CRDCdnLocks(t)
-               AdminCdnLocks(t)
-               SnapshotWithLock(t)
-               QueueUpdatesWithLock(t)
-               QueueUpdatesFromTopologiesWithLock(t)
-       })
-}
-
-func getCDNName(t *testing.T) string {
-       cdnResp, _, err := TOSession.GetCDNs(client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't get CDNs: %v", err)
-       }
-       if len(cdnResp.Response) < 1 {
-               t.Fatalf("no valid CDNs in response")
-       }
-       return cdnResp.Response[0].Name
-}
-
-func getCDNNameAndServerID(t *testing.T) (string, int) {
-       serverID := -1
-       cdnResp, _, err := TOSession.GetCDNs(client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't get CDNs: %v", err)
-       }
-       if len(cdnResp.Response) < 1 {
-               t.Fatalf("no valid CDNs in response")
-       }
-       for _, cdn := range cdnResp.Response {
-               opts := client.NewRequestOptions()
-               opts.QueryParameters.Set("cdn", strconv.Itoa(cdn.ID))
-               serversResp, _, err := TOSession.GetServers(opts)
-               if err != nil {
-                       t.Errorf("could not get servers for cdn %s: %v", 
cdn.Name, err)
-               }
-               if len(serversResp.Response) != 0 && serversResp.Response[0].ID 
!= nil {
-                       serverID = *serversResp.Response[0].ID
-                       return cdn.Name, serverID
+       WithObjs(t, []TCObj{Types, CacheGroups, CDNs, Parameters, Profiles, 
Statuses, Divisions, Regions, PhysLocations, Servers, Topologies, Tenants, 
Roles, Users, CDNLocks}, func() {
+
+               opsUserSession := utils.CreateV4Session(t, 
Config.TrafficOps.URL, "opsuser", "pa$$word", 
Config.Default.Session.TimeoutInSecs)
+               opsUserWithLockSession := utils.CreateV4Session(t, 
Config.TrafficOps.URL, "opslockuser", "pa$$word", 
Config.Default.Session.TimeoutInSecs)
+
+               methodTests := utils.V4TestCase{
+                       "GET": {
+                               "OK when VALID request": {
+                                       ClientSession: TOSession, Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+                                               
utils.ResponseLengthGreaterOrEqual(1)),
+                               },
+                               "OK when VALID CDN parameter": {
+                                       ClientSession: TOSession, RequestOpts: 
client.RequestOptions{QueryParameters: url.Values{"cdn": {"cdn2"}}},
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), 
utils.ResponseHasLength(1),
+                                               
validateGetResponseFields(map[string]interface{}{"username": "opslockuser", 
"cdn": "cdn2", "message": "test lock for updates", "soft": false})),
+                               },
+                       },
+                       "POST": {
+                               "CREATED when VALID request": {
+                                       ClientSession: TOSession,
+                                       RequestBody: map[string]interface{}{
+                                               "cdn":     "cdn3",
+                                               "message": "snapping cdn",
+                                               "soft":    true,
+                                       },
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusCreated),
+                                               
validateCreateResponseFields(map[string]interface{}{"username": "admin", "cdn": 
"cdn3", "message": "snapping cdn", "soft": true})),
+                               },
+                       },
+                       "DELETE": {
+                               "OK when VALID request": {
+                                       ClientSession: TOSession, RequestOpts: 
client.RequestOptions{QueryParameters: url.Values{"cdn": {"cdn1"}}},
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+                               },
+                               "FORBIDDEN when NON-ADMIN USER DOESNT OWN 
LOCK": {
+                                       ClientSession: opsUserSession,
+                                       RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"cdn": {"cdn4"}}},
+                                       Expectations:  
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
+                               },
+                               "OK when ADMIN USER DOESNT OWN LOCK": {
+                                       ClientSession: TOSession, RequestOpts: 
client.RequestOptions{QueryParameters: url.Values{"cdn": {"cdn4"}}},
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+                               },
+                       },
+                       "SNAPSHOT": {
+                               "OK when USER OWNS LOCK": {
+                                       ClientSession: opsUserWithLockSession,
+                                       RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"cdn": {"cdn2"}}},
+                                       Expectations:  
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+                               },
+                               "FORBIDDEN when ADMIN USER DOESNT OWN LOCK": {
+                                       ClientSession: TOSession, RequestOpts: 
client.RequestOptions{QueryParameters: url.Values{"cdn": {"cdn2"}}},
+                                       Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
+                               },
+                       },
+                       "SERVERS QUEUE UPDATES": {
+                               "OK when USER OWNS LOCK": {
+                                       EndpointId: getServerID(t, 
"cdn2-test-edge"), ClientSession: opsUserWithLockSession,
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+                               },
+                               "FORBIDDEN when ADMIN USER DOESNT OWN LOCK": {
+                                       EndpointId: getServerID(t, 
"cdn2-test-edge"), ClientSession: TOSession,
+                                       Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
+                               },
+                       },
+                       "TOPOLOGY QUEUE UPDATES": {
+                               "OK when USER OWNS LOCK": {
+                                       ClientSession: opsUserWithLockSession,
+                                       RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"topology": 
{"top-for-ds-req"}}},
+                                       RequestBody: map[string]interface{}{
+                                               "action": "queue",
+                                               "cdnId":  getCDNID(t, "cdn2"),
+                                       },
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+                               },
+                               "FORBIDDEN when ADMIN USER DOESNT OWN LOCK": {
+                                       ClientSession: TOSession,
+                                       RequestOpts:   
client.RequestOptions{QueryParameters: url.Values{"topology": 
{"top-for-ds-req"}}},
+                                       RequestBody: map[string]interface{}{
+                                               "action": "queue",
+                                               "cdnId":  getCDNID(t, "cdn2"),
+                                       },
+                                       Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
+                               },
+                       },
+                       "CACHE GROUP UPDATE": {
+                               "OK when USER OWNS LOCK": {
+                                       EndpointId: GetCacheGroupId(t, 
"cachegroup1"), ClientSession: opsUserWithLockSession,
+                                       RequestBody: map[string]interface{}{
+                                               "name":      "cachegroup1",
+                                               "shortName": "newShortName",
+                                               "typeName":  "EDGE_LOC",
+                                               "typeId":    -1,
+                                       },
+                                       Expectations: 
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+                               },
+                               "FORBIDDEN when ADMIN USER DOESNT OWN LOCK": {
+                                       EndpointId: GetCacheGroupId(t, 
"cachegroup1"), ClientSession: TOSession,
+                                       RequestBody: map[string]interface{}{
+                                               "name":      "cachegroup1",
+                                               "shortName": "newShortName",
+                                               "typeName":  "EDGE_LOC",
+                                               "typeId":    -1,
+                                       },
+                                       Expectations: 
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
+                               },
+                       },
                }
-       }
-       return "", serverID
-}
 
-func getCDNDetailsAndTopologyName(t *testing.T) (int, string, string) {
-       opts := client.NewRequestOptions()
-       topologiesResp, _, err := 
TOSession.GetTopologies(client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't get topologies, err: %v", err)
-       }
-       if len(topologiesResp.Response) == 0 {
-               t.Fatal("no topologies returned")
-       }
-       for _, top := range topologiesResp.Response {
-               for _, node := range top.Nodes {
-                       opts.QueryParameters.Set("name", node.Cachegroup)
-                       cacheGroupResp, _, err := TOSession.GetCacheGroups(opts)
-                       if err != nil {
-                               t.Errorf("error while GETting cachegroups: %v", 
err)
-                       }
-                       if len(cacheGroupResp.Response) != 0 && 
cacheGroupResp.Response[0].ID != nil {
-                               cacheGroupID := *cacheGroupResp.Response[0].ID
-                               opts.QueryParameters.Del("name")
-                               opts.QueryParameters.Set("cachegroup", 
strconv.Itoa(cacheGroupID))
-                               serversResp, _, err := 
TOSession.GetServers(opts)
-                               if err != nil {
-                                       t.Errorf("couldn't get servers: %v", 
err)
+               for method, testCases := range methodTests {
+                       t.Run(method, func(t *testing.T) {
+                               for name, testCase := range testCases {
+
+                                       topology := ""
+                                       cdnLock := tc.CDNLock{}
+                                       cacheGroup := tc.CacheGroupNullable{}
+                                       topQueueUp := 
tc.TopologiesQueueUpdateRequest{}
+
+                                       if 
testCase.RequestOpts.QueryParameters.Has("topology") {
+                                               topology = 
testCase.RequestOpts.QueryParameters.Get("topology")
+                                       }
+
+                                       if testCase.RequestBody != nil {
+                                               if getId, ok := 
testCase.RequestBody["cdnId"]; ok {
+                                                       
testCase.RequestBody["cdnId"] = getId.(func() int)()
+                                                       dat, err := 
json.Marshal(testCase.RequestBody)
+                                                       assert.NoError(t, err, 
"Error occurred when marshalling request body: %v", err)
+                                                       err = 
json.Unmarshal(dat, &topQueueUp)
+                                                       assert.NoError(t, err, 
"Error occurred when unmarshalling request body: %v", err)
+                                               } else if typeName, ok := 
testCase.RequestBody["typeName"]; ok {
+                                                       
testCase.RequestBody["typeId"] = GetTypeId(t, typeName.(string))
+                                                       dat, err := 
json.Marshal(testCase.RequestBody)
+                                                       assert.NoError(t, err, 
"Error occurred when marshalling request body: %v", err)
+                                                       err = 
json.Unmarshal(dat, &cacheGroup)
+                                                       assert.NoError(t, err, 
"Error occurred when unmarshalling request body: %v", err)
+                                               } else {
+                                                       dat, err := 
json.Marshal(testCase.RequestBody)
+                                                       assert.NoError(t, err, 
"Error occurred when marshalling request body: %v", err)
+                                                       err = 
json.Unmarshal(dat, &cdnLock)
+                                                       assert.NoError(t, err, 
"Error occurred when unmarshalling request body: %v", err)
+                                               }
+                                       }
+
+                                       switch method {
+                                       case "GET":
+                                               t.Run(name, func(t *testing.T) {
+                                                       resp, reqInf, err := 
testCase.ClientSession.GetCDNLocks(testCase.RequestOpts)
+                                                       for _, check := range 
testCase.Expectations {
+                                                               check(t, 
reqInf, resp.Response, resp.Alerts, err)
+                                                       }
+                                               })
+                                       case "POST":
+                                               t.Run(name, func(t *testing.T) {
+                                                       resp, reqInf, err := 
testCase.ClientSession.CreateCDNLock(cdnLock, testCase.RequestOpts)
+                                                       for _, check := range 
testCase.Expectations {
+                                                               check(t, 
reqInf, resp.Response, resp.Alerts, err)
+                                                       }
+                                               })
+                                       case "DELETE":
+                                               t.Run(name, func(t *testing.T) {
+                                                       resp, reqInf, err := 
testCase.ClientSession.DeleteCDNLocks(testCase.RequestOpts)
+                                                       for _, check := range 
testCase.Expectations {
+                                                               check(t, 
reqInf, resp.Response, resp.Alerts, err)
+                                                       }
+                                               })
+                                       case "SNAPSHOT":
+                                               {
+                                                       t.Run(name, func(t 
*testing.T) {
+                                                               resp, reqInf, 
err := testCase.ClientSession.SnapshotCRConfig(testCase.RequestOpts)
+                                                               for _, check := 
range testCase.Expectations {
+                                                                       
check(t, reqInf, resp.Response, resp.Alerts, err)
+                                                               }
+                                                       })
+                                               }
+                                       case "SERVERS QUEUE UPDATES":
+                                               {
+                                                       t.Run(name, func(t 
*testing.T) {
+                                                               resp, reqInf, 
err := testCase.ClientSession.SetServerQueueUpdate(testCase.EndpointId(), true, 
testCase.RequestOpts)
+                                                               for _, check := 
range testCase.Expectations {
+                                                                       
check(t, reqInf, resp.Response, resp.Alerts, err)
+                                                               }
+                                                       })
+                                               }
+                                       case "TOPOLOGY QUEUE UPDATES":
+                                               {
+                                                       t.Run(name, func(t 
*testing.T) {
+                                                               resp, reqInf, 
err := testCase.ClientSession.TopologiesQueueUpdate(topology, topQueueUp, 
testCase.RequestOpts)
+                                                               for _, check := 
range testCase.Expectations {
+                                                                       
check(t, reqInf, nil, resp.Alerts, err)
+                                                               }
+                                                       })
+                                               }
+                                       case "CACHE GROUP UPDATE":
+                                               {
+                                                       t.Run(name, func(t 
*testing.T) {
+                                                               resp, reqInf, 
err := testCase.ClientSession.UpdateCacheGroup(testCase.EndpointId(), 
cacheGroup, testCase.RequestOpts)
+                                                               for _, check := 
range testCase.Expectations {
+                                                                       
check(t, reqInf, nil, resp.Alerts, err)
+                                                               }
+                                                       })
+                                               }
+                                       }
                                }
-                               if len(serversResp.Response) != 0 && 
serversResp.Response[0].CDNName != nil && serversResp.Response[0].CDNID != nil {
-                                       return *serversResp.Response[0].CDNID, 
*serversResp.Response[0].CDNName, top.Name
-                               }
-                       }
+                       })
                }
-       }
-       t.Error("couldn't find a valid CDN and associated Topology name")
-       return -1, "", ""
+       })
 }
 
-func CRDCdnLocks(t *testing.T) {
-       cdn := getCDNName(t)
-       // CREATE
-       var cdnLock tc.CDNLock
-       cdnLock.CDN = cdn
-       cdnLock.UserName = TOSession.UserName
-       cdnLock.Message = util.StrPtr("snapping cdn")
-       cdnLock.Soft = util.BoolPtr(true)
-       cdnLockResp, _, err := TOSession.CreateCDNLock(cdnLock, 
client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't create cdn lock: %v", err)
-       }
-       if cdnLockResp.Response.UserName != cdnLock.UserName {
-               t.Errorf("expected username %v, got %v", cdnLock.UserName, 
cdnLockResp.Response.UserName)
-       }
-       if cdnLockResp.Response.CDN != cdnLock.CDN {
-               t.Errorf("expected cdn %v, got %v", cdnLock.CDN, 
cdnLockResp.Response.CDN)
-       }
-       if cdnLockResp.Response.Message == nil {
-               t.Errorf("expected a valid message, but got nothing")
-       }
-       if cdnLockResp.Response.Message != nil && *cdnLockResp.Response.Message 
!= *cdnLock.Message {
-               t.Errorf("expected Message %v, got %v", *cdnLock.Message, 
*cdnLockResp.Response.Message)
-       }
-       if cdnLockResp.Response.Soft == nil {
-               t.Errorf("expected a valid soft/hard setting, but got nothing")
-       }
-       if cdnLockResp.Response.Soft != nil && *cdnLockResp.Response.Soft != 
*cdnLock.Soft {
-               t.Errorf("expected 'Soft' to be %v, got %v", *cdnLock.Soft, 
*cdnLockResp.Response.Soft)
-       }
-
-       // READ
-       cdnLocksReadResp, _, err := 
TOSession.GetCDNLocks(client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("could not get CDN Locks: %v", err)
-       }
-       if len(cdnLocksReadResp.Response) != 1 {
-               t.Fatalf("expected to get back one CDN lock, but got %d 
instead", len(cdnLocksReadResp.Response))
-       }
-       if cdnLocksReadResp.Response[0].UserName != cdnLock.UserName {
-               t.Errorf("expected username %v, got %v", cdnLock.UserName, 
cdnLocksReadResp.Response[0].UserName)
-       }
-       if cdnLocksReadResp.Response[0].CDN != cdnLock.CDN {
-               t.Errorf("expected cdn %v, got %v", cdnLock.CDN, 
cdnLocksReadResp.Response[0].CDN)
-       }
-       if cdnLocksReadResp.Response[0].Message == nil {
-               t.Errorf("expected a valid message, but got nothing")
-       }
-       if cdnLocksReadResp.Response[0].Message != nil && 
*cdnLocksReadResp.Response[0].Message != *cdnLock.Message {
-               t.Errorf("expected Message %v, got %v", *cdnLock.Message, 
*cdnLocksReadResp.Response[0].Message)
-       }
-       if cdnLocksReadResp.Response[0].Soft == nil {
-               t.Errorf("expected a valid soft/hard setting, but got nothing")
-       }
-       if cdnLocksReadResp.Response[0].Soft != nil && 
*cdnLocksReadResp.Response[0].Soft != *cdnLock.Soft {
-               t.Errorf("expected 'Soft' to be %v, got %v", *cdnLock.Soft, 
*cdnLocksReadResp.Response[0].Soft)
-       }
-
-       // DELETE
-       _, reqInf, err := 
TOSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: 
url.Values{"cdn": []string{cdnLock.CDN}}})
-       if err != nil {
-               t.Fatalf("couldn't delete cdn lock, err: %v", err)
+func validateGetResponseFields(expectedResp map[string]interface{}) 
utils.CkReqFunc {
+       return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, 
alerts tc.Alerts, _ error) {
+               cdnLockResp := resp.([]tc.CDNLock)
+               assert.Equal(t, expectedResp["username"], 
cdnLockResp[0].UserName, "Expected username: %v Got: %v", 
expectedResp["username"], cdnLockResp[0].UserName)
+               assert.Equal(t, expectedResp["cdn"], cdnLockResp[0].CDN, 
"Expected CDN: %v Got: %v", expectedResp["cdn"], cdnLockResp[0].CDN)
+               assert.Equal(t, expectedResp["message"], 
*cdnLockResp[0].Message, "Expected Message %v Got: %v", 
expectedResp["message"], *cdnLockResp[0].Message)
+               assert.Equal(t, expectedResp["soft"], *cdnLockResp[0].Soft, 
"Expected 'Soft' to be: %v Got: %v", expectedResp["soft"], *cdnLockResp[0].Soft)
        }
-       if reqInf.StatusCode != http.StatusOK {
-               t.Errorf("expected status code of 200, but got %d instead", 
reqInf.StatusCode)
-       }
-
 }
 
-func AdminCdnLocks(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("[email protected]")
-       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"})
-
-       // Create another new user with operations level privileges
-       user2 := tc.UserV4{
-               Username:             "lock_user2",
-               RegistrationSent:     new(time.Time),
-               LocalPassword:        util.StrPtr("test_pa$$word2"),
-               ConfirmLocalPassword: util.StrPtr("test_pa$$word2"),
-               Role:                 "operations",
-       }
-       user2.Email = util.StrPtr("[email protected]")
-       user2.TenantID = resp.Response[0].ID
-       user2.FullName = util.StrPtr("firstName2 LastName2")
-       _, _, err = TOSession.CreateUser(user2, client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("could not create test user with username: %s, err: 
%v", user2.Username, err)
-       }
-       defer ForceDeleteTestUsersByUsernames(t, []string{"lock_user2"})
-
-       // 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)
-       }
-
-       // Establish another session with the newly created non admin level user
-       userSession2, _, err := client.LoginWithAgent(Config.TrafficOps.URL, 
user2.Username, *user2.LocalPassword, true, "to-api-v4-client-tests", false, 
toReqTimeout)
-       if err != nil {
-               t.Fatalf("could not login with user lock_user1: %v", err)
-       }
-
-       cdn := getCDNName(t)
-       // Create a lock for this user
-       _, _, err = userSession.CreateCDNLock(tc.CDNLock{
-               CDN:     cdn,
-               Message: util.StrPtr("test lock"),
-               Soft:    util.BoolPtr(true),
-       }, client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't create cdn lock: %v", err)
-       }
-
-       // Non admin user trying to delete another user's lock -> this should 
fail
-       _, reqInf, err := 
userSession2.DeleteCDNLocks(client.RequestOptions{QueryParameters: 
url.Values{"cdn": []string{cdn}}})
-       if err == nil {
-               t.Fatalf("expected error when a non admin user tries to delete 
another user's lock, but got nothing")
-       }
-       if reqInf.StatusCode != http.StatusForbidden {
-               t.Fatalf("expected a 403 status code, but got %d instead", 
reqInf.StatusCode)
-       }
-
-       // Now try to delete another user's lock by hitting the admin DELETE 
endpoint for cdn_locks -> this should pass
-       _, reqInf, err = 
TOSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: 
url.Values{"cdn": []string{cdn}}})
-       if err != nil {
-               t.Fatalf("expected no error while deleting other user's lock 
using admin endpoint, but got %v", err)
-       }
-       if reqInf.StatusCode != http.StatusOK {
-               t.Fatalf("expected a 200 status code, but got %d instead", 
reqInf.StatusCode)
+func validateCreateResponseFields(expectedResp map[string]interface{}) 
utils.CkReqFunc {
+       return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, 
alerts tc.Alerts, _ error) {
+               cdnLockResp := resp.(tc.CDNLock)
+               assert.Equal(t, expectedResp["username"], cdnLockResp.UserName, 
"Expected username: %v Got: %v", expectedResp["username"], cdnLockResp.UserName)
+               assert.Equal(t, expectedResp["cdn"], cdnLockResp.CDN, "Expected 
CDN: %v Got: %v", expectedResp["cdn"], cdnLockResp.CDN)
+               assert.Equal(t, expectedResp["message"], *cdnLockResp.Message, 
"Expected Message %v Got: %v", expectedResp["message"], *cdnLockResp.Message)
+               assert.Equal(t, expectedResp["soft"], *cdnLockResp.Soft, 
"Expected 'Soft' to be: %v Got: %v", expectedResp["soft"], *cdnLockResp.Soft)
        }
 }
 
-func SnapshotWithLock(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("[email protected]")
-       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)
-       }
-
-       cdn := getCDNName(t)
-
-       // Currently, no user has a lock on the "bar" CDN, so when 
"lock_user1", which does not have the lock on CDN "bar", tries to snap it, this 
should pass
-       opts := client.NewRequestOptions()
-       opts.QueryParameters.Set("cdn", cdn)
-       _, _, err = userSession.SnapshotCRConfig(opts)
-       if err != nil {
-               t.Errorf("expected no error while snapping cdn %s by user %s, 
but got %v", cdn, user1.Username, err)
-       }
-
-       // Create a lock for this user
-       _, _, err = userSession.CreateCDNLock(tc.CDNLock{
-               CDN:     cdn,
-               Message: util.StrPtr("test lock"),
-               Soft:    util.BoolPtr(true),
-       }, client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't create cdn lock: %v", err)
-       }
-
-       // "lock_user1", which has the lock on CDN "bar", tries to snap it -> 
this should pass
-       _, _, err = userSession.SnapshotCRConfig(opts)
-       if err != nil {
-               t.Errorf("expected no error while snapping cdn %s by user %s, 
but got %v", cdn, user1.Username, err)
-       }
-
-       // Admin user, which doesn't have the lock on the CDN "bar", is trying 
to snap it -> this should fail
-       _, reqInf, err := TOSession.SnapshotCRConfig(opts)
-       if err == nil {
-               t.Errorf("expected error while snapping cdn %s by user admin, 
but got nothing", cdn)
-       }
-       if reqInf.StatusCode != http.StatusForbidden {
-               t.Errorf("expected a 403 status code, but got %d instead", 
reqInf.StatusCode)
-       }
-
-       // Delete the lock
-       _, _, err = 
userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: 
url.Values{"cdn": []string{cdn}}})
-       if err != nil {
-               t.Errorf("expected no error while deleting other user's lock 
using admin endpoint, but got %v", err)
+func getCDNID(t *testing.T, cdnName string) func() int {
+       return func() int {
+               opts := client.NewRequestOptions()
+               opts.QueryParameters.Set("name", cdnName)
+               cdnsResp, _, err := TOSession.GetCDNs(opts)
+               assert.NoError(t, err, "Get CDNs Request failed with error:", 
err)
+               assert.Equal(t, 1, len(cdnsResp.Response), "Expected response 
object length 1, but got %d", len(cdnsResp.Response))
+               assert.NotNil(t, cdnsResp.Response[0].ID, "Expected id to not 
be nil")
+               return cdnsResp.Response[0].ID
        }
 }
 
-func QueueUpdatesWithLock(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("[email protected]")
-       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)
-       }
-
-       cdn, serverID := getCDNNameAndServerID(t)
-       if serverID == -1 {
-               t.Fatalf("Could not get any valid servers to queue updates on")
-       }
-
-       // Currently, no user has a lock on the "bar" CDN, so when 
"lock_user1", which does not have the lock on CDN "bar", tries to queue updates 
on a server in the same CDN, this should pass
-       _, _, err = userSession.SetServerQueueUpdate(serverID, true, 
client.RequestOptions{})
-       if err != nil {
-               t.Errorf("expected no error while queueing updates for a server 
in cdn %s by user %s, but got %v", cdn, user1.Username, err)
-       }
-
-       // Create a lock for this user
-       _, _, err = userSession.CreateCDNLock(tc.CDNLock{
-               CDN:     cdn,
-               Message: util.StrPtr("test lock"),
-               Soft:    util.BoolPtr(true),
-       }, client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't create cdn lock: %v", err)
-       }
-
-       // "lock_user1", which has the lock on CDN "bar", tries to queue 
updates on a server in it -> this should pass
-       _, _, err = userSession.SetServerQueueUpdate(serverID, true, 
client.RequestOptions{})
-       if err != nil {
-               t.Errorf("expected no error while queueing updates for a server 
in cdn %s by user %s, but got %v", cdn, user1.Username, err)
-       }
-
-       // Admin user, which doesn't have the lock on the CDN "bar", is trying 
to queue updates on a server in it -> this should fail
-       _, reqInf, err := TOSession.SetServerQueueUpdate(serverID, true, 
client.RequestOptions{})
-       if err == nil {
-               t.Errorf("expected error while queueing updates on a server in 
cdn %s by user admin, but got nothing", cdn)
-       }
-       if reqInf.StatusCode != http.StatusForbidden {
-               t.Fatalf("expected a 403 status code, but got %d instead", 
reqInf.StatusCode)
-       }
-
-       // Delete the lock
-       _, _, err = 
userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: 
url.Values{"cdn": []string{cdn}}})
-       if err != nil {
-               t.Fatalf("expected no error while deleting other user's lock 
using admin endpoint, but got %v", err)
+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.NoError(t, err, "Get Servers Request failed with 
error:", err)
+               assert.Equal(t, 1, len(serversResp.Response), "Expected 
response object length 1, but got %d", len(serversResp.Response))
+               assert.NotNil(t, serversResp.Response[0].ID, "Expected id to 
not be nil")
+               return *serversResp.Response[0].ID
        }
 }
 
-func QueueUpdatesFromTopologiesWithLock(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("[email protected]")
-       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)
-       }
-
-       cdnID, cdnName, topology := getCDNDetailsAndTopologyName(t)
-       if topology == "" || cdnName == "" || cdnID == -1 {
-               t.Fatalf("Could not get any valid topologies/ cdns to queue 
updates on")
-       }
-
-       // Currently, no user has a lock on the "bar" CDN, so when 
"lock_user1", which does not have the lock on CDN "bar", tries to queue updates 
on a topology in the same CDN, this should pass
-       _, _, err = userSession.TopologiesQueueUpdate(topology, 
tc.TopologiesQueueUpdateRequest{Action: "queue", CDNID: int64(cdnID)}, 
client.RequestOptions{})
-       if err != nil {
-               t.Errorf("expected no error while queueing updates for a 
topology server in cdn %s by user %s, but got %v", cdnName, user1.Username, err)
-       }
-
-       // Create a lock for this user
-       _, _, err = userSession.CreateCDNLock(tc.CDNLock{
-               CDN:     cdnName,
-               Message: util.StrPtr("test lock"),
-               Soft:    util.BoolPtr(true),
-       }, client.RequestOptions{})
-       if err != nil {
-               t.Fatalf("couldn't create cdn lock: %v", err)
-       }
-
-       // "lock_user1", which has the lock on CDN "bar", tries to queue 
updates on a topology in it -> this should pass
-       _, _, err = userSession.TopologiesQueueUpdate(topology, 
tc.TopologiesQueueUpdateRequest{Action: "queue", CDNID: int64(cdnID)}, 
client.RequestOptions{})
-       if err != nil {
-               t.Errorf("expected no error while queueing updates for a 
topology server in cdn %s by user %s, but got %v", cdnName, user1.Username, err)
-       }
-
-       // Admin user, which doesn't have the lock on the CDN "bar", is trying 
to queue updates on a topology in it -> this should fail
-       _, reqInf, err := TOSession.TopologiesQueueUpdate(topology, 
tc.TopologiesQueueUpdateRequest{Action: "queue", CDNID: int64(cdnID)}, 
client.RequestOptions{})
-       if err == nil {
-               t.Errorf("expected error while queueing updates on topology 
servers on cdn %s by user admin, but got nothing", cdnName)
-       }
-       if reqInf.StatusCode != http.StatusForbidden {
-               t.Fatalf("expected a 403 status code, but got %d instead", 
reqInf.StatusCode)
+func CreateTestCDNLocks(t *testing.T) {
+       for _, cl := range testData.CDNLocks {
+               ClientSession := TOSession
+               if cl.UserName != "" {
+                       for _, user := range testData.Users {
+                               if user.Username == cl.UserName {
+                                       ClientSession = 
utils.CreateV4Session(t, Config.TrafficOps.URL, user.Username, 
*user.LocalPassword, Config.Default.Session.TimeoutInSecs)
+                               }
+                       }
+               }
+               resp, _, err := ClientSession.CreateCDNLock(cl, 
client.RequestOptions{})
+               assert.NoError(t, err, "Could not create CDN Lock: %v - alerts: 
%+v", err, resp.Alerts)
        }
+}
 
-       // Delete the lock
-       _, _, err = 
userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: 
url.Values{"cdn": []string{cdnName}}})
-       if err != nil {
-               t.Fatalf("expected no error while deleting lock, but got %v", 
err)
+func DeleteTestCDNLocks(t *testing.T) {
+       opts := client.NewRequestOptions()
+       cdnlocks, _, err := TOSession.GetCDNLocks(opts)
+       assert.NoError(t, err, "Error retrieving CDN Locks for deletion: %v - 
alerts: %+v", err, cdnlocks.Alerts)
+       assert.GreaterOrEqual(t, len(cdnlocks.Response), 1, "Expected at least 
one CDN Lock for deletion")
+       for _, cl := range cdnlocks.Response {
+               opts.QueryParameters.Set("cdn", cl.CDN)
+               resp, _, err := TOSession.DeleteCDNLocks(opts)
+               assert.NoError(t, err, "Could not delete CDN Lock: %v - alerts: 
%+v", err, resp.Alerts)
+               // Retrieve the CDN Lock to see if it got deleted
+               cdnlock, _, err := TOSession.GetCDNLocks(opts)
+               assert.NoError(t, err, "Error deleting CDN Lock for '%s' : %v - 
alerts: %+v", cl.CDN, err, cdnlock.Alerts)
+               assert.Equal(t, 0, len(cdnlock.Response), "Expected CDN Lock 
for '%s' to be deleted", cl.CDN)
        }
 }
diff --git a/traffic_ops/testing/api/v4/tc-fixtures.json 
b/traffic_ops/testing/api/v4/tc-fixtures.json
index 4ae1fd0..0aa870d 100644
--- a/traffic_ops/testing/api/v4/tc-fixtures.json
+++ b/traffic_ops/testing/api/v4/tc-fixtures.json
@@ -283,6 +283,26 @@
             "name": "bar"
         }
     ],
+    "cdnlocks": [
+        {
+            "userName": "opslockuser",
+            "cdn": "cdn1",
+            "message": "test lock",
+            "soft": true
+        },
+        {
+            "userName": "opslockuser",
+            "cdn": "cdn2",
+            "message": "test lock for updates",
+            "soft": false
+        },
+        {
+            "userName": "opslockuser",
+            "cdn": "cdn4",
+            "message": "test lock",
+            "soft": true
+        }
+    ],
     "deliveryServiceRequestComments": [
         {
             "value": "this is comment one"
@@ -5641,6 +5661,27 @@
             "tenant": "root",
             "uid": 0,
             "username": "steering"
+        },
+        {
+            "addressLine1": "address of ops user with lock",
+            "addressLine2": "place",
+            "city": "somewhere",
+            "company": "else",
+            "country": "US",
+            "email": "[email protected]",
+            "fullName": "Ops with Lock User",
+            "gid": 0,
+            "localPasswd": "pa$$word",
+            "confirmLocalPasswd": "pa$$word",
+            "newUser": false,
+            "phoneNumber": "",
+            "postalCode": "",
+            "publicSshKey": "",
+            "role": "operations",
+            "stateOrProvince": "",
+            "tenant": "root",
+            "uid": 0,
+            "username": "opslockuser"
         }
     ],
     "steeringTargets": [
diff --git a/traffic_ops/testing/api/v4/traffic_control_test.go 
b/traffic_ops/testing/api/v4/traffic_control_test.go
index e1d68ec..cbf6a82 100644
--- a/traffic_ops/testing/api/v4/traffic_control_test.go
+++ b/traffic_ops/testing/api/v4/traffic_control_test.go
@@ -23,6 +23,7 @@ import (
 type TrafficControl struct {
        ASNs                                              []tc.ASN              
                  `json:"asns"`
        CDNs                                              []tc.CDN              
                  `json:"cdns"`
+       CDNLocks                                          []tc.CDNLock          
                  `json:"cdnlocks"`
        CacheGroups                                       
[]tc.CacheGroupNullable                 `json:"cachegroups"`
        Capabilities                                      []tc.Capability       
                  `json:"capability"`
        Coordinates                                       []tc.Coordinate       
                  `json:"coordinates"`
diff --git a/traffic_ops/testing/api/v4/withobjs_test.go 
b/traffic_ops/testing/api/v4/withobjs_test.go
index 18bc970..c1114b0 100644
--- a/traffic_ops/testing/api/v4/withobjs_test.go
+++ b/traffic_ops/testing/api/v4/withobjs_test.go
@@ -45,6 +45,7 @@ const (
        CacheGroups
        CacheGroupsDeliveryServices
        CDNs
+       CDNLocks
        CDNFederations
        CDNNotifications
        Coordinates
@@ -90,6 +91,7 @@ var withFuncs = map[TCObj]TCObjFuncs{
        CacheGroups:                           {CreateTestCacheGroups, 
DeleteTestCacheGroups},
        CacheGroupsDeliveryServices:           
{CreateTestCachegroupsDeliveryServices, DeleteTestCachegroupsDeliveryServices},
        CDNs:                                  {CreateTestCDNs, DeleteTestCDNs},
+       CDNLocks:                              {CreateTestCDNLocks, 
DeleteTestCDNLocks},
        CDNNotifications:                      {CreateTestCDNNotifications, 
DeleteTestCDNNotifications},
        CDNFederations:                        {CreateTestCDNFederations, 
DeleteTestCDNFederations},
        Coordinates:                           {CreateTestCoordinates, 
DeleteTestCoordinates},

Reply via email to