You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by de...@apache.org on 2018/09/13 19:54:44 UTC

[trafficcontrol] 02/03: Add TO Go cachegroups/dses API test, client funcs

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

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

commit 130baa85b122f2827621c98f9e87b3245e18d80b
Author: Robert Butts <ro...@apache.org>
AuthorDate: Thu Jun 28 08:18:42 2018 -0600

    Add TO Go cachegroups/dses API test, client funcs
---
 lib/go-tc/deliveryservices.go                      |  15 +++
 traffic_ops/client/asn.go                          |  32 +++++
 traffic_ops/client/coordinate.go                   |  23 ++++
 traffic_ops/client/deliveryserviceserver.go        |  23 ----
 .../api/v13/cachegroupsdeliveryservices_test.go    | 141 +++++++++++++++++++++
 .../testing/api/v13/deliveryserviceservers_test.go |   6 +-
 .../traffic_ops_golang/cachegroup/dspost.go        |  33 ++---
 7 files changed, 226 insertions(+), 47 deletions(-)

diff --git a/lib/go-tc/deliveryservices.go b/lib/go-tc/deliveryservices.go
index b92d549..effa711 100644
--- a/lib/go-tc/deliveryservices.go
+++ b/lib/go-tc/deliveryservices.go
@@ -559,6 +559,21 @@ type DSServerIDs struct {
 	Replace           *bool `json:"replace"`
 }
 
+type CachegroupPostDSReq struct {
+	DeliveryServices []int64 `json:"deliveryServices"`
+}
+
+type CacheGroupPostDSResp struct {
+	ID               util.JSONIntStr `json:"id"`
+	ServerNames      []CacheName     `json:"serverNames"`
+	DeliveryServices []int64         `json:"deliveryServices"`
+}
+
+type CacheGroupPostDSRespResponse struct {
+	Alerts
+	Response CacheGroupPostDSResp `json:"response"`
+}
+
 type AssignedDsResponse struct {
 	ServerID int   `json:"serverId"`
 	DSIds    []int `json:"dsIds"`
diff --git a/traffic_ops/client/asn.go b/traffic_ops/client/asn.go
index 2a38c65..89204c7 100644
--- a/traffic_ops/client/asn.go
+++ b/traffic_ops/client/asn.go
@@ -17,9 +17,11 @@ package client
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"net"
 	"net/http"
+	"strconv"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 )
@@ -130,3 +132,33 @@ func (to *Session) DeleteASNByASN(asn int) (tc.Alerts, ReqInf, error) {
 	err = json.NewDecoder(resp.Body).Decode(&alerts)
 	return alerts, reqInf, nil
 }
+
+func (to *Session) DeleteDeliveryServiceServer(dsID int, serverID int) (tc.Alerts, ReqInf, error) {
+	route := apiBase + `/deliveryservice_server/` + strconv.Itoa(dsID) + "/" + strconv.Itoa(serverID)
+	reqResp, remoteAddr, err := to.request(http.MethodDelete, route, nil)
+	reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: remoteAddr}
+	if err != nil {
+		return tc.Alerts{}, reqInf, errors.New("requesting from Traffic Ops: " + err.Error())
+	}
+	defer reqResp.Body.Close()
+	resp := tc.Alerts{}
+	if err = json.NewDecoder(reqResp.Body).Decode(&resp); err != nil {
+		return tc.Alerts{}, reqInf, errors.New("decoding response: " + err.Error())
+	}
+	return resp, reqInf, nil
+}
+
+func (to *Session) GetDeliveryServiceServers() (tc.DeliveryServiceServerResponse, ReqInf, error) {
+	route := apiBase + `/deliveryserviceserver`
+	reqResp, remoteAddr, err := to.request(http.MethodGet, route, nil)
+	reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss, RemoteAddr: remoteAddr}
+	if err != nil {
+		return tc.DeliveryServiceServerResponse{}, reqInf, errors.New("requesting from Traffic Ops: " + err.Error())
+	}
+	defer reqResp.Body.Close()
+	resp := tc.DeliveryServiceServerResponse{}
+	if err = json.NewDecoder(reqResp.Body).Decode(&resp); err != nil {
+		return tc.DeliveryServiceServerResponse{}, reqInf, errors.New("decoding response: " + err.Error())
+	}
+	return resp, reqInf, nil
+}
diff --git a/traffic_ops/client/coordinate.go b/traffic_ops/client/coordinate.go
index 57b051c..ab209bd 100644
--- a/traffic_ops/client/coordinate.go
+++ b/traffic_ops/client/coordinate.go
@@ -17,9 +17,11 @@ package client
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"net"
 	"net/http"
