You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by zr...@apache.org on 2021/07/29 17:19:03 UTC

[trafficcontrol] branch master updated: Add TO Client API for Origin Automation (#5960)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new be75b58  Add TO Client API for Origin Automation (#5960)
be75b58 is described below

commit be75b581494926c93cc71ad80d1f50e8f9be70ae
Author: dmohan001c <de...@comcast.com>
AuthorDate: Thu Jul 29 22:48:53 2021 +0530

    Add TO Client API for Origin Automation (#5960)
    
    * added test for get origins functionality
    
    * added tests for invalid origin scenarios
    
    * updated comments in origin tests
    
    * updated error conditions for origin duplicate scenarios
    
    * trigger GitHub actions
    
    * added tests for getoriginbyinvalidname and  primary
---
 traffic_ops/testing/api/v4/origins_test.go  | 547 +++++++++++++++++++++++++++-
 traffic_ops/testing/api/v4/tc-fixtures.json |   6 +-
 2 files changed, 540 insertions(+), 13 deletions(-)

diff --git a/traffic_ops/testing/api/v4/origins_test.go b/traffic_ops/testing/api/v4/origins_test.go
index 3dd27f5..b502469 100644
--- a/traffic_ops/testing/api/v4/origins_test.go
+++ b/traffic_ops/testing/api/v4/origins_test.go
@@ -36,16 +36,21 @@ func TestOrigins(t *testing.T) {
 		var header http.Header
 		header = make(map[string][]string)
 		header.Set(rfc.IfUnmodifiedSince, time)
+		CreateTestOriginDuplicateData(t)
+		GetTestOriginsByParams(t)
+		GetTestOriginsByInvalidParams(t)
 		UpdateTestOrigins(t)
 		UpdateTestOriginsWithHeaders(t, header)
 		GetTestOrigins(t)
 		NotFoundDeleteTest(t)
 		OriginTenancyTest(t)
-		VerifyPaginationSupport(t)
+		GetTestPaginationSupportOrigins(t)
 		header = make(map[string][]string)
 		etag := rfc.ETag(currentTime)
 		header.Set(rfc.IfMatch, etag)
 		UpdateTestOriginsWithHeaders(t, header)
+		CreateTestOriginInvalidData(t)
+		updateTestOriginsWithInvalidData(t)
 	})
 }
 
@@ -100,6 +105,23 @@ func CreateTestOrigins(t *testing.T) {
 	}
 }
 
