You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2017/01/10 03:38:21 UTC

[09/50] incubator-trafficcontrol git commit: initial commit of integration tests

initial commit of integration tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/3fa2b81e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/3fa2b81e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/3fa2b81e

Branch: refs/heads/master
Commit: 3fa2b81e3231dafc11662c7c5d094e6a19e65f6f
Parents: 5b40c9a
Author: David Neuman <da...@gmail.com>
Authored: Tue Nov 29 15:42:37 2016 -0700
Committer: Dan Kirkwood <da...@gmail.com>
Committed: Sun Jan 8 21:04:59 2017 -0700

----------------------------------------------------------------------
 .../client/tests/integration/cachegroup_test.go |  68 +++++
 .../client/tests/integration/cdn_test.go        |  91 +++++++
 .../client/tests/integration/crconfig_test.go   |  25 ++
 .../tests/integration/deliveryservice_test.go   | 267 +++++++++++++++++++
 .../tests/integration/integration_helper.go     |  89 +++++++
 5 files changed, 540 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3fa2b81e/traffic_ops/client/tests/integration/cachegroup_test.go
----------------------------------------------------------------------
diff --git a/traffic_ops/client/tests/integration/cachegroup_test.go b/traffic_ops/client/tests/integration/cachegroup_test.go
new file mode 100644
index 0000000..fbf19a5
--- /dev/null
+++ b/traffic_ops/client/tests/integration/cachegroup_test.go
@@ -0,0 +1,68 @@
+package integration
+
+import (
+	"encoding/json"
+	"testing"
+
+	traffic_ops "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+//TestCachegroupResults compares the results of the Cachegroup api and Cachegroup client
+func TestCachegroups(t *testing.T) {
+	//Get Cachegroups Data from API
+	resp, err := Request(*to, "GET", "/api/1.2/cachegroups.json", nil)
+	if err != nil {
+		t.Errorf("Could not get cachegroups.json reponse was: %v\n", err)
+	}
+
+	defer resp.Body.Close()
+	var apiCgRes traffic_ops.CacheGroupResponse
+	if err := json.NewDecoder(resp.Body).Decode(&apiCgRes); err != nil {
+		t.Errorf("Could not decode Cachegroup json.  Error is: %v\n", err)
+	}
+	apiCgs := apiCgRes.Response
+
+	clientCgs, err := to.CacheGroups()
+	if err != nil {
+		t.Errorf("Could not get Cachegroups from client.  Error is: %v\n", err)
+	}
+
+	if len(apiCgs) != len(clientCgs) {
+		t.Errorf("Array lengths from client and API are different...API = %d, Client = %d\n", len(apiCgs), len(clientCgs))
+	}
+
+	matchFound := false
+	for _, apiCg := range apiCgs {
+		for _, clientCg := range clientCgs {
+			if clientCg.Name != apiCg.Name {
+				continue
+			}
+			matchFound = true
+			//compare API results and client results
+			if apiCg.Name != clientCg.Name {
+				t.Errorf("Cachegroup Name from client and API are different...API = %s, Client = %s\n", apiCg.Name, clientCg.Name)
+			}
+			if apiCg.ShortName != clientCg.ShortName {
+				t.Errorf("Cachegroup ShortName from client and API are different...API = %s, Client = %s\n", apiCg.ShortName, clientCg.ShortName)
+			}
+			if apiCg.LastUpdated != clientCg.LastUpdated {
+				t.Errorf("Cachegroup Last Updated from client and API are different...API = %s, Client = %s\n", apiCg.Name, clientCg.Name)
+			}
+			if apiCg.Latitude != clientCg.Latitude {
+				t.Errorf("Cachegroup Latitude from client and API are different...API = %f, Client = %f\n", apiCg.Latitude, clientCg.Latitude)
+			}
+			if apiCg.Longitude != clientCg.Longitude {
+				t.Errorf("Cachegroup Longitude from client and API are different...API = %f, Client = %f\n", apiCg.Longitude, clientCg.Longitude)
+			}
+			if apiCg.ParentName != clientCg.ParentName {
+				t.Errorf("Cachegroup ParentName from client and API are different...API = %s, Client = %s\n", apiCg.ParentName, clientCg.ParentName)
+			}
+			if apiCg.Type != clientCg.Type {
+				t.Errorf("Cachegroup Type from client and API are different...API = %s, Client = %s\n", apiCg.Type, clientCg.Type)
+			}
+		}
+		if !matchFound {
+			t.Errorf("A match for %s from the API was not found in the client results\n", apiCg.Name)
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3fa2b81e/traffic_ops/client/tests/integration/cdn_test.go
----------------------------------------------------------------------
diff --git a/traffic_ops/client/tests/integration/cdn_test.go b/traffic_ops/client/tests/integration/cdn_test.go
new file mode 100644
index 0000000..04ad768
--- /dev/null
+++ b/traffic_ops/client/tests/integration/cdn_test.go
@@ -0,0 +1,91 @@
+package integration
+
+import (
+	"encoding/json"
+	"testing"
+
+	traffic_ops "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+//TestCDNs compares the results of the CDN api and CDN client
+func TestCDNs(t *testing.T) {
+	//Get CDNs Data from API
+	resp, err := Request(*to, "GET", "/api/1.2/cdns.json", nil)
+	if err != nil {
+		t.Errorf("Could not get cdns.json reponse was: %v\n", err)
+	}
+
+	defer resp.Body.Close()
+	var apiCDNRes traffic_ops.CDNResponse
+	if err := json.NewDecoder(resp.Body).Decode(&apiCDNRes); err != nil {
+		t.Errorf("Could not decode CDN json.  Error is: %v\n", err)
+	}
+	apiCDNs := apiCDNRes.Response
+
+	//get CDNs data from client
+	clientCDNs, err := to.CDNs()
+	if err != nil {
+		t.Errorf("Could not get CDNs from client.  Error is: %v\n", err)
+	}
+
+	if len(apiCDNs) != len(clientCDNs) {
+		t.Errorf("Array lengths from client and API are different...API = %s, Client = %s\n", apiCDNs, clientCDNs)
+	}
+
+	matchFound := false
+	for _, apiCDN := range apiCDNs {
+		for _, clientCDN := range clientCDNs {
+			if clientCDN.Name != apiCDN.Name {
+				continue
+			}
+			matchFound = true
+			//compare API results and client results
+			if apiCDN.Name != clientCDN.Name {
+				t.Errorf("CDN Name from client and API are different...API = %s, Client = %s\n", apiCDN.Name, clientCDN.Name)
+			}
+			if apiCDN.LastUpdated != clientCDN.LastUpdated {
+				t.Errorf("CDN Last Updated from client and API are different...API = %s, Client = %s\n", apiCDN.Name, clientCDN.Name)
+			}
+		}
+		if !matchFound {
+			t.Errorf("A match for %s from the API was not found in the client results\n", apiCDN.Name)
+		}
+	}
+}
+
+//TestCDNName ensures the client returns a CDN by name
+func TestCDNName(t *testing.T) {
+	//Get CDNs Data from API
+	resp, err := Request(*to, "GET", "/api/1.2/cdns.json", nil)
+	if err != nil {
+		t.Errorf("Could not get cdns.json reponse was: %v\n", err)
+	}
+
+	defer resp.Body.Close()
+	var apiCDNRes traffic_ops.CDNResponse
+	if err := json.NewDecoder(resp.Body).Decode(&apiCDNRes); err != nil {
+		t.Errorf("Could not decode CDN json.  Error is: %v\n", err)
+	}
+
+	apiCDNs := apiCDNRes.Response
+	apiName := apiCDNs[0].Name
+	apiLastUpdated := apiCDNs[0].LastUpdated
+
+	//get CDNs data from client
+	clientCDN, err := to.CDNName(apiName)
+
+	if len(clientCDN) != 1 {
+		t.Errorf("The length of the client CDN response %v is greater than 1!\n", len(apiCDNs))
+	}
+
+	clientName := clientCDN[0].Name
+	clientLastUpdated := clientCDN[0].LastUpdated
+
+	//compare API results and client results
+	if apiName != clientName {
+		t.Errorf("CDN Name from client and API are different...API = %s, Client = %s\n", apiName, clientName)
+	}
+	if apiLastUpdated != clientLastUpdated {
+		t.Errorf("CDN Last Updated from client and API are different...API = %s, Client = %s\n", apiName, clientName)
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3fa2b81e/traffic_ops/client/tests/integration/crconfig_test.go
----------------------------------------------------------------------
diff --git a/traffic_ops/client/tests/integration/crconfig_test.go b/traffic_ops/client/tests/integration/crconfig_test.go
new file mode 100644
index 0000000..7f404f7
--- /dev/null
+++ b/traffic_ops/client/tests/integration/crconfig_test.go
@@ -0,0 +1,25 @@
+package integration
+
+import "testing"
+
+//TestCachegroupResults compares the results of the Cachegroup api and Cachegroup client
+func TestGetCrConfig(t *testing.T) {
+	//Get a CDN from the to client
+	cdn, err := GetCdn()
+	if err != nil {
+		t.Errorf("TestGetCrConfig -- Could not get CDNs from TO...%v\n", err)
+	}
+
+	crConfig, cacheHitStatus, err := to.GetCRConfig(cdn.Name)
+	if err != nil {
+		t.Errorf("Could not get CrConfig for %s.  Error is...%v\n", cdn.Name, err)
+	}
+
+	if cacheHitStatus == "" {
+		t.Error("cacheHitStatus is empty...")
+	}
+
+	if len(crConfig) == 0 {
+		t.Error("Raw CrConfig reponse was 0...")
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3fa2b81e/traffic_ops/client/tests/integration/deliveryservice_test.go
----------------------------------------------------------------------
diff --git a/traffic_ops/client/tests/integration/deliveryservice_test.go b/traffic_ops/client/tests/integration/deliveryservice_test.go
new file mode 100644
index 0000000..c224cdf
--- /dev/null
+++ b/traffic_ops/client/tests/integration/deliveryservice_test.go
@@ -0,0 +1,267 @@
+package integration
+
+import (
+	"encoding/json"
+	"strconv"
+	"testing"
+	"time"
+
+	traffic_ops "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+// TestDeliveryServices compares the results of the Deliveryservices api and Deliveryservices client
+func TestDeliveryServices(t *testing.T) {
+	resp, err := Request(*to, "GET", "/api/1.2/deliveryservices.json", nil)
+	if err != nil {
+		t.Errorf("Could not get deliveryservices.json reponse was: %v\n", err)
+	}
+
+	defer resp.Body.Close()
+	var apiDsRes traffic_ops.GetDeliveryServiceResponse
+	if err := json.NewDecoder(resp.Body).Decode(&apiDsRes); err != nil {
+		t.Errorf("Could not decode Deliveryservice json.  Error is: %v\n", err)
+	}
+	apiDss := apiDsRes.Response
+
+	clientDss, err := to.DeliveryServices()
+	if err != nil {
+		t.Errorf("Could not get Deliveryservices from client.  Error is: %v\n", err)
+	}
+
+	if len(apiDss) != len(clientDss) {
+		t.Errorf("Array lengths from client and API are different...API = %v, Client = %v\n", apiDss, clientDss)
+	}
+
+	matchFound := false
+	for _, apiDs := range apiDss {
+		for _, clientDs := range clientDss {
+			if clientDs.XMLID != apiDs.XMLID {
+				continue
+			}
+			matchFound = true
+			compareDs(apiDs, clientDs, t)
+		}
+		if !matchFound {
+			t.Errorf("A match for %s from the API was not found in the client results\n", apiDs.XMLID)
+		}
+	}
+}
+
+var testDsID string
+
+func TestCreateDs(t *testing.T) {
+	//create a DS and validate response
+	cdn, err := GetCdn()
+	if err != nil {
+		t.Errorf("TestCreateDs -- Could not get CDNs from TO...%v\n", err)
+	}
+
+	profile, err := GetProfile()
+	if err != nil {
+		t.Errorf("TestCreateDs -- Could not get Profiles from TO...%v\n", err)
+	}
+
+	newDs := new(traffic_ops.DeliveryService)
+	newDs.Active = false
+	newDs.CCRDNSTTL = 30
+	newDs.CDNName = cdn.Name
+	newDs.CacheURL = "cacheURL"
+	newDs.CheckPath = "CheckPath"
+	newDs.DNSBypassCname = "DNSBypassCNAME"
+	newDs.DNSBypassIP = "10.10.10.10"
+	newDs.DNSBypassIP6 = "FF01:0:0:0:0:0:0:FB"
+	newDs.DNSBypassTTL = 30
+	newDs.DSCP = 0
+	newDs.DisplayName = "DisplayName"
+	newDs.EdgeHeaderRewrite = "EdgeHeaderRewrite"
+	newDs.GeoLimit = 5
+	newDs.GeoProvider = 1
+	newDs.GlobalMaxMBPS = 15000
+	newDs.GlobalMaxTPS = 15000
+	newDs.HTTPBypassFQDN = "HTTPBypassFQDN"
+	newDs.IPV6RoutingEnabled = true
+	newDs.InfoURL = "InfoUrl"
+	newDs.InitialDispersion = 5
+	newDs.LongDesc = "LongDesc"
+	newDs.LongDesc1 = "LongDesc1"
+	newDs.LongDesc2 = "LongDesc2"
+	newDs.MaxDNSAnswers = 5
+	newDs.MidHeaderRewrite = "MidHeaderRewrite"
+	newDs.MissLat = 5.555
+	newDs.MissLong = -50.5050
+	newDs.MultiSiteOrigin = true
+	newDs.OrgServerFQDN = "http://OrgServerFQDN"
+	newDs.ProfileDesc = profile.Description
+	newDs.ProfileName = profile.Name
+	newDs.Protocol = 1
+	newDs.QStringIgnore = 1
+	newDs.RangeRequestHandling = 0
+	newDs.RegexRemap = "regexRemap"
+	newDs.RemapText = "remapText"
+	newDs.Signed = false
+	newDs.TRResponseHeaders = "TRResponseHeaders"
+	newDs.Type = "HTTP"
+	newDs.XMLID = "Test-DS-" + strconv.FormatInt(time.Now().Unix(), 10)
+	newDs.RegionalGeoBlocking = false
+	newDs.LogsEnabled = false
+
+	//Create currently does not write regexes...
+	// newDsMatch1 := new(traffic_ops.DeliveryServiceMatch)
+	// newDsMatch1.Pattern = "Pattern1"
+	// newDsMatch1.SetNumber = "0"
+	// newDsMatch1.Type = "HOST"
+
+	// newDsMatch2 := new(traffic_ops.DeliveryServiceMatch)
+	// newDsMatch2.Pattern = "Pattern2"
+	// newDsMatch2.SetNumber = "1"
+	// newDsMatch2.Type = "HOST"
+
+	// newDs.MatchList = append(newDs.MatchList, *newDsMatch1)
+	// newDs.MatchList = append(newDs.MatchList, *newDsMatch2)
+
+	res, err := to.CreateDeliveryService(newDs)
+	if err != nil {
+		t.Error("Failed to create deliveryservice!  Error is: ", err)
+	} else {
+		compareDs(*newDs, res.Response[0], t)
+	}
+}
+
+func compareDs(ds1 traffic_ops.DeliveryService, ds2 traffic_ops.DeliveryService, t *testing.T) {
+	if ds1.Active != ds1.Active {
+		t.Errorf("Active -- Expected %v, Got %v\n", ds1.Active, ds2.Active)
+	}
+	if ds1.CCRDNSTTL != ds2.CCRDNSTTL {
+		t.Errorf("CCRDNSTTL -- Expected %v, Got %v\n", ds1.CCRDNSTTL, ds2.CCRDNSTTL)
+	}
+	if ds1.CDNName != ds2.CDNName {
+		t.Errorf("CDNName -- Expected %v, Got %v\n", ds1.CDNName, ds2.CDNName)
+	}
+	if ds1.CacheURL != ds2.CacheURL {
+		t.Errorf("CacheURL -- Expected %v, Got %v\n", ds1.CacheURL, ds2.CacheURL)
+	}
+	if ds1.CheckPath != ds2.CheckPath {
+		t.Errorf("CheckPath -- Expected %v, Got %v\n", ds1.CheckPath, ds2.CheckPath)
+	}
+	if ds1.DNSBypassCname != ds2.DNSBypassCname {
+		t.Errorf("DNSBypassCname -- Expected %v, Got %v\n", ds1.DNSBypassCname, ds2.DNSBypassCname)
+	}
+	if ds1.DNSBypassIP != ds2.DNSBypassIP {
+		t.Errorf("DNSBypassIP -- Expected %v, Got %v\n", ds1.DNSBypassIP, ds2.DNSBypassIP)
+	}
+	if ds1.DNSBypassIP6 != ds2.DNSBypassIP6 {
+		t.Errorf("DNSBypassIP6 -- Expected %v, Got %v\n", ds1.DNSBypassIP6, ds2.DNSBypassIP6)
+	}
+	if ds1.DNSBypassTTL != ds2.DNSBypassTTL {
+		t.Errorf("DNSBypassTTL -- Expected %v, Got %v\n", ds1.DNSBypassTTL, ds2.DNSBypassTTL)
+	}
+	if ds1.DSCP != ds2.DSCP {
+		t.Errorf("DSCP -- Expected %v, Got %v\n", ds1.DSCP, ds2.DSCP)
+	}
+	if ds1.DisplayName != ds2.DisplayName {
+		t.Errorf("DisplayName -- Expected %v, Got %v\n", ds1.DisplayName, ds2.DisplayName)
+	}
+	if ds1.EdgeHeaderRewrite != ds2.EdgeHeaderRewrite {
+		t.Errorf("EdgeHeaderRewrite -- Expected %v, Got %v\n", ds1.EdgeHeaderRewrite, ds2.EdgeHeaderRewrite)
+	}
+	if ds1.GeoLimit != ds2.GeoLimit {
+		t.Errorf("GeoLimit -- Expected %v, Got %v\n", ds1.GeoLimit, ds2.GeoLimit)
+	}
+	if ds1.GeoProvider != ds2.GeoProvider {
+		t.Errorf("GeoProvider -- Expected %v, Got %v\n", ds1.GeoProvider, ds2.GeoProvider)
+	}
+	if ds1.GlobalMaxMBPS != ds2.GlobalMaxMBPS {
+		t.Errorf("GlobalMaxMBPS -- Expected %v, Got %v\n", ds1.GlobalMaxMBPS, ds2.GlobalMaxMBPS)
+	}
+	if ds1.GlobalMaxTPS != ds2.GlobalMaxTPS {
+		t.Errorf("GlobalMaxTPS -- Expected %v, Got %v\n", ds1.GlobalMaxTPS, ds2.GlobalMaxTPS)
+	}
+	if ds1.HTTPBypassFQDN != ds2.HTTPBypassFQDN {
+		t.Errorf("HTTPBypassFQDN -- Expected %v, Got %v\n", ds1.HTTPBypassFQDN, ds2.HTTPBypassFQDN)
+	}
+	if ds1.ID > 0 && ds1.ID != ds2.ID {
+		t.Errorf("ID -- Expected %v, Got %v\n", ds1.ID, ds2.ID)
+	}
+	if ds1.IPV6RoutingEnabled != ds2.IPV6RoutingEnabled {
+		t.Errorf("IPv6RoutingEnabled -- Expected %v, Got %v\n", ds1.IPV6RoutingEnabled, ds2.IPV6RoutingEnabled)
+	}
+	if ds1.InfoURL != ds2.InfoURL {
+		t.Errorf("InfoURL -- Expected %v, Got %v\n", ds1.InfoURL, ds2.InfoURL)
+	}
+	if ds1.InitialDispersion != ds2.InitialDispersion {
+		t.Errorf("InitialDispersion -- Expected %v, Got %v\n", ds1.InitialDispersion, ds2.InitialDispersion)
+	}
+	if ds1.LastUpdated != ds2.LastUpdated {
+		t.Errorf("LastUpdated -- Expected %v, Got %v\n", ds1.LastUpdated, ds2.LastUpdated)
+	}
+	if ds1.LongDesc != ds2.LongDesc {
+		t.Errorf("LongDesc -- Expected %v, Got %v\n", ds1.LongDesc, ds2.LongDesc)
+	}
+	if ds1.LongDesc1 != ds2.LongDesc1 {
+		t.Errorf("LongDesc1 -- Expected %v, Got %v\n", ds1.LongDesc1, ds2.LongDesc1)
+	}
+	if ds1.LongDesc2 != ds2.LongDesc2 {
+		t.Errorf("LongDesc2 -- Expected %v, Got %v\n", ds1.LongDesc2, ds2.LongDesc2)
+	}
+	if ds1.MaxDNSAnswers != ds2.MaxDNSAnswers {
+		t.Errorf("MaxDNSAnswers-- Expected %v, Got %v\n", ds1.MaxDNSAnswers, ds2.MaxDNSAnswers)
+	}
+	if ds1.MidHeaderRewrite != ds2.MidHeaderRewrite {
+		t.Errorf("MidHeaderRewrite -- Expected %v, Got %v\n", ds1.MidHeaderRewrite, ds2.MidHeaderRewrite)
+	}
+	if ds1.MissLat != ds2.MissLat {
+		t.Errorf("MissLat -- Expected %v, Got %v\n", ds1.MissLat, ds2.MissLat)
+	}
+	if ds1.MissLong != ds2.MissLong {
+		t.Errorf("MissLong -- Expected %v, Got %v\n", ds1.MissLong, ds2.MissLong)
+	}
+	if ds1.MultiSiteOrigin != ds2.MultiSiteOrigin {
+		t.Errorf("MutiSiteOrigin -- Expected %v, Got %v\n", ds1.MultiSiteOrigin, ds2.MultiSiteOrigin)
+	}
+	if ds1.OrgServerFQDN != ds2.OrgServerFQDN {
+		t.Errorf("OrgServerFQDN -- Expected %v, Got %v\n", ds1.OrgServerFQDN, ds2.OrgServerFQDN)
+	}
+	if ds1.ProfileDesc != ds2.ProfileDesc {
+		t.Errorf("ProfileDesc -- Expected %v, Got %v\n", ds1.ProfileDesc, ds2.ProfileDesc)
+	}
+	if ds1.ProfileName != ds2.ProfileName {
+		t.Errorf("ProfileName -- Expected %v, Got %v\n", ds1.ProfileName, ds2.ProfileName)
+	}
+	if ds1.Protocol != ds2.Protocol {
+		t.Errorf("Protocol -- Expected %v, Got %v\n", ds1.Protocol, ds2.Protocol)
+	}
+	if ds1.QStringIgnore != ds2.QStringIgnore {
+		t.Errorf("QStringIgnore -- Expected %v, Got %v\n", ds1.QStringIgnore, ds2.QStringIgnore)
+	}
+	if ds1.RangeRequestHandling != ds2.RangeRequestHandling {
+		t.Errorf("RangeRequestHandling -- Expected %v, Got %v\n", ds1.RangeRequestHandling, ds2.RangeRequestHandling)
+	}
+	if ds1.RegexRemap != ds2.RegexRemap {
+		t.Errorf("RegexRemap -- Expected %v, Got %v\n", ds1.RegexRemap, ds2.RegexRemap)
+	}
+	if ds1.RemapText != ds2.RemapText {
+		t.Errorf("RemapText -- Expected %v, Got %v\n", ds1.RemapText, ds2.RemapText)
+	}
+	if ds1.Signed != ds2.Signed {
+		t.Errorf("Signed -- Expected %v, Got %v\n", ds1.Signed, ds2.Signed)
+	}
+	if ds1.TRResponseHeaders != ds2.TRResponseHeaders {
+		t.Errorf("TRResponseHeaders -- Expected %v, Got %v\n", ds1.TRResponseHeaders, ds2.TRResponseHeaders)
+	}
+	if ds1.Type != ds2.Type {
+		t.Errorf("Type -- Expected %v, Got %v\n", ds1.Type, ds2.Type)
+	}
+	if ds1.RegionalGeoBlocking != ds2.RegionalGeoBlocking {
+		t.Errorf("RegionalGeoBlocking -- Expected %v, Got %v\n", ds1.RegionalGeoBlocking, ds2.RegionalGeoBlocking)
+	}
+	if ds1.LogsEnabled != ds2.LogsEnabled {
+		t.Errorf("LogsEnabled -- Expected %v, Got %v\n", ds1.LogsEnabled, ds2.LogsEnabled)
+	}
+	if len(ds1.MatchList) > 0 {
+		for i, match := range ds1.MatchList {
+			if match != ds2.MatchList[i] {
+				t.Errorf("Matchlist -- Expected %v, Got %v\n", match, ds2.MatchList[i])
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/3fa2b81e/traffic_ops/client/tests/integration/integration_helper.go
----------------------------------------------------------------------
diff --git a/traffic_ops/client/tests/integration/integration_helper.go b/traffic_ops/client/tests/integration/integration_helper.go
new file mode 100644
index 0000000..73f6370
--- /dev/null
+++ b/traffic_ops/client/tests/integration/integration_helper.go
@@ -0,0 +1,89 @@
+package integration
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"net/http"
+	"os"
+
+	traffic_ops "github.com/apache/incubator-trafficcontrol/traffic_ops/client"
+)
+
+var (
+	to *traffic_ops.Session
+)
+
+func init() {
+	toURL := flag.String("toURL", "http://localhost:3000", "Traffic Ops URL")
+	toUser := flag.String("toUser", "admin", "Traffic Ops user")
+	toPass := flag.String("toPass", "password", "Traffic Ops password")
+	flag.Parse()
+	var loginErr error
+	to, loginErr = traffic_ops.Login(*toURL, *toUser, *toPass, true)
+	if loginErr != nil {
+		fmt.Printf("\nError logging in to %v: %v\nMake sure toURL, toUser, and toPass flags are included and correct.\nExample:  go test -toUser=admin -toPass=pass -toURL=http://localhost:3000\n\n", *toURL, loginErr)
+		os.Exit(1)
+	}
+}
+
+//GetCdn returns a Cdn struct
+func GetCdn() (traffic_ops.CDN, error) {
+	cdns, err := to.CDNs()
+	if err != nil {
+		return *new(traffic_ops.CDN), err
+	}
+	cdn := cdns[0]
+	if cdn.Name == "ALL" {
+		cdn = cdns[1]
+	}
+	return cdn, nil
+}
+
+//GetProfile returns a Profile Struct
+func GetProfile() (traffic_ops.Profile, error) {
+	profiles, err := to.Profiles()
+	if err != nil {
+		return *new(traffic_ops.Profile), err
+	}
+	return profiles[0], nil
+}
+
+//Request sends a request to TO and returns a response.
+//This is basically a copy of the private "request" method in the traffic_ops.go \
+//but I didn't want to make that one public.
+func Request(to traffic_ops.Session, method, path string, body []byte) (*http.Response, error) {
+	url := fmt.Sprintf("%s%s", to.URL, path)
+
+	var req *http.Request
+	var err error
+
+	if body != nil && method != "GET" {
+		req, err = http.NewRequest(method, url, bytes.NewBuffer(body))
+		if err != nil {
+			return nil, err
+		}
+		req.Header.Set("Content-Type", "application/json")
+	} else {
+		req, err = http.NewRequest("GET", url, nil)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	resp, err := to.UserAgent.Do(req)
+	if err != nil {
+		return nil, err
+	}
+
+	if resp.StatusCode != http.StatusOK {
+		e := traffic_ops.HTTPError{
+			HTTPStatus:     resp.Status,
+			HTTPStatusCode: resp.StatusCode,
+			URL:            url,
+		}
+		return nil, &e
+	}
+
+	return resp, nil
+}