+	"strconv"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 )
@@ -130,3 +132,24 @@ func (to *Session) DeleteCoordinateByID(id int) (tc.Alerts, ReqInf, error) {
 	err = json.NewDecoder(resp.Body).Decode(&alerts)
 	return alerts, reqInf, nil
 }
+
+func (to *Session) SetCachegroupDeliveryServices(cgID int, dsIDs []int64) (tc.CacheGroupPostDSRespResponse, ReqInf, error) {
+	uri := apiBase + `/cachegroups/` + strconv.Itoa(cgID) + `/deliveryservices`
+	req := tc.CachegroupPostDSReq{DeliveryServices: dsIDs}
+	reqBody, err := json.Marshal(req)
+	reqInf := ReqInf{CacheHitStatus: CacheHitStatusMiss}
+	if err != nil {
+		return tc.CacheGroupPostDSRespResponse{}, reqInf, err
+	}
+	reqResp, _, err := to.request(http.MethodPost, uri, reqBody)
+	if err != nil {
+		return tc.CacheGroupPostDSRespResponse{}, reqInf, errors.New("requesting from Traffic Ops: " + err.Error())
+	}
+	defer reqResp.Body.Close()
+
+	resp := tc.CacheGroupPostDSRespResponse{}
+	if err := json.NewDecoder(reqResp.Body).Decode(&resp); err != nil {
+		return tc.CacheGroupPostDSRespResponse{}, reqInf, errors.New("decoding response: " + err.Error())
+	}
+	return resp, reqInf, nil
+}
diff --git a/traffic_ops/client/deliveryserviceserver.go b/traffic_ops/client/deliveryserviceserver.go
index 7f30d9b..4e618ea 100644
--- a/traffic_ops/client/deliveryserviceserver.go
+++ b/traffic_ops/client/deliveryserviceserver.go
@@ -17,23 +17,11 @@ package client
 
 import (
 	"encoding/json"
-	"strconv"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-util"
 )
 
-func (to *Session) GetDeliveryServiceServers() ([]tc.DeliveryServiceServer, ReqInf, error) {
-	path := apiBase + `/deliveryserviceserver`
-	// deliveryService
-	resp := tc.DeliveryServiceServerResponse{}
-	reqInf, err := get(to, path, &resp)
-	if err != nil {
-		return nil, reqInf, err
-	}
-	return resp.Response, reqInf, nil
-}
-
 // CreateDeliveryServiceServers associates the given servers with the given delivery services. If replace is true, it deletes any existing associations for the given delivery service.
 func (to *Session) CreateDeliveryServiceServers(dsID int, serverIDs []int, replace bool) (*tc.DSServerIDs, error) {
 	path := apiBase + `/deliveryserviceserver`
@@ -54,14 +42,3 @@ func (to *Session) CreateDeliveryServiceServers(dsID int, serverIDs []int, repla
 	}
 	return &resp.Response, nil
 }
