You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ra...@apache.org on 2018/10/04 14:39:36 UTC

[trafficcontrol] 04/10: Add TO Go federations tests

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

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

commit 7594b3765b47ce36d8e46a9e139b3012a97789a1
Author: Robert Butts <ro...@apache.org>
AuthorDate: Fri Sep 21 17:17:19 2018 -0600

    Add TO Go federations tests
---
 lib/go-tc/federation.go                            |   4 -
 traffic_ops/client/federation.go                   |  80 ++++++++++++
 traffic_ops/testing/api/v13/federations_test.go    | 145 +++++++++++++++++++++
 traffic_ops/testing/api/v14/cdnfederations_test.go |   1 +
 traffic_ops/traffic_ops_golang/federations/ds.go   |  11 +-
 .../traffic_ops_golang/federations/federations.go  |   3 +-
 6 files changed, 234 insertions(+), 10 deletions(-)

diff --git a/lib/go-tc/federation.go b/lib/go-tc/federation.go
index 44ec733..33c604c 100644
--- a/lib/go-tc/federation.go
+++ b/lib/go-tc/federation.go
@@ -21,7 +21,6 @@ package tc
 
 import (
 	"database/sql"
-	"errors"
 )
 
 type CDNFederationResponse struct {
@@ -102,8 +101,5 @@ type FederationDSPost struct {
 }
 
 func (f *FederationDSPost) Validate(tx *sql.Tx) error {
-	if len(f.DSIDs) == 0 {
-		return errors.New("no dsIds to assign")
-	}
 	return nil
 }
diff --git a/traffic_ops/client/federation.go b/traffic_ops/client/federation.go
new file mode 100644
index 0000000..84c26b6
--- /dev/null
+++ b/traffic_ops/client/federation.go
@@ -0,0 +1,80 @@
+/*
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package client
+
+import (
+	"encoding/json"
+	"errors"
+	"net/http"
+	"strconv"
+
+	"github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+func (to *Session) Federations() ([]tc.AllFederation, ReqInf, error) {
+	type FederationResponse struct {
+		Response []tc.AllFederation `json:"response"`
+	}
+	data := FederationResponse{}
+	inf, err := get(to, apiBase+"/federations", &data)
+	return data.Response, inf, err
+}
+
+func (to *Session) AllFederations() ([]tc.AllFederation, ReqInf, error) {
+	type FederationResponse struct {
+		Response []tc.AllFederation `json:"response"`
+	}
+	data := FederationResponse{}
+	inf, err := get(to, apiBase+"/federations/all", &data)
+	return data.Response, inf, err
+}
+
+func (to *Session) AllFederationsForCDN(cdnName string) ([]tc.AllFederation, ReqInf, error) {
+	// because the Federations JSON array is heterogeneous (array members may be a AllFederation or AllFederationCDN), we have to try decoding each separately.
+	type FederationResponse struct {
+		Response []json.RawMessage `json:"response"`
+	}
+	data := FederationResponse{}
+	inf, err := get(to, apiBase+"/federations/all?cdnName="+cdnName, &data)
+	if err != nil {
+		return nil, inf, err
+	}
+
+	feds := []tc.AllFederation{}
+	for _, raw := range data.Response {
+		fed := tc.AllFederation{}
+		if err := json.Unmarshal([]byte(raw), &fed); err != nil {
+			// we don't actually need the CDN, but we want to return an error if we got something unexpected
+			cdnFed := tc.AllFederationCDN{}
+			if err := json.Unmarshal([]byte(raw), &cdnFed); err != nil {
+				return nil, inf, errors.New("Traffic Ops returned an unexpected object: '" + string(raw) + "'")
+			}
+		}
+		feds = append(feds, fed)
+	}
+	return feds, inf, nil
+}
+
+func (to *Session) CreateFederationDeliveryServices(federationID int, deliveryServiceIDs []int, replace bool) (ReqInf, error) {
+	req := tc.FederationDSPost{DSIDs: deliveryServiceIDs, Replace: &replace}
+	jsonReq, err := json.Marshal(req)
+	if err != nil {
+		return ReqInf{CacheHitStatus: CacheHitStatusMiss}, err
+	}
+	resp := map[string]interface{}{}
+	inf, err := makeReq(to, http.MethodPost, apiBase+`/federations/`+strconv.Itoa(federationID)+`/deliveryservices`, jsonReq, &resp)
+	return inf, err
+}
diff --git a/traffic_ops/testing/api/v13/federations_test.go b/traffic_ops/testing/api/v13/federations_test.go
new file mode 100644
index 0000000..1473f27
--- /dev/null
+++ b/traffic_ops/testing/api/v13/federations_test.go
@@ -0,0 +1,145 @@
+package v13
+
+/*
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+import (
+	"testing"
+
+	"github.com/apache/trafficcontrol/lib/go-log"
+)
+
+func TestFederations(t *testing.T) {
+	CreateTestCDNs(t)
+	CreateTestTypes(t)
+	CreateTestProfiles(t)
+	CreateTestStatuses(t)
+	CreateTestDivisions(t)
+	CreateTestRegions(t)
+	CreateTestPhysLocations(t)
+	CreateTestCacheGroups(t)
+	CreateTestDeliveryServices(t)
+	CreateTestUsersDeliveryServices(t)
+	CreateTestCDNFederations(t)
+	// UpdateTestCDNFederations(t)
+	// GetTestCDNFederations(t)
+
+	PostTestFederationsDeliveryServices(t)
+	GetTestFederations(t)
+	DeleteTestFederationsDeliveryServices(t)
+
+	DeleteTestCDNFederations(t)
+	DeleteTestUsersDeliveryServices(t)
+	DeleteTestDeliveryServices(t)
+	DeleteTestCacheGroups(t)
+	DeleteTestPhysLocations(t)
+	DeleteTestRegions(t)
+	DeleteTestDivisions(t)
+	DeleteTestStatuses(t)
+	DeleteTestProfiles(t)
+	DeleteTestTypes(t)
+	DeleteTestCDNs(t)
+}
+
+func GetTestFederations(t *testing.T) {
+	log.Debugln("GetTestFederations")
+
+	if len(testData.Federations) == 0 {
+		t.Fatalf("no federations test data")
+	}
+
+	feds, _, err := TOSession.AllFederations()
+	if err != nil {
+		t.Fatalf("getting federations: " + err.Error())
+	}
+
+	if len(feds) != 1 {
+		t.Fatalf("federations expected 1, actual: %+v", len(feds))
+	}
+	fed := feds[0]
+
+	if len(fed.Mappings) < 1 {
+		t.Fatalf("federation mappings expected <0, actual: 0")
+	}
+
+	mapping := fed.Mappings[0]
+	if mapping.CName == nil {
+		t.Fatalf("federation mapping expected cname, actual: nil")
+	}
+	if mapping.TTL == nil {
+		t.Fatalf("federation mapping expected ttl, actual: nil")
+	}
+
+	matched := false
+	for _, testFed := range testData.Federations {
+		if testFed.CName == nil {
+			t.Fatalf("test federation missing cname!")
+		}
+		if testFed.TTL == nil {
+			t.Fatalf("test federation missing ttl!")
+		}
+
+		if *mapping.CName != *testFed.CName {
+			continue
+		}
+		matched = true
+
+		if *mapping.TTL != *testFed.TTL {
+			t.Fatalf("federation mapping ttl expected: %v, actual: %v", *testFed.TTL, *mapping.TTL)
+		}
+	}
+	if !matched {
+		t.Fatalf("federation mapping expected to match test data, actual: cname %v not in test data", *mapping.CName)
+	}
+
+	log.Debugln("GetTestFederations PASSED")
+}
+
+func PostTestFederationsDeliveryServices(t *testing.T) {
+	log.Debugln("PostTestFederationsDeliveryServices")
+	dses, _, err := TOSession.GetDeliveryServices()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServices: %v - %v\n", err, dses)
+	}
+	if len(dses) == 0 {
+		t.Fatalf("no delivery services, must have at least 1 ds to test federations deliveryservices\n")
+	}
+	ds := dses[0]
+	if len(fedIDs) == 0 {
+		t.Fatalf("no federations, must have at least 1 federation to test federations deliveryservices\n")
+	}
+	fedID := fedIDs[0]
+
+	if _, err = TOSession.CreateFederationDeliveryServices(fedID, []int{ds.ID}, true); err != nil {
+		t.Fatalf("creating federations delivery services: %v\n", err)
+	}
+	log.Debugln("PostTestFederationsDeliveryServices PASSED")
+}
+
+func DeleteTestFederationsDeliveryServices(t *testing.T) {
+	log.Debugln("DeleteTestFederationsDeliveryServices")
+	// doesn't actually call a DELETE method; this exists primarily to clean up PostTestFederationsDeliveryServices
+
+	if len(fedIDs) == 0 {
+		t.Fatalf("no federations, must have at least 1 federation to test federations deliveryservices\n")
+	}
+	fedID := fedIDs[0]
+
+	_, err := TOSession.CreateFederationDeliveryServices(fedID, nil, true)
+	if err != nil {
+		t.Fatalf("creating (deleting) federations delivery services: %v\n", err)
+	}
+	log.Debugln("DeleteTestFederationsDeliveryServices PASSED")
+}
diff --git a/traffic_ops/testing/api/v14/cdnfederations_test.go b/traffic_ops/testing/api/v14/cdnfederations_test.go
index 662e01c..970f4e4 100644
--- a/traffic_ops/testing/api/v14/cdnfederations_test.go
+++ b/traffic_ops/testing/api/v14/cdnfederations_test.go
@@ -128,4 +128,5 @@ func DeleteTestCDNFederations(t *testing.T) {
 			t.Errorf("expected federation to be deleted")
 		}
 	}
+	fedIDs = nil // reset the global variable for the next test
 }
diff --git a/traffic_ops/traffic_ops_golang/federations/ds.go b/traffic_ops/traffic_ops_golang/federations/ds.go
index 6619af9..7ab0628 100644
--- a/traffic_ops/traffic_ops_golang/federations/ds.go
+++ b/traffic_ops/traffic_ops_golang/federations/ds.go
@@ -55,10 +55,13 @@ func PostDSes(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
-	if err := insertDSFeds(inf.Tx.Tx, fedID, post.DSIDs); err != nil {
-		userErr, sysErr, errCode := api.ParseDBError(err)
-		api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
-		return
+	if len(post.DSIDs) > 0 {
+		// there might be no DSes, if the user is trying to clear the assignments
+		if err := insertDSFeds(inf.Tx.Tx, fedID, post.DSIDs); err != nil {
+			userErr, sysErr, errCode := api.ParseDBError(err)
+			api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
+			return
+		}
 	}
 
 	api.WriteRespAlertObj(w, r, tc.SuccessLevel, strconv.Itoa(len(post.DSIDs))+" delivery service(s) were assigned to the federation "+strconv.Itoa(fedID), post)
diff --git a/traffic_ops/traffic_ops_golang/federations/federations.go b/traffic_ops/traffic_ops_golang/federations/federations.go
index 048c432..29c9a60 100644
--- a/traffic_ops/traffic_ops_golang/federations/federations.go
+++ b/traffic_ops/traffic_ops_golang/federations/federations.go
@@ -40,7 +40,6 @@ func Get(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	allFederations := []tc.IAllFederation{}
 	feds, err := getUserFederations(inf.Tx.Tx, inf.User)
 	if err != nil {
 		api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("federations.Get getting federations: "+err.Error()))
@@ -51,7 +50,7 @@ func Get(w http.ResponseWriter, r *http.Request) {
 		api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("federations.Get getting federations resolvers: "+err.Error()))
 		return
 	}
-	allFederations = addResolvers(allFederations, feds, fedsResolvers)
+	allFederations := addResolvers([]tc.IAllFederation{}, feds, fedsResolvers)
 	api.WriteResp(w, r, allFederations)
 }