+func CreateTestOriginDuplicateData(t *testing.T) {
+	if len(testData.Origins) < 1 {
+		t.Fatal("Need at least one Origin to test duplicate scenario")
+	}
+	firstOrigin := testData.Origins[0]
+	if firstOrigin.Name == nil {
+		t.Fatalf("couldn't get the name of test origin server")
+	}
+	resp, reqInf, err := TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected, origin name %s already exists, but no error found - Alerts %v", *firstOrigin.Name, resp.Alerts)
+	}
+}
+
 func NotFoundDeleteTest(t *testing.T) {
 	resp, _, err := TOSession.DeleteOrigin(2020, client.RequestOptions{})
 	if err == nil {
@@ -161,16 +183,40 @@ func UpdateTestOrigins(t *testing.T) {
 	}
 	updatedPort := 4321
 	updatedFQDN := "updated.example.com"
-
-	// update port and FQDN values on origin
-	remoteOrigin.Port = &updatedPort
-	remoteOrigin.FQDN = &updatedFQDN
-	updResp, _, err := TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	updatedIpAddress := "5.6.7.8"
+	updatedIpv6Address := "dead:beef:cafe::455"
+	updatedIsPrimary := false
+	updatedProfile := "EDGEInCDN2"
+	updateDeliveryService := "ds3"
+	updateCachegroup := "multiOriginCachegroup"
+	updateCoordinate := "coordinate2"
+	updateProtocol := "https"
+	updateTenant := "tenant2"
+
+	// update Cachegroup/Coordinate/Name/Delivery Service/Port/FQDN/IPAddress/IPV6Address/Profile/IsPrimary/Protocol/Tenant values on origin
+	originRequest := tc.Origin{
+		Cachegroup:      &updateCachegroup,
+		Coordinate:      &updateCoordinate,
+		Name:            remoteOrigin.Name,
+		DeliveryService: &updateDeliveryService,
+		FQDN:            &updatedFQDN,
+		IP6Address:      &updatedIpv6Address,
+		IPAddress:       &updatedIpAddress,
+		IsPrimary:       &updatedIsPrimary,
+		Port:            &updatedPort,
+		Profile:         &updatedProfile,
+		Protocol:        &updateProtocol,
+		Tenant:          &updateTenant,
+	}
+
+	updResp, reqInf, err := TOSession.UpdateOrigin(*remoteOrigin.ID, originRequest, client.RequestOptions{})
 	if err != nil {
 		t.Errorf("cannot update Origin '%s' (#%d): %v - %v", foName, *remoteOrigin.ID, err, updResp.Alerts)
 	}
-
-	// Retrieve the origin to check port and FQDN values were updated
+	if reqInf.StatusCode != http.StatusOK {
+		t.Errorf("Expected 200 Status Code, but found %d", reqInf.StatusCode)
+	}
+	// Retrieve the origin to check cachegroup, coordinate, deliveryservice, port, FQDN, IPAddress, IPV6Address, Profile, IsPrimary, Protocol, Tenant values were updated
 	opts.QueryParameters.Del("name")
 	opts.QueryParameters.Set("id", strconv.Itoa(*remoteOrigin.ID))
 	resp, _, err = TOSession.GetOrigins(opts)
@@ -182,6 +228,24 @@ func UpdateTestOrigins(t *testing.T) {
 	}
 	respOrigin := resp.Response[0]
 
+	if respOrigin.Cachegroup == nil {
+		t.Errorf("results do not match, actual: null or undefined - expected: %s", updateCachegroup)
+	} else if *respOrigin.Cachegroup != updateCachegroup {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.Cachegroup, updateCachegroup)
+	}
+
+	if respOrigin.Coordinate == nil {
+		t.Errorf("results do not match, actual: null or undefined - expected: %s", updateCoordinate)
+	} else if *respOrigin.Coordinate != updateCoordinate {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.Coordinate, updateCoordinate)
+	}
+
+	if respOrigin.DeliveryService == nil {
+		t.Errorf("results do not match, actual: null or undefined - expected: %s", updateDeliveryService)
+	} else if *respOrigin.DeliveryService != updateDeliveryService {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.DeliveryService, updateDeliveryService)
+	}
+
 	if respOrigin.Port == nil {
 		t.Errorf("results do not match, actual: null or undefined - expected: %d", updatedPort)
 	} else if *respOrigin.Port != updatedPort {
@@ -192,6 +256,41 @@ func UpdateTestOrigins(t *testing.T) {
 	} else if *respOrigin.FQDN != updatedFQDN {
 		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.FQDN, updatedFQDN)
 	}