-
-// DeleteDeliveryService deletes the given delivery service server association.
-func (to *Session) DeleteDeliveryServiceServer(dsID int, serverID int) error {
-	path := apiBase + `/deliveryservice_server/` + strconv.Itoa(dsID) + `/` + strconv.Itoa(serverID)
-	resp := struct{ tc.Alerts }{}
-	err := del(to, path, &resp)
-	if err != nil {
-		return err
-	}
-	return nil
-}
diff --git a/traffic_ops/testing/api/v13/cachegroupsdeliveryservices_test.go b/traffic_ops/testing/api/v13/cachegroupsdeliveryservices_test.go
new file mode 100644
index 0000000..10abfee
--- /dev/null
+++ b/traffic_ops/testing/api/v13/cachegroupsdeliveryservices_test.go
@@ -0,0 +1,141 @@
+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 (
+	"github.com/apache/trafficcontrol/lib/go-log"
+	"testing"
+)
+
+func TestDeliveryServicesCachegroups(t *testing.T) {
+	CreateTestCDNs(t)
+	CreateTestTypes(t)
+	CreateTestProfiles(t)
+	CreateTestStatuses(t)
+	CreateTestDivisions(t)
+	CreateTestRegions(t)
+	CreateTestPhysLocations(t)
+	CreateTestCacheGroups(t)
+	CreateTestServers(t)
+	CreateTestDeliveryServices(t)
+
+	CreateTestCachegroupsDeliveryServices(t)
+	DeleteTestCachegroupsDeliveryServices(t)
+
+	DeleteTestDeliveryServices(t)
+	DeleteTestServers(t)
+	DeleteTestCacheGroups(t)
+	DeleteTestPhysLocations(t)
+	DeleteTestRegions(t)
+	DeleteTestDivisions(t)
+	DeleteTestStatuses(t)
+	DeleteTestProfiles(t)
+	DeleteTestTypes(t)
+	DeleteTestCDNs(t)
+}
+
+const TestEdgeServerCacheGroupName = "cachegroup1" // TODO this is the name hard-coded in the create servers test; change to be dynamic
+
+func CreateTestCachegroupsDeliveryServices(t *testing.T) {
+	log.Debugln("CreateTestCachegroupsDeliveryServices")
+
+	dss, _, err := TOSession.GetDeliveryServiceServers()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServiceServers: %v\n", err)
+	}
+	if len(dss.Response) > 0 {
+		t.Fatalf("cannot test cachegroups delivery services: expected no initial delivery service servers, actual %v\n", len(dss.Response))
+	}
+
+	dses, _, err := TOSession.GetDeliveryServices()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServices: %v - %v\n", err, dses)
+	}
+
+	clientCGs, _, err := TOSession.GetCacheGroupByName(TestEdgeServerCacheGroupName)
+	if err != nil {
+		t.Fatalf("getting cachegroup: " + err.Error() + "\n")
+	}
+	if len(clientCGs) != 1 {
+		t.Fatalf("getting cachegroup expected 1, got %v\n", len(clientCGs))
+	}
+	clientCG := clientCGs[0]
+
+	cgID := clientCG.ID
+
+	dsIDs := []int64{}
+	for _, ds := range dses {
+		dsIDs = append(dsIDs, int64(ds.ID))
+	}
+
+	resp, _, err := TOSession.SetCachegroupDeliveryServices(cgID, dsIDs)
+	if err != nil {
+		t.Fatalf("setting cachegroup delivery services returned error: %v\n", err)
+	}
+	if len(resp.Response.ServerNames) == 0 {
+		t.Fatalf("setting cachegroup delivery services returned success, but no servers set\n")
+	}
+
+	for _, serverName := range resp.Response.ServerNames {
+		servers, _, err := TOSession.GetServerByHostName(string(serverName))
+		if err != nil {
+			t.Fatalf("getting server: " + err.Error())
+		}
+		if len(servers) != 1 {
+			t.Fatalf("getting servers: expected 1 got %v\n", len(servers))
+		}
+		server := servers[0]
+		serverID := server.ID
+
+		serverDSes, _, err := TOSession.GetDeliveryServicesByServer(serverID)
+
+		for _, dsID := range dsIDs {
+			found := false
+			for _, serverDS := range serverDSes {
+				if serverDS.ID == int(dsID) {
+					found = true
+					break
+				}
+			}
+			if !found {
+				t.Fatalf("post succeeded, but didn't assign delivery service %v to server\n", dsID)
+			}
+		}
+	}
+}
+
+func DeleteTestCachegroupsDeliveryServices(t *testing.T) {
+	log.Debugln("DeleteTestCachegroupsDeliveryServices")
+
+	dss, _, err := TOSession.GetDeliveryServiceServers()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServiceServers: %v\n", err)
+	}
+	for _, ds := range dss.Response {
+		_, _, err := TOSession.DeleteDeliveryServiceServer(*ds.DeliveryService, *ds.Server)
+		if err != nil {
+			t.Fatalf("deleting delivery service servers: " + err.Error() + "\n")
+		}
+	}
+
+	dss, _, err = TOSession.GetDeliveryServiceServers()
+	if err != nil {
+		t.Fatalf("cannot GET DeliveryServiceServers: %v\n", err)
+	}
+	if len(dss.Response) > 0 {
+		t.Fatalf("deleting delivery service servers: delete succeeded, expected empty subsequent get, actual %v\n", len(dss.Response))
+	}
+}
diff --git a/traffic_ops/testing/api/v13/deliveryserviceservers_test.go b/traffic_ops/testing/api/v13/deliveryserviceservers_test.go
index 2c60ae1..99e61ac 100644
--- a/traffic_ops/testing/api/v13/deliveryserviceservers_test.go
+++ b/traffic_ops/testing/api/v13/deliveryserviceservers_test.go
@@ -79,7 +79,7 @@ func DeleteTestDeliveryServiceServers(t *testing.T) {
 	}
 
 	found := false
