This is an automated email from the ASF dual-hosted git repository.
srijeet0406 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 2e4a2492ab Refactor Tenants Tests (#6946)
2e4a2492ab is described below
commit 2e4a2492ab97b3fdbb084415f13e31a889296f74
Author: Eric Holguin <[email protected]>
AuthorDate: Fri Jul 15 12:52:41 2022 -0600
Refactor Tenants Tests (#6946)
* initial refactor
* Tenants test refactor
* add tenant users for delivery service tenancy tests
* Moved tenancy tests to delivery service test file
---
.../api/v3/deliveryservice_requests_test.go | 4 +-
.../testing/api/v3/deliveryservices_test.go | 45 +-
traffic_ops/testing/api/v3/tc-fixtures.json | 42 ++
traffic_ops/testing/api/v3/tenants_test.go | 498 +++++---------
.../api/v4/deliveryservice_requests_test.go | 6 +-
.../testing/api/v4/deliveryservices_test.go | 45 +-
traffic_ops/testing/api/v4/tc-fixtures.json | 42 ++
traffic_ops/testing/api/v4/tenants_test.go | 761 ++++++++-------------
8 files changed, 606 insertions(+), 837 deletions(-)
diff --git a/traffic_ops/testing/api/v3/deliveryservice_requests_test.go
b/traffic_ops/testing/api/v3/deliveryservice_requests_test.go
index df323a44a4..c60813840b 100644
--- a/traffic_ops/testing/api/v3/deliveryservice_requests_test.go
+++ b/traffic_ops/testing/api/v3/deliveryservice_requests_test.go
@@ -59,7 +59,7 @@ func TestDeliveryServiceRequests(t *testing.T) {
"changeType": "create",
"deliveryService":
generateDeliveryService(t, map[string]interface{}{
"displayName": "NEW
DISPLAY NAME",
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"xmlId":
"test-ds1",
}),
"status": "draft",
@@ -72,7 +72,7 @@ func TestDeliveryServiceRequests(t *testing.T) {
RequestBody: map[string]interface{}{
"changeType": "create",
"deliveryService":
generateDeliveryService(t, map[string]interface{}{
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"xmlId": "test-ds1",
}),
"status": "submitted",
diff --git a/traffic_ops/testing/api/v3/deliveryservices_test.go
b/traffic_ops/testing/api/v3/deliveryservices_test.go
index c1a436b37f..82ce800585 100644
--- a/traffic_ops/testing/api/v3/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v3/deliveryservices_test.go
@@ -37,6 +37,9 @@ func TestDeliveryServices(t *testing.T) {
currentTime := time.Now().UTC().Add(-15 * time.Second)
currentTimeRFC := currentTime.Format(time.RFC1123)
+ tenant1UserSession := utils.CreateV3Session(t,
Config.TrafficOps.URL, "tenant1user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
+ tenant2UserSession := utils.CreateV3Session(t,
Config.TrafficOps.URL, "tenant2user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
+ tenant3UserSession := utils.CreateV3Session(t,
Config.TrafficOps.URL, "tenant3user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
tenant4UserSession := utils.CreateV3Session(t,
Config.TrafficOps.URL, "tenant4user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
methodTests := utils.V3TestCase{
@@ -62,9 +65,30 @@ func TestDeliveryServices(t *testing.T) {
ClientSession: TOSession,
RequestParams: url.Values{"accessibleTo": {"1"}},
Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseLengthGreaterOrEqual(1)),
},
- "EMPTY RESPONSE when TENANT attempts reading DS
OUTSIDE TENANCY": {
- ClientSession: tenant4UserSession,
RequestParams: url.Values{"xmlId": {"ds3"}},
- Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ "OK when PARENT TENANT reads DS of INACTIVE
CHILD TENANT": {
+ ClientSession: tenant1UserSession,
+ RequestParams: url.Values{"xmlId":
{"ds2"}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(1)),
+ },
+ "EMPTY RESPONSE when DS BELONGS to TENANT but
PARENT TENANT is INACTIVE": {
+ ClientSession: tenant3UserSession,
+ RequestParams: url.Values{"xmlId":
{"ds3"}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ },
+ "EMPTY RESPONSE when INACTIVE TENANT reads DS
of SAME TENANCY": {
+ ClientSession: tenant2UserSession,
+ RequestParams: url.Values{"xmlId":
{"ds2"}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ },
+ "EMPTY RESPONSE when TENANT reads DS OUTSIDE
TENANCY": {
+ ClientSession: tenant4UserSession,
+ RequestParams: url.Values{"xmlId":
{"ds3"}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ },
+ "EMPTY RESPONSE when CHILD TENANT reads DS of
PARENT TENANT": {
+ ClientSession: tenant3UserSession,
+ RequestParams: url.Values{"xmlId":
{"ds2"}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
},
},
"POST": {
@@ -92,7 +116,7 @@ func TestDeliveryServices(t *testing.T) {
"BAD REQUEST when creating DS with TENANCY NOT
THE SAME AS CURRENT TENANT": {
ClientSession: tenant4UserSession,
RequestBody: generateDeliveryService(t,
map[string]interface{}{
- "tenantId": GetTenantId(t,
"tenant3"),
+ "tenantId": GetTenantID(t,
"tenant3")(),
"xmlId": "test-tenancy",
}),
Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden)),
@@ -124,7 +148,7 @@ func TestDeliveryServices(t *testing.T) {
"maxOriginConnections":
500,
"routingName":
"cdn",
"signingAlgorithm":
"uri_signing",
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"trRequestHeaders":
"X-ooF\nX-raB",
"trResponseHeaders":
"Access-Control-Max-Age: 600\nContent-Type: text/html; charset=utf-8",
"xmlId":
"ds-test-minor-versions",
@@ -289,7 +313,7 @@ func TestDeliveryServices(t *testing.T) {
if val, ok :=
testCase.RequestParams["accessibleTo"]; ok {
if _, err :=
strconv.Atoi(val[0]); err != nil {
-
testCase.RequestParams.Set("accessibleTo", strconv.Itoa(GetTenantId(t, val[0])))
+
testCase.RequestParams.Set("accessibleTo", strconv.Itoa(GetTenantID(t,
val[0])()))
}
}
if val, ok :=
testCase.RequestParams["cdn"]; ok {
@@ -309,7 +333,7 @@ func TestDeliveryServices(t *testing.T) {
}
if val, ok :=
testCase.RequestParams["tenant"]; ok {
if _, err :=
strconv.Atoi(val[0]); err != nil {
-
testCase.RequestParams.Set("tenant", strconv.Itoa(GetTenantId(t, val[0])))
+
testCase.RequestParams.Set("tenant", strconv.Itoa(GetTenantID(t, val[0])()))
}
}
@@ -443,13 +467,6 @@ func GetProfileId(t *testing.T, profileName string) int {
return resp[0].ID
}
-func GetTenantId(t *testing.T, tenantName string) int {
- resp, _, err := TOSession.TenantByNameWithHdr(tenantName, http.Header{})
- assert.RequireNoError(t, err, "Get Tenants Request failed with error:
%v", err)
- assert.RequireNotNil(t, resp, "Expected resp to not be nil")
- return resp.ID
-}
-
func generateDeliveryService(t *testing.T, requestDS map[string]interface{})
map[string]interface{} {
// map for the most basic HTTP Delivery Service a user can create
genericHTTPDS := map[string]interface{}{
diff --git a/traffic_ops/testing/api/v3/tc-fixtures.json
b/traffic_ops/testing/api/v3/tc-fixtures.json
index 8ec7462391..926c7fe803 100644
--- a/traffic_ops/testing/api/v3/tc-fixtures.json
+++ b/traffic_ops/testing/api/v3/tc-fixtures.json
@@ -5376,6 +5376,48 @@
"uid": 0,
"username": "readonlyuser"
},
+ {
+ "addressLine1": "address of tenant1user",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "[email protected]",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": 4,
+ "stateOrProvince": "LA",
+ "tenant": "tenant1",
+ "uid": 0,
+ "username": "tenant1user"
+ },
+ {
+ "addressLine1": "address of tenant2user",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "[email protected]",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": 4,
+ "stateOrProvince": "LA",
+ "tenant": "tenant2",
+ "uid": 0,
+ "username": "tenant2user"
+ },
{
"addressLine1": "address of admin",
"addressLine2": "",
diff --git a/traffic_ops/testing/api/v3/tenants_test.go
b/traffic_ops/testing/api/v3/tenants_test.go
index e0560f6cb8..7e76399c5b 100644
--- a/traffic_ops/testing/api/v3/tenants_test.go
+++ b/traffic_ops/testing/api/v3/tenants_test.go
@@ -16,352 +16,232 @@ package v3
*/
import (
+ "encoding/json"
"net/http"
"sort"
"strconv"
- "strings"
"testing"
"time"
"github.com/apache/trafficcontrol/lib/go-rfc"
"github.com/apache/trafficcontrol/lib/go-tc"
- "github.com/apache/trafficcontrol/traffic_ops/v3-client"
+ "github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+ "github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+ "github.com/apache/trafficcontrol/traffic_ops/toclientlib"
)
func TestTenants(t *testing.T) {
WithObjs(t, []TCObj{Tenants}, func() {
- SortTestTenants(t)
- GetTestTenants(t)
- UpdateTestTenants(t)
- UpdateTestRootTenant(t)
- currentTime := time.Now().UTC().Add(-5 * time.Second)
- time := currentTime.Format(time.RFC1123)
- var header http.Header
- header = make(map[string][]string)
- header.Set(rfc.IfUnmodifiedSince, time)
- UpdateTestTenantsWithHeaders(t, header)
- header = make(map[string][]string)
- etag := rfc.ETag(currentTime)
- header.Set(rfc.IfMatch, etag)
- UpdateTestTenantsWithHeaders(t, header)
- })
-}
-
-func UpdateTestTenantsWithHeaders(t *testing.T, header http.Header) {
- // Retrieve the Tenant by name so we can get the id for the Update
- name := "tenant2"
- parentName := "tenant1"
- modTenant, _, err := TOSession.TenantByNameWithHdr(name, header)
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %s - %v", name, err)
- }
-
- newParent, _, err := TOSession.TenantByNameWithHdr(parentName, header)
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %s - %v", parentName, err)
- }
- if newParent != nil {
- modTenant.ParentID = newParent.ID
- _, reqInf, err :=
TOSession.UpdateTenantWithHdr(strconv.Itoa(modTenant.ID), modTenant, header)
- if err == nil {
- t.Fatalf("expected a precondition failed error, got
none")
+ currentTime := time.Now().UTC().Add(-15 * time.Second)
+ currentTimeRFC := currentTime.Format(time.RFC1123)
+ tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+ methodTests := utils.V3TestCase{
+ "GET": {
+ "NOT MODIFIED when NO CHANGES made": {
+ ClientSession: TOSession,
+ RequestHeaders:
http.Header{rfc.IfModifiedSince: {tomorrow}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+ },
+ "OK when VALID request": {
+ ClientSession: TOSession,
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+
utils.ResponseLengthGreaterOrEqual(1), validateTenantSort()),
+ },
+ },
+ "POST": {
+ "NO ERROR when VALID request": {
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": true,
+ "name": "tenant5",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ Expectations:
utils.CkRequest(utils.NoError(),
validateTenantCreateUpdateFields(map[string]interface{}{"Name": "tenant5"})),
+ },
+ },
+ "PUT": {
+ "OK when VALID request": {
+ EndpointId: GetTenantID(t,
"tenant4"),
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "newname",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+
validateTenantCreateUpdateFields(map[string]interface{}{"Name": "newname",
"Active": false})),
+ },
+ "BAD REQUEST when ROOT TENANT": {
+ EndpointId: GetTenantID(t, "root"),
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "tenant1",
+ "parentName": "root",
+ },
+ Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+ },
+ "PRECONDITION FAILED when updating with IMS &
IUS Headers": {
+ EndpointId: GetTenantID(t,
"tenant2"),
+ ClientSession: TOSession,
+ RequestHeaders:
http.Header{rfc.IfUnmodifiedSince: {currentTimeRFC}},
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "tenant2",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ Expectations:
utils.CkRequest(utils.HasError(),
utils.HasStatus(http.StatusPreconditionFailed)),
+ },
+ "PRECONDITION FAILED when updating with IFMATCH
ETAG Header": {
+ EndpointId: GetTenantID(t,
"tenant2"),
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "tenant2",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ RequestHeaders:
http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}},
+ Expectations:
utils.CkRequest(utils.HasError(),
utils.HasStatus(http.StatusPreconditionFailed)),
+ },
+ },
+ "DELETE": {
+ "ERROR when TENANT HAS CHILDREN": {
+ EndpointId: GetTenantID(t,
"tenant1"),
+ ClientSession: TOSession,
+ Expectations:
utils.CkRequest(utils.HasError()),
+ },
+ },
}
- if reqInf.StatusCode != http.StatusPreconditionFailed {
- t.Errorf("expected a status 412 Precondition Failed,
but got %d", reqInf.StatusCode)
- }
- }
-}
-
-func TestTenantsActive(t *testing.T) {
- WithObjs(t, []TCObj{CDNs, Types, Tenants, CacheGroups, Parameters,
Profiles, Statuses, Divisions, Regions, PhysLocations, Servers, Topologies,
DeliveryServices, Users}, func() {
- UpdateTestTenantsActive(t)
- })
-}
-func CreateTestTenants(t *testing.T) {
- for _, ten := range testData.Tenants {
- resp, err := TOSession.CreateTenant(&ten)
-
- if err != nil {
- t.Errorf("could not CREATE tenant %s: %v", ten.Name,
err)
- } else if resp == nil {
- t.Errorf("nil response")
- } else if resp.Response.Name != ten.Name {
- t.Errorf("expected tenant '%s'; got '%s'", ten.Name,
resp.Response.Name)
+ for method, testCases := range methodTests {
+ t.Run(method, func(t *testing.T) {
+ for name, testCase := range testCases {
+ tenant := tc.Tenant{}
+
+ if testCase.RequestBody != nil {
+ dat, err :=
json.Marshal(testCase.RequestBody)
+ assert.NoError(t, err, "Error
occurred when marshalling request body: %v", err)
+ err = json.Unmarshal(dat,
&tenant)
+ assert.NoError(t, err, "Error
occurred when unmarshalling request body: %v", err)
+ }
+
+ switch method {
+ case "GET", "GET AFTER CHANGES":
+ t.Run(name, func(t *testing.T) {
+ resp, reqInf, err :=
testCase.ClientSession.TenantsWithHdr(testCase.RequestHeaders)
+ for _, check := range
testCase.Expectations {
+ check(t,
reqInf, resp, tc.Alerts{}, err)
+ }
+ })
+ case "POST":
+ t.Run(name, func(t *testing.T) {
+ resp, err :=
testCase.ClientSession.CreateTenant(&tenant)
+ for _, check := range
testCase.Expectations {
+ if resp != nil {
+
check(t, toclientlib.ReqInf{}, resp.Response, resp.Alerts, err)
+ }
+ }
+ })
+ case "PUT":
+ t.Run(name, func(t *testing.T) {
+ resp, reqInf, err :=
testCase.ClientSession.UpdateTenantWithHdr(strconv.Itoa(testCase.EndpointId()),
&tenant, testCase.RequestHeaders)
+ for _, check := range
testCase.Expectations {
+ if resp != nil {
+
check(t, reqInf, resp.Response, resp.Alerts, err)
+ }
+ }
+ })
+ case "DELETE":
+ t.Run(name, func(t *testing.T) {
+ _, err :=
testCase.ClientSession.DeleteTenant(strconv.Itoa(testCase.EndpointId()))
+ for _, check := range
testCase.Expectations {
+ check(t,
toclientlib.ReqInf{}, nil, tc.Alerts{}, err)
+ }
+ })
+ }
+ }
+ })
}
- }
+ })
}
-func GetTestTenants(t *testing.T) {
- resp, _, err := TOSession.Tenants()
- if err != nil {
- t.Errorf("cannot GET all tenants: %v - %v", err, resp)
- return
- }
- foundTenants := make(map[string]tc.Tenant, len(resp))
- for _, ten := range resp {
- foundTenants[ten.Name] = ten
- }
-
- // expect root and badTenant (defined in todb.go) + all defined in
testData.Tenants
- if len(resp) != 2+len(testData.Tenants) {
- t.Errorf("expected %d tenants, got %d",
2+len(testData.Tenants), len(resp))
- }
-
- for _, ten := range testData.Tenants {
- if ft, ok := foundTenants[ten.Name]; ok {
- if ft.ParentName != ten.ParentName {
- t.Errorf("tenant %s: expected parent %s, got
%s", ten.Name, ten.ParentName, ft.ParentName)
+func validateTenantFields(expectedResp map[string]interface{}) utils.CkReqFunc
{
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _
tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ tenantResp := resp.([]tc.Tenant)
+ for field, expected := range expectedResp {
+ for _, tenant := range tenantResp {
+ switch field {
+ case "Active":
+ assert.Equal(t, expected,
tenant.Active, "Expected Active to be %v, but got %b", expected, tenant.Active)
+ case "Name":
+ assert.Equal(t, expected, tenant.Name,
"Expected Name to be %v, but got %s", expected, tenant.Name)
+ case "ParentName":
+ assert.Equal(t, expected,
tenant.ParentName, "Expected ParentName to be %v, but got %s", expected,
tenant.ParentName)
+ default:
+ t.Errorf("Expected field: %v, does not
exist in response", field)
+ }
}
- } else {
- t.Errorf("expected tenant %s: not found", ten.Name)
}
}
}
-func SortTestTenants(t *testing.T) {
- var header http.Header
- var sortedList []string
- resp, _, err := TOSession.TenantsWithHdr(header)
- if err != nil {
- t.Fatalf("Expected no error, but got %v", err.Error())
- }
- for i, _ := range resp {
- sortedList = append(sortedList, resp[i].Name)
- }
-
- res := sort.SliceIsSorted(sortedList, func(p, q int) bool {
- return sortedList[p] < sortedList[q]
- })
- if res != true {
- t.Errorf("list is not sorted by their names: %v", sortedList)
+func validateTenantCreateUpdateFields(expectedResp map[string]interface{})
utils.CkReqFunc {
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _
tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ tenantResp := resp.(tc.Tenant)
+ tenants := []tc.Tenant{tenantResp}
+ validateTenantFields(expectedResp)(t, toclientlib.ReqInf{},
tenants, tc.Alerts{}, nil)
}
}
-func UpdateTestTenants(t *testing.T) {
-
- // Retrieve the Tenant by name so we can get the id for the Update
- name := "tenant2"
- parentName := "tenant1"
- modTenant, _, err := TOSession.TenantByName(name)
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %s - %v", name, err)
- }
-
- newParent, _, err := TOSession.TenantByName(parentName)
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %s - %v", parentName, err)
- }
- modTenant.ParentID = newParent.ID
-
- _, err = TOSession.UpdateTenant(strconv.Itoa(modTenant.ID), modTenant)
- if err != nil {
- t.Errorf("cannot UPDATE Tenant by id: %v", err)
- }
-
- // Retrieve the Tenant to check Tenant parent name got updated
- respTenant, _, err := TOSession.Tenant(strconv.Itoa(modTenant.ID))
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %v - %v", name, err)
- }
- if respTenant.ParentName != parentName {
- t.Errorf("results do not match actual: %s, expected: %s",
respTenant.ParentName, parentName)
- }
-
-}
-
-func UpdateTestRootTenant(t *testing.T) {
- // Retrieve the Tenant by name so we can get the id for the Update
- name := "root"
- modTenant, _, err := TOSession.TenantByNameWithHdr(name, nil)
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %s - %v", name, err)
- }
-
- modTenant.Active = false
- modTenant.ParentID = modTenant.ID
- _, reqInf, err :=
TOSession.UpdateTenantWithHdr(strconv.Itoa(modTenant.ID), modTenant, nil)
- if err == nil {
- t.Fatalf("expected an error when trying to update the 'root'
tenant, but got nothing")
- }
- if reqInf.StatusCode != http.StatusBadRequest {
- t.Errorf("expected a status 400 Bad Request, but got %d",
reqInf.StatusCode)
- }
-}
-
-func DeleteTestTenants(t *testing.T) {
-
- t1 := "tenant1"
- tenant1, _, err := TOSession.TenantByName(t1)
-
- if err != nil {
- t.Errorf("cannot GET Tenant by name: %v - %v", t1, err)
- }
- expectedChildDeleteErrMsg := `Tenant '` + strconv.Itoa(tenant1.ID) + `'
has child tenants. Please update these child tenants and retry.`
- if _, err := TOSession.DeleteTenant(strconv.Itoa(tenant1.ID)); err ==
nil {
- t.Fatalf("%s has child tenants -- should not be able to
delete", t1)
- } else if !strings.Contains(err.Error(), expectedChildDeleteErrMsg) {
- t.Errorf("expected error: %s; got %s",
expectedChildDeleteErrMsg, err.Error())
- }
-
- deletedTenants := map[string]struct{}{}
- for {
- initLenDeleted := len(deletedTenants)
- for _, tn := range testData.Tenants {
- if _, ok := deletedTenants[tn.Name]; ok {
- continue
- }
-
- hasParent := false
- for _, otherTenant := range testData.Tenants {
- if _, ok := deletedTenants[otherTenant.Name];
ok {
- continue
- }
- if otherTenant.ParentName == tn.Name {
- hasParent = true
- break
- }
- }
- if hasParent {
- continue
- }
-
- toTenant, _, err := TOSession.TenantByName(tn.Name)
- if err != nil {
- t.Fatalf("getting tenant %s: %v", tn.Name, err)
- }
- if _, err =
TOSession.DeleteTenant(strconv.Itoa(toTenant.ID)); err != nil {
- t.Fatalf("deleting tenant %s: %v",
toTenant.Name, err)
- }
- deletedTenants[tn.Name] = struct{}{}
-
- }
- if len(deletedTenants) == len(testData.Tenants) {
- break
- }
- if len(deletedTenants) == initLenDeleted {
- t.Fatal("could not delete tenants: not tenant without
an existing child found (cycle?)")
+func validateTenantSort() utils.CkReqFunc {
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{},
alerts tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ var tenants []string
+ tenantResp := resp.([]tc.Tenant)
+ for _, tenant := range tenantResp {
+ tenants = append(tenants, tenant.Name)
}
+ assert.Equal(t, true, sort.StringsAreSorted(tenants), "List is
not sorted by their names: %v", tenants)
}
}
-func ExtractXMLID(ds *tc.DeliveryServiceNullable) string {
- if ds.XMLID != nil {
- return *ds.XMLID
+func GetTenantID(t *testing.T, name string) func() int {
+ return func() int {
+ tenant, _, err := TOSession.TenantByNameWithHdr(name, nil)
+ assert.RequireNoError(t, err, "Get Tenants Request failed with
error:", err)
+ assert.RequireNotNil(t, tenant, "Expected tenant to not be nil")
+ return tenant.ID
}
- return "nil"
}
-func UpdateTestTenantsActive(t *testing.T) {
- originalTenants, _, err := TOSession.Tenants()
- if err != nil {
- t.Fatalf("getting tenants error expected: nil, actual: %+v",
err)
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", true)
- setTenantActive(t, "tenant3", false)
-
- // ds3 has tenant3. Even though tenant3 is inactive, we should still be
able to get it, because our user is tenant1, which is active.
- dses, _, err := TOSession.GetDeliveryServiceByXMLIDNullable("ds3")
- if err != nil {
- t.Fatal("failed to get delivery service, when the DS's tenant
was inactive (even though our user's tenant was active)")
- } else if len(dses) != 1 {
- t.Error("admin user getting delivery service ds3 with tenant3,
expected: ds, actual: empty")
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", false)
- setTenantActive(t, "tenant3", true)
-
- // ds3 has tenant3. Even though tenant3's parent, tenant2, is inactive,
we should still be able to get it, because our user is tenant1, which is active.
- _, _, err = TOSession.GetDeliveryServiceByXMLIDNullable("ds3")
- if err != nil {
- t.Fatal("failed to get delivery service, when a parent tenant
was inactive (even though our user's tenant was active)")
- }
-
- toReqTimeout := time.Second *
time.Duration(Config.Default.Session.TimeoutInSecs)
- tenant3Session, _, err := client.LoginWithAgent(TOSession.URL,
"tenant3user", "pa$$word", true, "to-api-v1-client-tests/tenant3user", true,
toReqTimeout)
- if err != nil {
- t.Fatalf("failed to get log in with tenant3user: " +
err.Error())
- }
-
- tenant4Session, _, err := client.LoginWithAgent(TOSession.URL,
"tenant4user", "pa$$word", true, "to-api-v1-client-tests/tenant4user", true,
toReqTimeout)
- if err != nil {
- t.Fatalf("failed to get log in with tenant4user: " +
err.Error())
- }
-
- // tenant3user with tenant3 has no access to ds3 with tenant3 when
parent tenant2 is inactive
- dses, _, err = tenant3Session.GetDeliveryServiceByXMLIDNullable("ds3")
- for _, ds := range dses {
- t.Errorf("tenant3user got delivery service %+v with tenant3 but
tenant3 parent tenant2 is inactive, expected: no ds", ExtractXMLID(&ds))
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", true)
- setTenantActive(t, "tenant3", false)
-
- // tenant3user with tenant3 has no access to ds3 with tenant3 when
tenant3 is inactive
- dses, _, err = tenant3Session.GetDeliveryServiceByXMLIDNullable("ds3")
- for _, ds := range dses {
- t.Errorf("tenant3user got delivery service %+v with tenant3 but
tenant3 is inactive, expected: no ds", ExtractXMLID(&ds))
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", true)
- setTenantActive(t, "tenant3", true)
-
- // tenant3user with tenant3 has access to ds3 with tenant3
- dses, _, err = tenant3Session.GetDeliveryServiceByXMLIDNullable("ds3")
- if err != nil {
- t.Errorf("tenant3user getting delivery service ds3 error
expected: nil, actual: %+v", err)
- } else if len(dses) == 0 {
- t.Error("tenant3user getting delivery service ds3 with tenant3,
expected: ds, actual: empty")
- }
-
- // 1. ds2 has tenant2.
- // 2. tenant3user has tenant3.
- // 3. tenant2 is not a child of tenant3 (tenant3 is a child of tenant2)
- // 4. Therefore, tenant3user should not have access to ds2
- dses, _, _ = tenant3Session.GetDeliveryServiceByXMLIDNullable("ds2")
- for _, ds := range dses {
- t.Errorf("tenant3user got delivery service %+v with tenant2,
expected: no ds", ExtractXMLID(&ds))
- }
-
- // 1. ds1 has tenant1.
- // 2. tenant4user has tenant4.
- // 3. tenant1 is not a child of tenant4 (tenant4 is unrelated to
tenant1)
- // 4. Therefore, tenant4user should not have access to ds1
- dses, _, _ = tenant4Session.GetDeliveryServiceByXMLIDNullable("ds1")
- for _, ds := range dses {
- t.Errorf("tenant4user got delivery service %+v with tenant1,
expected: no ds", ExtractXMLID(&ds))
+func CreateTestTenants(t *testing.T) {
+ for _, tenant := range testData.Tenants {
+ resp, err := TOSession.CreateTenant(&tenant)
+ assert.RequireNoError(t, err, "Could not create Tenant '%s': %v
- alerts: %+v", tenant.Name, err, resp.Alerts)
}
+}
- setTenantActive(t, "tenant3", false)
- dses, _, _ = tenant3Session.GetDeliveryServiceByXMLIDNullable("ds3")
- for _, ds := range dses {
- t.Errorf("tenant3user was inactive, but got delivery service
%+v with tenant3, expected: no ds", ExtractXMLID(&ds))
- }
+func DeleteTestTenants(t *testing.T) {
+ tenants, _, err := TOSession.TenantsWithHdr(nil)
+ assert.NoError(t, err, "Cannot get Tenants: %v", err)
- for _, tn := range originalTenants {
- if tn.Name == "root" {
+ for i := len(tenants) - 1; i >= 0; i-- {
+ if tenants[i].Name == "root" {
continue
}
- if _, err := TOSession.UpdateTenant(strconv.Itoa(tn.ID), &tn);
err != nil {
- t.Fatalf("restoring original tenants: " + err.Error())
- }
- }
-}
-
-func setTenantActive(t *testing.T, name string, active bool) {
- tn, _, err := TOSession.TenantByName(name)
- if err != nil {
- t.Fatalf("cannot GET Tenant by name: %s - %v", name, err)
- }
- tn.Active = active
- _, err = TOSession.UpdateTenant(strconv.Itoa(tn.ID), tn)
- if err != nil {
- t.Fatalf("cannot UPDATE Tenant by id: %v", err)
+ alerts, err :=
TOSession.DeleteTenant(strconv.Itoa(tenants[i].ID))
+ assert.NoError(t, err, "Unexpected error deleting Tenant '%s'
(#%d): %v - alerts: %+v", tenants[i].Name, tenants[i].ID, err, alerts.Alerts)
}
+ // Retrieve Tenants to see if they got deleted, only root should exist
+ tenants, _, err = TOSession.TenantsWithHdr(nil)
+ assert.NoError(t, err, "Error getting Tenants after deletion: %v", err)
+ assert.Equal(t, len(tenants), 1, "Expected only 1 Tenant, but found
%d.", len(tenants))
}
diff --git a/traffic_ops/testing/api/v4/deliveryservice_requests_test.go
b/traffic_ops/testing/api/v4/deliveryservice_requests_test.go
index 6890c33148..07e2e12111 100644
--- a/traffic_ops/testing/api/v4/deliveryservice_requests_test.go
+++ b/traffic_ops/testing/api/v4/deliveryservice_requests_test.go
@@ -82,7 +82,7 @@ func TestDeliveryServiceRequests(t *testing.T) {
"changeType": "create",
"requested":
generateDeliveryService(t, map[string]interface{}{
"displayName": "NEW
DISPLAY NAME",
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"xmlId":
"test-ds1",
}),
"status": "draft",
@@ -95,7 +95,7 @@ func TestDeliveryServiceRequests(t *testing.T) {
RequestBody: map[string]interface{}{
"changeType": "create",
"requested":
generateDeliveryService(t, map[string]interface{}{
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"xmlId": "test-ds1",
}),
"status": "submitted",
@@ -111,7 +111,7 @@ func TestDeliveryServiceRequests(t *testing.T) {
"requested":
generateDeliveryService(t, map[string]interface{}{
"longDesc1": "long desc
1",
"longDesc2": "long desc
2",
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"xmlId": "test-ds1",
}),
"status": "draft",
diff --git a/traffic_ops/testing/api/v4/deliveryservices_test.go
b/traffic_ops/testing/api/v4/deliveryservices_test.go
index dc079224d0..294ff54a07 100644
--- a/traffic_ops/testing/api/v4/deliveryservices_test.go
+++ b/traffic_ops/testing/api/v4/deliveryservices_test.go
@@ -38,6 +38,9 @@ func TestDeliveryServices(t *testing.T) {
currentTimeRFC := currentTime.Format(time.RFC1123)
tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+ tenant1UserSession := utils.CreateV4Session(t,
Config.TrafficOps.URL, "tenant1user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
+ tenant2UserSession := utils.CreateV4Session(t,
Config.TrafficOps.URL, "tenant2user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
+ tenant3UserSession := utils.CreateV4Session(t,
Config.TrafficOps.URL, "tenant3user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
tenant4UserSession := utils.CreateV4Session(t,
Config.TrafficOps.URL, "tenant4user", "pa$$word",
Config.Default.Session.TimeoutInSecs)
methodTests := utils.V4TestCase{
@@ -156,11 +159,31 @@ func TestDeliveryServices(t *testing.T) {
ClientSession: TOSession, RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"sortOrder": {"desc"}}},
Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
validateDescSort()),
},
- "EMPTY RESPONSE when TENANT attempts reading DS
OUTSIDE TENANCY": {
+ "OK when PARENT TENANT reads DS of INACTIVE
CHILD TENANT": {
+ ClientSession: tenant1UserSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"xmlId": {"ds2"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(1)),
+ },
+ "EMPTY RESPONSE when DS BELONGS to TENANT but
PARENT TENANT is INACTIVE": {
+ ClientSession: tenant3UserSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"xmlId": {"ds3"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ },
+ "EMPTY RESPONSE when INACTIVE TENANT reads DS
of SAME TENANCY": {
+ ClientSession: tenant2UserSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"xmlId": {"ds2"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ },
+ "EMPTY RESPONSE when TENANT reads DS OUTSIDE
TENANCY": {
ClientSession: tenant4UserSession,
RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"xmlId": {"ds3"}}},
Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
},
+ "EMPTY RESPONSE when CHILD TENANT reads DS of
PARENT TENANT": {
+ ClientSession: tenant3UserSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"xmlId": {"ds2"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
utils.ResponseHasLength(0)),
+ },
},
"POST": {
"CREATED when VALID request WITH GEO LIMIT
COUNTRIES": {
@@ -223,7 +246,7 @@ func TestDeliveryServices(t *testing.T) {
"BAD REQUEST when creating DS with TENANCY NOT
THE SAME AS CURRENT TENANT": {
ClientSession: tenant4UserSession,
RequestBody: generateDeliveryService(t,
map[string]interface{}{
- "tenantId": GetTenantId(t,
"tenant3"),
+ "tenantId": GetTenantID(t,
"tenant3")(),
"xmlId": "test-tenancy",
}),
Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusForbidden),
utils.ResponseHasLength(0)),
@@ -403,7 +426,7 @@ func TestDeliveryServices(t *testing.T) {
"maxOriginConnections":
500,
"routingName":
"cdn",
"signingAlgorithm":
"uri_signing",
- "tenantId":
GetTenantId(t, "tenant1"),
+ "tenantId":
GetTenantID(t, "tenant1")(),
"trRequestHeaders":
"X-ooF\nX-raB",
"trResponseHeaders":
"Access-Control-Max-Age: 600\nContent-Type: text/html; charset=utf-8",
"xmlId":
"ds-test-minor-versions",
@@ -478,7 +501,7 @@ func TestDeliveryServices(t *testing.T) {
if val, ok :=
testCase.RequestOpts.QueryParameters["accessibleTo"]; ok {
if _, err :=
strconv.Atoi(val[0]); err != nil {
-
testCase.RequestOpts.QueryParameters.Set("accessibleTo",
strconv.Itoa(GetTenantId(t, val[0])))
+
testCase.RequestOpts.QueryParameters.Set("accessibleTo",
strconv.Itoa(GetTenantID(t, val[0])()))
}
}
if val, ok :=
testCase.RequestOpts.QueryParameters["cdn"]; ok {
@@ -498,7 +521,7 @@ func TestDeliveryServices(t *testing.T) {
}
if val, ok :=
testCase.RequestOpts.QueryParameters["tenant"]; ok {
if _, err :=
strconv.Atoi(val[0]); err != nil {
-
testCase.RequestOpts.QueryParameters.Set("tenant", strconv.Itoa(GetTenantId(t,
val[0])))
+
testCase.RequestOpts.QueryParameters.Set("tenant", strconv.Itoa(GetTenantID(t,
val[0])()))
}
}
@@ -704,18 +727,6 @@ func GetProfileId(t *testing.T, profileName string) int {
return resp.Response[0].ID
}
-func GetTenantId(t *testing.T, tenantName string) int {
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("name", tenantName)
- resp, _, err := TOSession.GetTenants(opts)
-
- assert.RequireNoError(t, err, "Get Tenants Request failed with error:
%v", err)
- assert.RequireEqual(t, 1, len(resp.Response), "Expected response object
length 1, but got %d", len(resp.Response))
- assert.RequireNotNil(t, &resp.Response[0].ID, "Expected id to not be
nil")
-
- return resp.Response[0].ID
-}
-
func generateDeliveryService(t *testing.T, requestDS map[string]interface{})
map[string]interface{} {
// map for the most basic HTTP Delivery Service a user can create
genericHTTPDS := map[string]interface{}{
diff --git a/traffic_ops/testing/api/v4/tc-fixtures.json
b/traffic_ops/testing/api/v4/tc-fixtures.json
index 524c11f14d..af41fccfbb 100644
--- a/traffic_ops/testing/api/v4/tc-fixtures.json
+++ b/traffic_ops/testing/api/v4/tc-fixtures.json
@@ -6032,6 +6032,48 @@
"uid": 0,
"username": "readonlyuser"
},
+ {
+ "addressLine1": "address of tenant1user",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "[email protected]",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": "admin",
+ "stateOrProvince": "LA",
+ "tenant": "tenant1",
+ "uid": 0,
+ "username": "tenant1user"
+ },
+ {
+ "addressLine1": "address of tenant2user",
+ "addressLine2": "",
+ "city": "Anywhere",
+ "company": "Comcast",
+ "country": "USA",
+ "email": "[email protected]",
+ "fullName": "Fred the admin",
+ "gid": 0,
+ "localPasswd": "pa$$word",
+ "confirmLocalPasswd": "pa$$word",
+ "newUser": false,
+ "phoneNumber": "810-555-9876",
+ "postalCode": "55443",
+ "publicSshKey": "",
+ "role": "admin",
+ "stateOrProvince": "LA",
+ "tenant": "tenant2",
+ "uid": 0,
+ "username": "tenant2user"
+ },
{
"addressLine1": "address of admin",
"addressLine2": "",
diff --git a/traffic_ops/testing/api/v4/tenants_test.go
b/traffic_ops/testing/api/v4/tenants_test.go
index 66230c7ccf..8a294c7a3c 100644
--- a/traffic_ops/testing/api/v4/tenants_test.go
+++ b/traffic_ops/testing/api/v4/tenants_test.go
@@ -16,10 +16,9 @@ package v4
*/
import (
- "fmt"
+ "encoding/json"
"net/http"
"net/url"
- "reflect"
"sort"
"strconv"
"testing"
@@ -27,535 +26,313 @@ import (
"github.com/apache/trafficcontrol/lib/go-rfc"
"github.com/apache/trafficcontrol/lib/go-tc"
+ "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 TestTenants(t *testing.T) {
WithObjs(t, []TCObj{Tenants}, func() {
- SortTestTenants(t)
- GetTestTenants(t)
- UpdateTestTenants(t)
- UpdateTestRootTenant(t)
- currentTime := time.Now().UTC().Add(-5 * time.Second)
- time := currentTime.Format(time.RFC1123)
- var header http.Header
- header = make(map[string][]string)
- header.Set(rfc.IfUnmodifiedSince, time)
- UpdateTestTenantsWithHeaders(t, header)
- header = make(map[string][]string)
- etag := rfc.ETag(currentTime)
- header.Set(rfc.IfMatch, etag)
- UpdateTestTenantsWithHeaders(t, header)
- GetTestTenantsByActive(t)
- GetTestPaginationSupportTenant(t)
- SortTestTenantDesc(t)
- })
-}
-
-// This test will break if the testing Tenancy tree is modified in specific
ways
-func UpdateTestTenantsWithHeaders(t *testing.T, header http.Header) {
- opts := client.NewRequestOptions()
- opts.Header = header
-
- // Retrieve the Tenant by name so we can get the id for the Update
- name := "tenant2"
- opts.QueryParameters.Set("name", name)
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", name, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with the name
'tenant2', found: %d", len(resp.Response))
- }
- modTenant := resp.Response[0]
-
- parentName := "tenant1"
- opts.QueryParameters.Set("name", parentName)
- resp, _, err = TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", parentName, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with the name
'tenant1', found: %d", len(resp.Response))
- }
- newParent := resp.Response[0]
- modTenant.ParentID = newParent.ID
- opts.QueryParameters.Del("name")
- _, reqInf, err := TOSession.UpdateTenant(modTenant.ID, modTenant, opts)
- if err == nil {
- t.Fatalf("expected a precondition failed error, got none")
- }
- if reqInf.StatusCode != http.StatusPreconditionFailed {
- t.Errorf("expected a status 412 Precondition Failed, but got
%d", reqInf.StatusCode)
- }
-}
-
-func TestTenantsActive(t *testing.T) {
- WithObjs(t, []TCObj{CDNs, Types, Tenants, CacheGroups, Parameters,
Profiles, Statuses, Divisions, Regions, PhysLocations, Servers, Topologies,
ServiceCategories, DeliveryServices, Users}, func() {
- UpdateTestTenantsActive(t)
- })
-}
-
-func CreateTestTenants(t *testing.T) {
- for _, ten := range testData.Tenants {
- resp, _, err := TOSession.CreateTenant(ten,
client.RequestOptions{})
- if err != nil {
- t.Errorf("could not create Tenant '%s': %v - alerts:
%+v", ten.Name, err, resp.Alerts)
- } else if resp.Response.Name != ten.Name {
- t.Errorf("expected tenant '%s'; got '%s'", ten.Name,
resp.Response.Name)
+ currentTime := time.Now().UTC().Add(-15 * time.Second)
+ currentTimeRFC := currentTime.Format(time.RFC1123)
+ tomorrow := currentTime.AddDate(0, 0, 1).Format(time.RFC1123)
+
+ methodTests := utils.V4TestCase{
+ "GET": {
+ "NOT MODIFIED when NO CHANGES made": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {tomorrow}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+ },
+ "OK when VALID request": {
+ ClientSession: TOSession,
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+
utils.ResponseLengthGreaterOrEqual(1), validateTenantSort()),
+ },
+ "OK when VALID ACTIVE parameter": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"active": {"true"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+
validateTenantFields(map[string]interface{}{"Active": true})),
+ },
+ "VALID when SORTORDER param is DESC": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"sortOrder": {"desc"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
validateTenantDescSort()),
+ },
+ "FIRST RESULT when LIMIT=1": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit":
{"1"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
validateTenantPagination("limit")),
+ },
+ "SECOND RESULT when LIMIT=1 OFFSET=1": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit":
{"1"}, "offset": {"1"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
validateTenantPagination("offset")),
+ },
+ "SECOND RESULT when LIMIT=1 PAGE=2": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit":
{"1"}, "page": {"2"}}},
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
validateTenantPagination("page")),
+ },
+ "BAD REQUEST when INVALID LIMIT parameter": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"limit": {"-2"}}},
+ Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+ },
+ "BAD REQUEST when INVALID OFFSET parameter": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "offset":
{"0"}}},
+ Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+ },
+ "BAD REQUEST when INVALID PAGE parameter": {
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "page":
{"0"}}},
+ Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+ },
+ },
+ "POST": {
+ "OK when VALID request": {
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": true,
+ "name": "tenant5",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+
validateTenantCreateUpdateFields(map[string]interface{}{"Name": "tenant5"})),
+ },
+ },
+ "PUT": {
+ "OK when VALID request": {
+ EndpointId: GetTenantID(t,
"tenant4"),
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "newname",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ Expectations:
utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK),
+
validateTenantCreateUpdateFields(map[string]interface{}{"Name": "newname",
"Active": false})),
+ },
+ "BAD REQUEST when ROOT TENANT": {
+ EndpointId: GetTenantID(t, "root"),
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "tenant1",
+ "parentName": "root",
+ },
+ Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+ },
+ "PRECONDITION FAILED when updating with IMS &
IUS Headers": {
+ EndpointId: GetTenantID(t,
"tenant2"),
+ ClientSession: TOSession,
+ RequestOpts:
client.RequestOptions{Header: http.Header{rfc.IfUnmodifiedSince:
{currentTimeRFC}}},
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "tenant2",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ Expectations:
utils.CkRequest(utils.HasError(),
utils.HasStatus(http.StatusPreconditionFailed)),
+ },
+ "PRECONDITION FAILED when updating with IFMATCH
ETAG Header": {
+ EndpointId: GetTenantID(t,
"tenant2"),
+ ClientSession: TOSession,
+ RequestBody: map[string]interface{}{
+ "active": false,
+ "name": "tenant2",
+ "parentName": "root",
+ "parentId": GetTenantID(t,
"root")(),
+ },
+ RequestOpts:
client.RequestOptions{Header: http.Header{rfc.IfMatch:
{rfc.ETag(currentTime)}}},
+ Expectations:
utils.CkRequest(utils.HasError(),
utils.HasStatus(http.StatusPreconditionFailed)),
+ },
+ },
+ "DELETE": {
+ "BAD REQUEST when TENANT HAS CHILDREN": {
+ EndpointId: GetTenantID(t,
"tenant1"),
+ ClientSession: TOSession,
+ Expectations:
utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+ },
+ },
}
- }
-}
-func GetTestTenantsByActive(t *testing.T) {
- opts := client.NewRequestOptions()
- for _, ten := range testData.Tenants {
- opts.QueryParameters.Set("active",
strconv.FormatBool(ten.Active))
- resp, reqInf, err := TOSession.GetTenants(opts)
- if len(resp.Response) < 1 {
- t.Errorf("Expected atleast one Tenants response %v",
resp)
- }
- if err != nil {
- t.Errorf("cannot get Tenant by Active: %v - alerts:
%+v", err, resp.Alerts)
- }
- if reqInf.StatusCode != http.StatusOK {
- t.Errorf("Expected 200 status code, got %v",
reqInf.StatusCode)
+ for method, testCases := range methodTests {
+ t.Run(method, func(t *testing.T) {
+ for name, testCase := range testCases {
+ tenant := tc.Tenant{}
+
+ if testCase.RequestBody != nil {
+ dat, err :=
json.Marshal(testCase.RequestBody)
+ assert.NoError(t, err, "Error
occurred when marshalling request body: %v", err)
+ err = json.Unmarshal(dat,
&tenant)
+ assert.NoError(t, err, "Error
occurred when unmarshalling request body: %v", err)
+ }
+
+ switch method {
+ case "GET", "GET AFTER CHANGES":
+ t.Run(name, func(t *testing.T) {
+ resp, reqInf, err :=
testCase.ClientSession.GetTenants(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.CreateTenant(tenant, testCase.RequestOpts)
+ for _, check := range
testCase.Expectations {
+ check(t,
reqInf, resp.Response, resp.Alerts, err)
+ }
+ })
+ case "PUT":
+ t.Run(name, func(t *testing.T) {
+ resp, reqInf, err :=
testCase.ClientSession.UpdateTenant(testCase.EndpointId(), tenant,
testCase.RequestOpts)
+ for _, check := range
testCase.Expectations {
+ check(t,
reqInf, resp.Response, resp.Alerts, err)
+ }
+ })
+ case "DELETE":
+ t.Run(name, func(t *testing.T) {
+ alerts, reqInf, err :=
testCase.ClientSession.DeleteTenant(testCase.EndpointId(), testCase.RequestOpts)
+ for _, check := range
testCase.Expectations {
+ check(t,
reqInf, nil, alerts, err)
+ }
+ })
+ }
+ }
+ })
}
- }
+ })
}
-func GetTestTenants(t *testing.T) {
- resp, _, err := TOSession.GetTenants(client.RequestOptions{})
- if err != nil {
- t.Errorf("cannot get all Tenants: %v - alerts: %+v", err,
resp.Alerts)
- return
- }
- foundTenants := make(map[string]tc.Tenant, len(resp.Response))
- for _, ten := range resp.Response {
- foundTenants[ten.Name] = ten
- }
-
- // expect root and badTenant (defined in todb.go) + all defined in
testData.Tenants
- if len(resp.Response) != 2+len(testData.Tenants) {
- t.Errorf("expected %d tenants, got %d",
2+len(testData.Tenants), len(resp.Response))
- }
-
- for _, ten := range testData.Tenants {
- if ft, ok := foundTenants[ten.Name]; ok {
- if ft.ParentName != ten.ParentName {
- t.Errorf("Tenant '%s': expected parent '%s',
got '%s'", ten.Name, ten.ParentName, ft.ParentName)
+func validateTenantFields(expectedResp map[string]interface{}) utils.CkReqFunc
{
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _
tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ tenantResp := resp.([]tc.Tenant)
+ for field, expected := range expectedResp {
+ for _, tenant := range tenantResp {
+ switch field {
+ case "Active":
+ assert.Equal(t, expected,
tenant.Active, "Expected Active to be %v, but got %b", expected, tenant.Active)
+ case "Name":
+ assert.Equal(t, expected, tenant.Name,
"Expected Name to be %v, but got %s", expected, tenant.Name)
+ case "ParentName":
+ assert.Equal(t, expected,
tenant.ParentName, "Expected ParentName to be %v, but got %s", expected,
tenant.ParentName)
+ default:
+ t.Errorf("Expected field: %v, does not
exist in response", field)
+ }
}
- } else {
- t.Errorf("expected Tenant '%s': not found", ten.Name)
}
}
}
-func SortTestTenants(t *testing.T) {
- resp, _, err := TOSession.GetTenants(client.RequestOptions{})
- if err != nil {
- t.Fatalf("Expected no error, but got: %v - alerts: %+v", err,
resp.Alerts)
- }
- sortedList := make([]string, 0, len(resp.Response))
- for _, tenant := range resp.Response {
- sortedList = append(sortedList, tenant.Name)
- }
-
- if !sort.StringsAreSorted(sortedList) {
- t.Errorf("list is not sorted by their names: %v", sortedList)
- }
-}
-
-func UpdateTestTenants(t *testing.T) {
-
- // Retrieve the Tenant by name so we can get the id for the Update
- name := "tenant2"
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("name", name)
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", name, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with the name
'tenant2', found: %d", len(resp.Response))
- }
- modTenant := resp.Response[0]
-
- parentName := "tenant1"
- opts.QueryParameters.Set("name", parentName)
- resp, _, err = TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", parentName, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with the name
'tenant1', found: %d", len(resp.Response))
+func validateTenantCreateUpdateFields(expectedResp map[string]interface{})
utils.CkReqFunc {
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _
tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ tenantResp := resp.(tc.Tenant)
+ tenants := []tc.Tenant{tenantResp}
+ validateTenantFields(expectedResp)(t, toclientlib.ReqInf{},
tenants, tc.Alerts{}, nil)
}
- newParent := resp.Response[0]
- modTenant.ParentID = newParent.ID
-
- response, _, err := TOSession.UpdateTenant(modTenant.ID, modTenant,
client.RequestOptions{})
- if err != nil {
- t.Errorf("cannot update Tenant: %v - alerts: %+v", err,
response.Alerts)
- }
-
- // Retrieve the Tenant to check Tenant parent name got updated
- opts.QueryParameters.Del("name")
- opts.QueryParameters.Set("id", strconv.Itoa(modTenant.ID))
- resp, _, err = TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", name, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with ID %d,
found: %d", modTenant.ID, len(resp.Response))
- }
- respTenant := resp.Response[0]
- if respTenant.ParentName != parentName {
- t.Errorf("results do not match actual: %s, expected: %s",
respTenant.ParentName, parentName)
- }
-
}
-func UpdateTestRootTenant(t *testing.T) {
- // Retrieve the Tenant by name so we can get the id for the Update
- name := "root"
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("name", name)
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", name, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with the name
'root', found: %d", len(resp.Response))
- }
- modTenant := resp.Response[0]
-
- modTenant.Active = false
- modTenant.ParentID = modTenant.ID
- _, reqInf, err := TOSession.UpdateTenant(modTenant.ID, modTenant,
client.RequestOptions{})
- if err == nil {
- t.Fatalf("expected an error when trying to update the 'root'
tenant, but got nothing")
- }
- if reqInf.StatusCode != http.StatusBadRequest {
- t.Errorf("expected a status 400 Bad Request, but got %d",
reqInf.StatusCode)
+func validateTenantSort() utils.CkReqFunc {
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{},
alerts tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ var tenants []string
+ tenantResp := resp.([]tc.Tenant)
+ for _, tenant := range tenantResp {
+ tenants = append(tenants, tenant.Name)
+ }
+ assert.Equal(t, true, sort.StringsAreSorted(tenants), "List is
not sorted by their names: %v", tenants)
}
}
-func DeleteTestTenants(t *testing.T) {
- t1 := "tenant1"
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("name", t1)
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", t1, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expeected exactly one Tenant to exist with the name
'%s', found: %d", t1, len(resp.Response))
- }
- tenant1 := resp.Response[0]
-
- expectedChildDeleteErrMsg := fmt.Sprintf("Tenant '%d' has child
tenants. Please update these child tenants and retry.", tenant1.ID)
- if response, _, err := TOSession.DeleteTenant(tenant1.ID,
client.RequestOptions{}); err == nil {
- t.Fatalf("%s has child tenants -- should not be able to
delete", t1)
- } else if !alertsHaveError(response.Alerts, expectedChildDeleteErrMsg) {
- t.Errorf("expected error: %s; got: %v - alerts: %+v",
expectedChildDeleteErrMsg, err, response.Alerts)
- }
-
- deletedTenants := map[string]struct{}{}
- for {
- initLenDeleted := len(deletedTenants)
- for _, tn := range testData.Tenants {
- if _, ok := deletedTenants[tn.Name]; ok {
- continue
- }
-
- hasParent := false
- for _, otherTenant := range testData.Tenants {
- if _, ok := deletedTenants[otherTenant.Name];
ok {
- continue
- }
- if otherTenant.ParentName == tn.Name {
- hasParent = true
- break
- }
- }
- if hasParent {
- continue
- }
-
- opts.QueryParameters.Set("name", tn.Name)
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Fatalf("getting Tenants filtered by name
'%s': %v - alerts: %+v", tn.Name, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist
with the name '%s', found: %d", tn.Name, len(resp.Response))
- }
- toTenant := resp.Response[0]
-
- if alerts, _, err :=
TOSession.DeleteTenant(toTenant.ID, client.RequestOptions{}); err != nil {
- t.Fatalf("deleting Tenant '%s': %v - alerts:
%+v", toTenant.Name, err, alerts.Alerts)
- }
- deletedTenants[tn.Name] = struct{}{}
-
- }
- if len(deletedTenants) == len(testData.Tenants) {
- break
+func validateTenantDescSort() utils.CkReqFunc {
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{},
alerts tc.Alerts, _ error) {
+ assert.RequireNotNil(t, resp, "Expected Tenant response to not
be nil.")
+ tenantDescResp := resp.([]tc.Tenant)
+ var descSortedList []string
+ var ascSortedList []string
+ assert.RequireGreaterOrEqual(t, len(tenantDescResp), 2, "Need
at least 2 Tenants in Traffic Ops to test desc sort, found: %d",
len(tenantDescResp))
+ // Get Tenants in the default ascending order for comparison.
+ tenantsAscResp, _, err :=
TOSession.GetTenants(client.RequestOptions{})
+ assert.RequireNoError(t, err, "Unexpected error getting Tenants
with default sort order: %v - alerts: %+v", err, tenantsAscResp.Alerts)
+ // Verify the response match in length, i.e. equal amount of
Tenants.
+ assert.RequireEqual(t, len(tenantsAscResp.Response),
len(tenantDescResp), "Expected descending order response length: %v, to match
ascending order response length %v", len(tenantsAscResp.Response),
len(tenantDescResp))
+ // Insert Tenant names to the front of a new list, so they are
now reversed to be in ascending order.
+ for _, tenant := range tenantDescResp {
+ descSortedList = append([]string{tenant.Name},
descSortedList...)
}
- if len(deletedTenants) == initLenDeleted {
- t.Fatal("could not delete tenants: not tenant without
an existing child found (cycle?)")
+ // Insert Tenant names by appending to a new list, so they stay
in ascending order.
+ for _, tenant := range tenantsAscResp.Response {
+ ascSortedList = append(ascSortedList, tenant.Name)
}
+ assert.Exactly(t, ascSortedList, descSortedList, "Tenant
responses are not equal after reversal: %v - %v", ascSortedList, descSortedList)
}
}
-func ExtractXMLID(ds *tc.DeliveryServiceV4) string {
- if ds.XMLID != nil {
- return *ds.XMLID
- }
- return "nil"
-}
-
-func UpdateTestTenantsActive(t *testing.T) {
- originalTenants, _, err := TOSession.GetTenants(client.RequestOptions{})
- if err != nil {
- t.Fatalf("getting Tenants error expected: nil, actual: %v -
alerts: %+v", err, originalTenants.Alerts)
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", true)
- setTenantActive(t, "tenant3", false)
-
- // ds3 has tenant3. Even though tenant3 is inactive, we should still be
able to get it, because our user is tenant1, which is active.
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("xmlId", "ds3")
- resp, _, err := TOSession.GetDeliveryServices(opts)
- if err != nil {
- t.Fatalf("failed to get delivery service, when the DS's tenant
was inactive (even though our user's tenant was active): %v - alerts: %+v",
err, resp.Alerts)
- } else if len(resp.Response) != 1 {
- t.Error("admin user getting delivery service ds3 with tenant3,
expected: ds, actual: empty")
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", false)
- setTenantActive(t, "tenant3", true)
-
- // ds3 has tenant3. Even though tenant3's parent, tenant2, is inactive,
we should still be able to get it, because our user is tenant1, which is active.
- resp, _, err = TOSession.GetDeliveryServices(opts)
- if err != nil {
- t.Fatalf("failed to get delivery service, when a parent tenant
was inactive (even though our user's tenant was active): %v - alerts: %+v",
err, resp.Alerts)
- }
-
- toReqTimeout := time.Second *
time.Duration(Config.Default.Session.TimeoutInSecs)
- tenant3Session, _, err := client.LoginWithAgent(TOSession.URL,
"tenant3user", "pa$$word", true, "to-api-v1-client-tests/tenant3user", true,
toReqTimeout)
- if err != nil {
- t.Fatalf("failed to get log in with tenant3user: " +
err.Error())
- }
-
- tenant4Session, _, err := client.LoginWithAgent(TOSession.URL,
"tenant4user", "pa$$word", true, "to-api-v1-client-tests/tenant4user", true,
toReqTimeout)
- if err != nil {
- t.Fatalf("failed to get log in with tenant4user: " +
err.Error())
- }
-
- // tenant3user with tenant3 has no access to ds3 with tenant3 when
parent tenant2 is inactive
- resp, _, err = tenant3Session.GetDeliveryServices(opts)
- if err != nil {
- t.Errorf("Unexpected error fetching Delivery Services filtered
by XMLID 'ds3': %v - alerts: %+v", err, resp.Alerts)
- }
- for _, ds := range resp.Response {
- t.Errorf("tenant3user got delivery service %s with tenant3 but
tenant3 parent tenant2 is inactive, expected: no ds", ExtractXMLID(&ds))
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", true)
- setTenantActive(t, "tenant3", false)
-
- // tenant3user with tenant3 has no access to ds3 with tenant3 when
tenant3 is inactive
- resp, _, err = tenant3Session.GetDeliveryServices(opts)
- if err != nil {
- t.Errorf("Unexpected error fetching Delivery Services filtered
by XMLID 'ds3': %v - alerts: %+v", err, resp.Alerts)
- }
- for _, ds := range resp.Response {
- t.Errorf("tenant3user got delivery service %s with tenant3 but
tenant3 is inactive, expected: no ds", ExtractXMLID(&ds))
- }
-
- setTenantActive(t, "tenant1", true)
- setTenantActive(t, "tenant2", true)
- setTenantActive(t, "tenant3", true)
-
- // tenant3user with tenant3 has access to ds3 with tenant3
- resp, _, err = tenant3Session.GetDeliveryServices(opts)
- if err != nil {
- t.Errorf("tenant3user getting delivery service ds3 error
expected: nil, actual: %+v", err)
- } else if len(resp.Response) == 0 {
- t.Error("tenant3user getting delivery service ds3 with tenant3,
expected: ds, actual: empty")
- }
-
- // 1. ds2 has tenant2.
- // 2. tenant3user has tenant3.
- // 3. tenant2 is not a child of tenant3 (tenant3 is a child of tenant2)
- // 4. Therefore, tenant3user should not have access to ds2
- opts.QueryParameters.Set("xmlId", "ds2")
- resp, _, err = tenant3Session.GetDeliveryServices(opts)
- if err != nil {
- t.Errorf("Unexpected error fetching Delivery Services filtered
by XMLID 'ds2': %v - alerts: %+v", err, resp.Alerts)
- }
- for _, ds := range resp.Response {
- t.Errorf("tenant3user got delivery service %s with tenant2,
expected: no ds", ExtractXMLID(&ds))
- }
-
- // 1. ds1 has tenant1.
- // 2. tenant4user has tenant4.
- // 3. tenant1 is not a child of tenant4 (tenant4 is unrelated to
tenant1)
- // 4. Therefore, tenant4user should not have access to ds1
- opts.QueryParameters.Set("xmlId", "ds1")
- resp, _, err = tenant4Session.GetDeliveryServices(opts)
- if err != nil {
- t.Errorf("Unexpected error fetching Delivery Services filtered
by XMLID 'ds1': %v - alerts: %+v", err, resp.Alerts)
- }
- for _, ds := range resp.Response {
- t.Errorf("tenant4user got delivery service %s with tenant1,
expected: no ds", ExtractXMLID(&ds))
- }
-
- setTenantActive(t, "tenant3", false)
- opts.QueryParameters.Set("xmlId", "ds3")
- resp, _, err = tenant3Session.GetDeliveryServices(opts)
- if err != nil {
- t.Errorf("Unexpected error fetching Delivery Services filtered
by XMLID 'ds3': %v - alerts: %+v", err, resp.Alerts)
- }
- for _, ds := range resp.Response {
- t.Errorf("tenant3user was inactive, but got delivery service %s
with tenant3, expected: no ds", ExtractXMLID(&ds))
- }
-
- for _, tn := range originalTenants.Response {
- if tn.Name == "root" {
- continue
- }
- if resp, _, err := TOSession.UpdateTenant(tn.ID, tn,
client.RequestOptions{}); err != nil {
- t.Fatalf("restoring original tenants: %v - alerts:
%+v", err, resp.Alerts)
+func validateTenantPagination(paginationParam string) utils.CkReqFunc {
+ return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _
tc.Alerts, _ error) {
+ paginationResp := resp.([]tc.Tenant)
+
+ opts := client.NewRequestOptions()
+ opts.QueryParameters.Set("orderby", "id")
+ respBase, _, err := TOSession.GetTenants(opts)
+ assert.RequireNoError(t, err, "Cannot get Tenants: %v - alerts:
%+v", err, respBase.Alerts)
+
+ tenants := respBase.Response
+ assert.RequireGreaterOrEqual(t, len(tenants), 3, "Need at least
3 Tenants in Traffic Ops to test pagination support, found: %d", len(tenants))
+ switch paginationParam {
+ case "limit:":
+ assert.Exactly(t, tenants[:1], paginationResp,
"expected GET Tenants with limit = 1 to return first result")
+ case "offset":
+ assert.Exactly(t, tenants[1:2], paginationResp,
"expected GET Tenants with limit = 1, offset = 1 to return second result")
+ case "page":
+ assert.Exactly(t, tenants[1:2], paginationResp,
"expected GET Tenants with limit = 1, page = 2 to return second result")
}
}
}
-func setTenantActive(t *testing.T, name string, active bool) {
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("name", name)
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Fatalf("cannot get Tenants filtered by name '%s': %v -
alerts: %+v", name, err, resp.Alerts)
- }
- if len(resp.Response) != 1 {
- t.Fatalf("Expected exactly one Tenant to exist with the name
'%s', found: %d", name, len(resp.Response))
- }
- tn := resp.Response[0]
-
- tn.Active = active
- response, _, err := TOSession.UpdateTenant(tn.ID, tn,
client.RequestOptions{})
- if err != nil {
- t.Fatalf("cannot update Tenant: %v - alerts: %+v", err,
response.Alerts)
+func GetTenantID(t *testing.T, name string) func() int {
+ return func() int {
+ opts := client.NewRequestOptions()
+ opts.QueryParameters.Set("name", name)
+ tenants, _, err := TOSession.GetTenants(opts)
+ assert.RequireNoError(t, err, "Get Tenants Request failed with
error:", err)
+ assert.RequireEqual(t, 1, len(tenants.Response), "Expected
response object length 1, but got %d", len(tenants.Response))
+ return tenants.Response[0].ID
}
}
-func GetTestPaginationSupportTenant(t *testing.T) {
- opts := client.NewRequestOptions()
- opts.QueryParameters.Set("orderby", "id")
- resp, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Fatalf("cannot Get Tenant: %v - alerts: %+v", err,
resp.Alerts)
- }
- tenant := resp.Response
- if len(tenant) < 3 {
- t.Fatalf("Need at least 3 Tenants in Traffic Ops to test
pagination support, found: %d", len(tenant))
- }
-
- opts.QueryParameters.Set("limit", "1")
- tenantsWithLimit, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Fatalf("cannot Get Tenant with Limit: %v - alerts: %+v", err,
tenantsWithLimit.Alerts)
- }
- if !reflect.DeepEqual(tenant[:1], tenantsWithLimit.Response) {
- t.Error("expected GET tenants with limit = 1 to return first
result")
- }
-
- opts.QueryParameters.Set("offset", "1")
- tenantsWithOffset, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Fatalf("cannot Get Tenant with Limit and Offset: %v - alerts:
%+v", err, tenantsWithOffset.Alerts)
- }
- if !reflect.DeepEqual(tenant[1:2], tenantsWithOffset.Response) {
- t.Error("expected GET tenant with limit = 1, offset = 1 to
return second result")
- }
-
- opts.QueryParameters.Del("offset")
- opts.QueryParameters.Set("page", "2")
- tenantsWithPage, _, err := TOSession.GetTenants(opts)
- if err != nil {
- t.Fatalf("cannot Get Tenant with Limit and Page: %v - alerts:
%+v", err, tenantsWithPage.Alerts)
- }
- if !reflect.DeepEqual(tenant[1:2], tenantsWithPage.Response) {
- t.Error("expected GET tenant with limit = 1, page = 2 to return
second result")
- }
-
- opts.QueryParameters = url.Values{}
- opts.QueryParameters.Set("limit", "-2")
- resp, _, err = TOSession.GetTenants(opts)
- if err == nil {
- t.Error("expected GET tenant to return an error when limit is
not bigger than -1")
- } else if !alertsHaveError(resp.Alerts.Alerts, "must be bigger than
-1") {
- t.Errorf("expected GET tenant to return an error for limit is
not bigger than -1, actual error: %v - alerts: %+v", err, resp.Alerts)
- }
-
- opts.QueryParameters.Set("limit", "1")
- opts.QueryParameters.Set("offset", "0")
- resp, _, err = TOSession.GetTenants(opts)
- if err == nil {
- t.Error("expected GET tenant to return an error when offset is
not a positive integer")
- } else if !alertsHaveError(resp.Alerts.Alerts, "must be a positive
integer") {
- t.Errorf("expected GET tenant to return an error for offset is
not a positive integer, actual error: %v - alerts: %+v", err, resp.Alerts)
- }
-
- opts.QueryParameters = url.Values{}
- opts.QueryParameters.Set("limit", "1")
- opts.QueryParameters.Set("page", "0")
- resp, _, err = TOSession.GetTenants(opts)
- if err == nil {
- t.Error("expected GET tenant to return an error when page is
not a positive integer")
- } else if !alertsHaveError(resp.Alerts.Alerts, "must be a positive
integer") {
- t.Errorf("expected GET tenant to return an error for page is
not a positive integer, actual error: %v - alerts: %+v", err, resp.Alerts)
+func CreateTestTenants(t *testing.T) {
+ for _, tenant := range testData.Tenants {
+ resp, _, err := TOSession.CreateTenant(tenant,
client.RequestOptions{})
+ assert.RequireNoError(t, err, "Could not create Tenant '%s': %v
- alerts: %+v", tenant.Name, err, resp.Alerts)
}
}
-func SortTestTenantDesc(t *testing.T) {
- resp, _, err := TOSession.GetTenants(client.RequestOptions{})
- if err != nil {
- t.Errorf("Expected no error, but got error in Tenant with
default ordering: %v - alerts: %+v", err, resp.Alerts)
- }
- respAsc := resp.Response
- if len(respAsc) < 1 {
- t.Fatal("Need at least one Tenant in Traffic Ops to test Tenant
sort ordering")
- }
-
+func DeleteTestTenants(t *testing.T) {
opts := client.NewRequestOptions()
opts.QueryParameters.Set("sortOrder", "desc")
- resp, _, err = TOSession.GetTenants(opts)
- if err != nil {
- t.Errorf("Expected no error, but got error in Tenant with
Descending ordering: %v - alerts: %+v", err, resp.Alerts)
- }
- respDesc := resp.Response
- if len(respDesc) < 1 {
- t.Fatal("Need at least one Tenant in Traffic Ops to test Tenant
sort ordering")
- }
+ tenants, _, err := TOSession.GetTenants(opts)
+ assert.NoError(t, err, "Cannot get Tenants: %v - alerts: %+v", err,
tenants.Alerts)
- if len(respAsc) != len(respDesc) {
- t.Fatalf("Traffic Ops returned %d Tenant using default sort
order, but %d Tenant when sort order was explicitly set to descending",
len(respAsc), len(respDesc))
- }
-
- // reverse the descending-sorted response and compare it to the
ascending-sorted one
- // TODO ensure at least two in each slice? A list of length one is
- // trivially sorted both ascending and descending.
- for start, end := 0, len(respDesc)-1; start < end; start, end =
start+1, end-1 {
- respDesc[start], respDesc[end] = respDesc[end], respDesc[start]
- }
- if respDesc[0].Name != respAsc[0].Name {
- t.Errorf("Tenant responses are not equal after reversal: Asc:
%s - Desc: %s", respDesc[0].Name, respAsc[0].Name)
+ for _, tenant := range tenants.Response {
+ if tenant.Name == "root" {
+ continue
+ }
+ alerts, _, err := TOSession.DeleteTenant(tenant.ID,
client.RequestOptions{})
+ assert.NoError(t, err, "Unexpected error deleting Tenant '%s'
(#%d): %v - alerts: %+v", tenant.Name, tenant.ID, err, alerts.Alerts)
+ // Retrieve the Tenant to see if it got deleted
+ opts.QueryParameters.Set("id", strconv.Itoa(tenant.ID))
+ getTenants, _, err := TOSession.GetTenants(opts)
+ assert.NoError(t, err, "Error getting Tenant '%s' after
deletion: %v - alerts: %+v", tenant.Name, err, getTenants.Alerts)
+ assert.Equal(t, 0, len(getTenants.Response), "Expected Tenant
'%s' to be deleted, but it was found in Traffic Ops", tenant.Name)
}
}