+	if respOrigin.IPAddress == nil {
+		t.Errorf("results do not match, actual: null or undefined, expected: '%s'", updatedIpAddress)
+	} else if *respOrigin.IPAddress != updatedIpAddress {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.IPAddress, updatedIpAddress)
+	}
+
+	if respOrigin.IP6Address == nil {
+		t.Errorf("results do not match, actual: null or undefined, expected: '%s'", updatedIpv6Address)
+	} else if *respOrigin.IP6Address != updatedIpv6Address {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.IP6Address, updatedIpv6Address)
+	}
+
+	if respOrigin.IsPrimary == nil {
+		t.Errorf("results do not match, actual: null or undefined, expected: '%t'", updatedIsPrimary)
+	} else if *respOrigin.IsPrimary != updatedIsPrimary {
+		t.Errorf("results do not match actual: %t, expected: %t", *respOrigin.IsPrimary, updatedIsPrimary)
+	}
+
+	if respOrigin.Profile == nil {
+		t.Errorf("results do not match, actual: null or undefined, expected: '%s'", updatedProfile)
+	} else if *respOrigin.Profile != updatedProfile {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.Profile, updatedProfile)
+	}
+
+	if respOrigin.Protocol == nil {
+		t.Errorf("results do not match, actual: null or undefined, expected: '%s'", updateProtocol)
+	} else if *respOrigin.Protocol != updateProtocol {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.Protocol, updateProtocol)
+	}
+
+	if respOrigin.Tenant == nil {
+		t.Errorf("results do not match, actual: null or undefined, expected: '%s'", updateTenant)
+	} else if *respOrigin.Tenant != updateTenant {
+		t.Errorf("results do not match actual: %s, expected: %s", *respOrigin.Tenant, updateTenant)
+	}
 }
 
 func OriginTenancyTest(t *testing.T) {
@@ -270,17 +369,17 @@ func alertsHaveError(alerts []tc.Alert, err string) bool {
 	return false
 }
 
-func VerifyPaginationSupport(t *testing.T) {
+func GetTestPaginationSupportOrigins(t *testing.T) {
 	opts := client.NewRequestOptions()
 	opts.QueryParameters.Set("orderby", "id")
 	resp, _, err := TOSession.GetOrigins(opts)
 	if err != nil {
 		t.Fatalf("cannot get Origins: %v - alerts: %+v", err, resp.Alerts)
 	}
-	if len(resp.Response) < 3 {
-		t.Fatalf("Need at least 3 Origins in Traffic Ops to test pagination")
-	}
 	origins := resp.Response
+	if len(origins) < 3 {
+		t.Fatalf("Need at least 3 Origins in Traffic Ops to test pagination, found: %d", len(resp.Response))
+	}
 
 	opts.QueryParameters.Set("limit", "1")
 	originsWithLimit, _, err := TOSession.GetOrigins(opts)
@@ -374,3 +473,427 @@ func DeleteTestOrigins(t *testing.T) {
 		}
 	}
 }
+
+func GetTestOriginsByParams(t *testing.T) {
+	if len(testData.Origins) < 1 {
+		t.Fatal("Need at least one Origin to test Get Origins by params")
+	}
+	origins := testData.Origins[0]
+	if origins.Name == nil || len(*origins.Name) == 0 {
+		t.Fatal("Found nil value in Origin name")
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("name", *origins.Name)
+	originByName, _, _ := TOSession.GetOrigins(opts)
+	if len(originByName.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Delivery Service, but found %d", len(originByName.Response))
+	}
+	if originByName.Response[0].DeliveryServiceID == nil {
+		t.Fatal("Found nil value in delivery service")
+	}
+	if originByName.Response[0].CachegroupID == nil {
+		t.Fatal("Found nil value in Cachegroup")
+	}
+	if originByName.Response[0].CoordinateID == nil {
+		t.Fatal("Found nil value in Coordinate")
+	}
+	if originByName.Response[0].ProfileID == nil {
+		t.Fatal("Found nil value in Profile")
+	}
+	if originByName.Response[0].IsPrimary == nil {
+		t.Fatal("Found nil value in IsPrimary field")
+	}
+
+	//Get Origins by DSID
+	dsId := *originByName.Response[0].DeliveryServiceID
+	opts.QueryParameters.Del("name")
+	opts.QueryParameters.Set("deliveryservice", strconv.Itoa(dsId))
+	originByDs, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin by DeliveryService ID: %v - alerts: %+v", err, originByDs.Alerts)
+	}
+	if len(originByDs.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Delivery Service, but found %d", len(originByDs.Response))
+	}
+
+	//Get Origins by Cachegroup
+	cachegroupID := *originByName.Response[0].CachegroupID
+	opts.QueryParameters.Del("deliveryservice")
+	opts.QueryParameters.Set("cachegroup", strconv.Itoa(cachegroupID))
+	originByCg, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin by Cachegroup ID: %v - alerts: %+v", err, originByCg.Alerts)
+	}
+	if len(originByCg.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Cachegroups, but found %d", len(originByCg.Response))
+	}
+
+	//Get Origins by Coordinate
+	CoordinateID := *originByName.Response[0].CoordinateID
+	opts.QueryParameters.Del("cachegroup")
+	opts.QueryParameters.Set("coordinate", strconv.Itoa(CoordinateID))
+	originByCoordinate, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin by Coordinate ID: %v - alerts: %+v", err, originByCoordinate.Alerts)
+	}
+	if len(originByCoordinate.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Coordinate, but found %d", len(originByCoordinate.Response))
+	}
+
+	//Get Origins by Profile
+	profileId := *originByName.Response[0].ProfileID
+	opts.QueryParameters.Del("coordinate")
+	opts.QueryParameters.Set("profileId", strconv.Itoa(profileId))
+	originByProfile, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin by Profile ID: %v - alerts: %+v", err, originByProfile.Alerts)
+	}
+	if len(originByProfile.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Profile, but found %d", len(originByProfile.Response))
+	}
+
+	//Get Origins by Primary
+	isPrimary := *originByName.Response[0].IsPrimary
+	opts.QueryParameters.Del("profileId")
+	opts.QueryParameters.Set("isPrimary", strconv.FormatBool(isPrimary))
+	originByPrimary, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin by Primary ID: %v - alerts: %+v", err, originByPrimary.Alerts)
+	}
+	if len(originByPrimary.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Primary, but found %d", len(originByPrimary.Response))
+	}
+
+	//Get Origins by Tenant
+	tenant := *originByName.Response[0].TenantID
+	opts.QueryParameters.Del("isPrimary")
+	opts.QueryParameters.Set("tenant", strconv.Itoa(tenant))
+	originByTenant, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin by Tenant ID: %v - alerts: %+v", err, originByTenant.Alerts)
+	}
+	if len(originByTenant.Response) < 1 {
+		t.Fatalf("Expected atleast one Origin for GET Origin by Tenant, but found %d", len(originByTenant.Response))
+	}
+}
+
+func GetTestOriginsByInvalidParams(t *testing.T) {
+
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryservice", "12345")
+	originByDs, _, _ := TOSession.GetOrigins(opts)
+	if len(originByDs.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid Delivery Service, but found %d", len(originByDs.Response))
+	}
+
+	//Get Origins by Cachegroup
+	opts.QueryParameters.Del("deliveryservice")
+	opts.QueryParameters.Set("cachegroup", "12345")
+	originByCg, _, _ := TOSession.GetOrigins(opts)
+	if len(originByCg.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid Cachegroups, but found %d", len(originByCg.Response))
+	}
+
+	//Get Origins by Coordinate
+	opts.QueryParameters.Del("cachegroup")
+	opts.QueryParameters.Set("coordinate", "12345")
+	originByCoordinate, _, _ := TOSession.GetOrigins(opts)
+	if len(originByCoordinate.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid Coordinate, but found %d", len(originByCoordinate.Response))
+	}
+
+	//Get Origins by Profile
+	opts.QueryParameters.Del("coordinate")
+	opts.QueryParameters.Set("profileId", "12345")
+	originByProfile, _, _ := TOSession.GetOrigins(opts)
+	if len(originByProfile.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid Profile, but found %d", len(originByProfile.Response))
+	}
+
+	//Get Origins by Tenant
+	opts.QueryParameters.Del("profileId")
+	opts.QueryParameters.Set("tenant", "12345")
+	originByTenant, _, _ := TOSession.GetOrigins(opts)
+	if len(originByTenant.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid Tenant, but found %d", len(originByTenant.Response))
+	}
+
+	//Get Origins by Name
+	opts.QueryParameters.Del("tenant")
+	opts.QueryParameters.Set("name", "abcdef")
+	originByName, _, _ := TOSession.GetOrigins(opts)
+	if len(originByName.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid name, but found %d", len(originByName.Response))
+	}
+
+	//Get Origins by Primary
+	opts.QueryParameters.Del("name")
+	opts.QueryParameters.Set("primary", "12345")
+	originByPrimary, _, _ := TOSession.GetOrigins(opts)
+	if len(originByPrimary.Response) > 0 {
+		t.Fatalf("Expected empty response for GET Origin by invalid Primary, but found %d", len(originByPrimary.Response))
+	}
+}
+
+func CreateTestOriginInvalidData(t *testing.T) {
+	if len(testData.Origins) < 1 {
+		t.Fatal("Need at least one Origin to test duplicate Origins")
+	}
+	firstOrigin := testData.Origins[0]
+	if firstOrigin.Name == nil {
+		t.Fatalf("couldn't get the name of test origin server")
+	}
+	oldCachegroupId := firstOrigin.CachegroupID
+	oldProfileId := firstOrigin.ProfileID
+	oldTenantId := firstOrigin.TenantID
+	oldProtocol := firstOrigin.Protocol
+	oldCoordinateId := firstOrigin.CoordinateID
+	oldIpv4 := firstOrigin.IPAddress
+
+	//invalid cg id
+	cachegroupID := new(int)
+	*cachegroupID = 12345
+	name := new(string)
+	*name = "invalid"
+	firstOrigin.CachegroupID = cachegroupID
+	firstOrigin.Name = name
+	resp, reqInf, err := TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected cachegroup not found - Alerts %v", resp.Alerts)
+	}
+
+	//invalid profile id
+	firstOrigin.CachegroupID = oldCachegroupId
+	profileId := new(int)
+	*profileId = 12345
+	firstOrigin.ProfileID = profileId
+	resp, reqInf, err = TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected profile not found - Alerts %v", resp.Alerts)
+	}
+
+	//invalid tenant id
+	firstOrigin.ProfileID = oldProfileId
+	tenantId := new(int)
+	*tenantId = 12345
+	firstOrigin.TenantID = tenantId
+	resp, reqInf, err = TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusForbidden {
+		t.Errorf("Expected 403 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected user not authorized for requested tenant - Alerts %v", resp.Alerts)
+	}
+
+	//invalid protocol id
+	firstOrigin.TenantID = oldTenantId
+	protocol := new(string)
+	*protocol = "abcd"
+	firstOrigin.Protocol = protocol
+	resp, reqInf, err = TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected 'protocol' must be http or https - Alerts %v", resp.Alerts)
+	}
+
+	//invalid coordinate id
+	firstOrigin.Protocol = oldProtocol
+	coordinateId := new(int)
+	*coordinateId = 12345
+	firstOrigin.CoordinateID = coordinateId
+	resp, reqInf, err = TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected coordinate not found - Alerts %v", resp.Alerts)
+	}
+
+	//invalid IPV4
+	firstOrigin.CoordinateID = oldCoordinateId
+	ipv4 := new(string)
+	*ipv4 = "1.11"
+	firstOrigin.IPAddress = ipv4
+	resp, reqInf, err = TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected 'ipAddress' must be a valid IPv4 address - Alerts %v", resp.Alerts)
+	}
+
+	//invalid IPV6
+	firstOrigin.IPAddress = oldIpv4
+	ipv6 := new(string)
+	*ipv6 = "1:1:1:1:1"
+	firstOrigin.IP6Address = ipv6
+	resp, reqInf, err = TOSession.CreateOrigin(firstOrigin, client.RequestOptions{})
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status code, but found %d", reqInf.StatusCode)
+	}
+	if err == nil {
+		t.Errorf("Expected 'ip6Address' must be a valid IPv6 address - Alerts %v", resp.Alerts)
+	}
+}
+
+func updateTestOriginsWithInvalidData(t *testing.T) {
+	if len(testData.Origins) < 1 {
+		t.Fatal("Need at least one Origin to test updating Origins")
+	}
+	firstOrigin := testData.Origins[0]
+	if firstOrigin.Name == nil {
+		t.Fatal("Found an Origin in the testing data with null or undefined name")
+	}
+	foName := *firstOrigin.Name
+	// Retrieve the origin by name so we can get the id for the Update
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("name", foName)
+	resp, _, err := TOSession.GetOrigins(opts)
+	if err != nil {
+		t.Errorf("cannot get Origin '%s': %v - alerts: %+v", foName, err, resp.Alerts)
+	}
+	if len(resp.Response) != 1 {
+		t.Fatalf("Expected exactly one Origin to exist with name '%s', found: %d", foName, len(resp.Response))
+	}
+	remoteOrigin := resp.Response[0]
+	if remoteOrigin.ID == nil {
+		t.Fatalf("Traffic Ops responded with a representation of Origin '%s' that had null or undefined ID", foName)
+	}
+
+	oldCachegroupId := remoteOrigin.CachegroupID
+	oldProfileId := remoteOrigin.ProfileID
+	oldTenantId := remoteOrigin.TenantID
+	oldProtocol := remoteOrigin.Protocol
+	oldCoordinateId := remoteOrigin.CoordinateID
+	oldIpv4 := remoteOrigin.IPAddress
+	oldIpv6 := remoteOrigin.IP6Address
+	oldPort := remoteOrigin.Port
+	oldDeliveryServiceId := remoteOrigin.DeliveryServiceID
+
+	//update invalid port
+	updatedPort := 123456
+	remoteOrigin.Port = &updatedPort
+	updResp, reqInf, err := TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - Port must be a valid integer between 1 and 65535. Port - %d, Alerts %v", updatedPort, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update cachegroup id
+	remoteOrigin.Port = oldPort
+	updatedCachegroupId := 123456
+	remoteOrigin.CachegroupID = &updatedCachegroupId
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - Cachegroup not found. Cachegroup - %d, Alerts %v", updatedCachegroupId, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update coordinate id
+	remoteOrigin.CachegroupID = oldCachegroupId
+	updatedCoordinateId := 123456
+	remoteOrigin.CoordinateID = &updatedCoordinateId
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - Coordinate not found, Coordinate - %d, Alerts %v", updatedCoordinateId, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid ds id
+	remoteOrigin.CoordinateID = oldCoordinateId
+	updatedDeliveryServiceId := 123456
+	remoteOrigin.DeliveryServiceID = &updatedDeliveryServiceId
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - checking tenancy: requested delivery service does not exist, Delivery Service - %d, Alerts %v", updatedDeliveryServiceId, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid protocol
+	remoteOrigin.DeliveryServiceID = oldDeliveryServiceId
+	updatedProtocol := "httpsss"
+	remoteOrigin.Protocol = &updatedProtocol
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - Protocol must be http or https. Protocol - %s, Alerts %v", updatedProtocol, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid ipv6
+	remoteOrigin.Protocol = oldProtocol
+	updatedIpv6 := "1.1"
+	remoteOrigin.IP6Address = &updatedIpv6
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - Ip6Address must be a valid IPv6 address. IPV6 Address - %s, Alerts %v", updatedIpv6, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid ipv4
+	remoteOrigin.IP6Address = oldIpv6
+	updatedIpv4 := "1.1"
+	remoteOrigin.IPAddress = &updatedIpv4
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - IpAddress must be a valid IPv4 address. IPV4 - %s, Alerts %v", updatedIpv4, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected 400 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid tenant
+	remoteOrigin.IPAddress = oldIpv4
+	updatedTenantId := 11111
+	remoteOrigin.TenantID = &updatedTenantId
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - user not authorized for requested tenant. Tenant - %d, Alerts %v", updatedTenantId, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusForbidden {
+		t.Errorf("Expected 403 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid profile
+	remoteOrigin.TenantID = oldTenantId
+	updatedProfileId := 12345
+	remoteOrigin.ProfileID = &updatedProfileId
+	updResp, reqInf, err = TOSession.UpdateOrigin(*remoteOrigin.ID, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - profile not found %d - Alerts %v", updatedProfileId, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status Code, but found %d", reqInf.StatusCode)
+	}
+
+	//update invalid id
+	remoteOrigin.ProfileID = oldProfileId
+	invalidId := new(int)
+	*invalidId = 12345
+	updResp, reqInf, err = TOSession.UpdateOrigin(*invalidId, remoteOrigin, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected - Origin not found. Origin ID - %d, Alerts %v", *invalidId, updResp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusNotFound {
+		t.Errorf("Expected 404 Status Code, but found %d", reqInf.StatusCode)
+	}
+}
diff --git a/traffic_ops/testing/api/v4/tc-fixtures.json b/traffic_ops/testing/api/v4/tc-fixtures.json
index 52ac6ec..e5dc6c9 100644
--- a/traffic_ops/testing/api/v4/tc-fixtures.json
+++ b/traffic_ops/testing/api/v4/tc-fixtures.json
@@ -1643,17 +1643,21 @@
         {
             "name": "origin1",
             "cachegroup": "originCachegroup",
+            "Coordinate": "coordinate1",
             "deliveryService": "ds1",
             "fqdn": "origin1.example.com",
             "ipAddress": "1.2.3.4",
             "ip6Address": "dead:beef:cafe::42",
             "port": 1234,
+            "Profile" : "ATS_EDGE_TIER_CACHE",
             "protocol": "http",
-            "tenant": "tenant1"
+            "tenant": "tenant1",
+            "isPrimary" : true
         },
         {
             "name": "origin2",
             "cachegroup": "originCachegroup",
+            "Coordinate": "coordinate1",
             "deliveryService": "ds2",
             "fqdn": "origin2.example.com",
             "ipAddress": "5.6.7.8",