-	for _, dss := range dsServers {
+	for _, dss := range dsServers.Response {
 		if *dss.DeliveryService == ds.ID && *dss.Server == server.ID {
 			found = true
 			break
@@ -89,7 +89,7 @@ func DeleteTestDeliveryServiceServers(t *testing.T) {
 		t.Fatalf("POST delivery service servers returned success, but ds-server not in GET")
 	}
 
-	if err := TOSession.DeleteDeliveryServiceServer(ds.ID, server.ID); err != nil {
+	if _, _, err := TOSession.DeleteDeliveryServiceServer(ds.ID, server.ID); err != nil {
 		t.Fatalf("DELETE delivery service server: %v\n", err)
 	}
 
@@ -99,7 +99,7 @@ func DeleteTestDeliveryServiceServers(t *testing.T) {
 	}
 
 	found = false
-	for _, dss := range dsServers {
+	for _, dss := range dsServers.Response {
 		if *dss.DeliveryService == ds.ID && *dss.Server == server.ID {
 			found = true
 			break
diff --git a/traffic_ops/traffic_ops_golang/cachegroup/dspost.go b/traffic_ops/traffic_ops_golang/cachegroup/dspost.go
index 01ac0e9..8ec3dee 100644
--- a/traffic_ops/traffic_ops_golang/cachegroup/dspost.go
+++ b/traffic_ops/traffic_ops_golang/cachegroup/dspost.go
@@ -28,6 +28,7 @@ import (
 	"strconv"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
@@ -35,10 +36,6 @@ import (
 	"github.com/lib/pq"
 )
 
-type CachegroupPostDSReq struct {
-	DeliveryServices []int64 `json:"deliveryServices"`
-}
-
 func DSPostHandler(w http.ResponseWriter, r *http.Request) {
 	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"})
 	if userErr != nil || sysErr != nil {
@@ -47,7 +44,7 @@ func DSPostHandler(w http.ResponseWriter, r *http.Request) {
 	}
 	defer inf.Close()
 
-	req := CachegroupPostDSReq{}
+	req := tc.CachegroupPostDSReq{}
 	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
 		api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, errors.New("malformed JSON: "+err.Error()), nil)
 		return
@@ -58,48 +55,42 @@ func DSPostHandler(w http.ResponseWriter, r *http.Request) {
 	api.RespWriterVals(w, r, inf.Tx.Tx, vals)(postDSes(inf.Tx.Tx, inf.User, int64(inf.IntParams["id"]), req.DeliveryServices))
 }
 
-type CacheGroupPostDSResp struct {
-	ID               int64          `json:"id"`
-	ServerNames      []tc.CacheName `json:"serverNames"`
-	DeliveryServices []int64        `json:"deliveryServices"`
-}
-
-func postDSes(tx *sql.Tx, user *auth.CurrentUser, cgID int64, dsIDs []int64) (CacheGroupPostDSResp, error) {
+func postDSes(tx *sql.Tx, user *auth.CurrentUser, cgID int64, dsIDs []int64) (tc.CacheGroupPostDSResp, error) {
 	cdnName, err := getCachegroupCDN(tx, cgID)
 	if err != nil {
-		return CacheGroupPostDSResp{}, errors.New("getting cachegroup CDN: " + err.Error())
+		return tc.CacheGroupPostDSResp{}, errors.New("getting cachegroup CDN: " + err.Error())
 	}
 
 	tenantIDs, err := getDSTenants(tx, dsIDs)
 	if err != nil {
-		return CacheGroupPostDSResp{}, errors.New("getting delivery service tennat IDs: " + err.Error())
+		return tc.CacheGroupPostDSResp{}, errors.New("getting delivery service tennat IDs: " + err.Error())
 	}
 	for _, tenantID := range tenantIDs {
 		ok, err := tenant.IsResourceAuthorizedToUserTx(int(tenantID), user, tx)
 		if err != nil {
-			return CacheGroupPostDSResp{}, errors.New("checking tenancy: " + err.Error())
+			return tc.CacheGroupPostDSResp{}, errors.New("checking tenancy: " + err.Error())
 		}
 		if !ok {
-			return CacheGroupPostDSResp{}, errors.New("not authorized for delivery service tenant " + strconv.FormatInt(tenantID, 10))
+			return tc.CacheGroupPostDSResp{}, errors.New("not authorized for delivery service tenant " + strconv.FormatInt(tenantID, 10))
 		}
 	}
 
 	if err := verifyDSesCDN(tx, dsIDs, cdnName); err != nil {
-		return CacheGroupPostDSResp{}, errors.New("verifying delivery service CDNs match cachegroup server CDNs: " + err.Error())
+		return tc.CacheGroupPostDSResp{}, errors.New("verifying delivery service CDNs match cachegroup server CDNs: " + err.Error())
 	}
 	cgServers, err := getCachegroupServers(tx, cgID)
 	if err != nil {
-		return CacheGroupPostDSResp{}, errors.New("getting cachegroup server names " + err.Error())
+		return tc.CacheGroupPostDSResp{}, errors.New("getting cachegroup server names " + err.Error())
 	}
 	if err := insertCachegroupDSes(tx, cgID, dsIDs); err != nil {
-		return CacheGroupPostDSResp{}, errors.New("inserting cachegroup delivery services: " + err.Error())
+		return tc.CacheGroupPostDSResp{}, errors.New("inserting cachegroup delivery services: " + err.Error())
 	}
 
 	if err := updateParams(tx, dsIDs); err != nil {
-		return CacheGroupPostDSResp{}, errors.New("updating delivery service parameters: " + err.Error())
+		return tc.CacheGroupPostDSResp{}, errors.New("updating delivery service parameters: " + err.Error())
 	}
 	api.CreateChangeLogRawTx(api.ApiChange, fmt.Sprintf("assign servers in cache group %v to deliveryservices %v", cgID, dsIDs), user, tx)
-	return CacheGroupPostDSResp{ID: cgID, ServerNames: cgServers, DeliveryServices: dsIDs}, nil
+	return tc.CacheGroupPostDSResp{ID: util.JSONIntStr(cgID), ServerNames: cgServers, DeliveryServices: dsIDs}, nil
 }
 
 func insertCachegroupDSes(tx *sql.Tx, cgID int64, dsIDs []int64) error {