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},