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

ocket8888 pushed a commit to branch 5.1.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit 00916fb690c5aee9a946f3bd7928c8feabe5abbe
Author: Zach Hoffman <[email protected]>
AuthorDate: Fri Apr 23 12:43:02 2021 -0600

    Return legacy Monitoring Config from legacy Monitoring Config handler 
(#5755)
    
    * Set Health Threshold Parameters when converting to legacy Traffic Monitor 
Config
    
    * Make tc.strToThreshold() visibile
    
    * Return legacy Monitoring Config from legacy Monitoring Config handler
    
    * Remove duplicate parameters
    
    * Remove SnapshotGetMonitoringLegacyHandler()
    
    * Remove "Legacy" from logging
    
    * Copy new API tests to API v3 and API v4
    
    * Revert "Remove SnapshotGetMonitoringLegacyHandler()"
    
    * Revert crconfig.SnapshotGetMonitoringLegacyHandler() changes
    
    * Add godocs
    
    * Check the length of profiles, not cdns
    
    * Remove redundant condition
    
    * gofmt
    
    (cherry picked from commit a233b14a9a72c80f855c2b91ee88b71a783c49d0)
---
 CHANGELOG.md                                |  1 +
 lib/go-tc/nullable_test.go                  |  1 +
 lib/go-tc/traffic_monitor.go                | 47 ++++++++++++++--
 traffic_ops/testing/api/v1/crconfig_test.go | 83 ++++++++++++++++++++++++++++-
 traffic_ops/testing/api/v1/tc-fixtures.json | 36 +++++++------
 traffic_ops/testing/api/v2/crconfig_test.go | 83 ++++++++++++++++++++++++++++-
 traffic_ops/testing/api/v2/tc-fixtures.json | 36 +++++++------
 traffic_ops/testing/api/v3/crconfig_test.go | 81 ++++++++++++++++++++++++++++
 traffic_ops/testing/api/v3/tc-fixtures.json | 36 +++++++------
 9 files changed, 353 insertions(+), 51 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5759f5..f0a94c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - [#5712](https://github.com/apache/trafficcontrol/issues/5712) - Ensure that 
5.x Traffic Stats is compatible with 5.x Traffic Monitor and 5.x Traffic Ops, 
and that it doesn't log all 0's for `cache_stats`
 - Fixed ORT being unable to update URLSIG keys for Delivery Services
 - Fixed an issue where Traffic Ops becoming unavailable caused Traffic Monitor 
to segfault and crash
+- [#5754](https://github.com/apache/trafficcontrol/issues/5754) - Ensure 
Health Threshold Parameters use legacy format for legacy Monitoring Config 
handler
 
 ## [5.1.1] - 2021-03-19
 ### Added
diff --git a/lib/go-tc/nullable_test.go b/lib/go-tc/nullable_test.go
index 9c0fcdf..442bc8e 100644
--- a/lib/go-tc/nullable_test.go
+++ b/lib/go-tc/nullable_test.go
@@ -2,6 +2,7 @@
 // skip this unless specifically testing for nullable vs non-nullable struct 
comparison
 
 // Run as `go test -tags nullable`
+//go:build nullable
 // +build nullable
 
 package tc
diff --git a/lib/go-tc/traffic_monitor.go b/lib/go-tc/traffic_monitor.go
index 6f7f1b2..e4b7d09 100644
--- a/lib/go-tc/traffic_monitor.go
+++ b/lib/go-tc/traffic_monitor.go
@@ -80,6 +80,10 @@ type TrafficMonitorConfig struct {
        Profiles []TMProfile `json:"profiles,omitempty"`
 }
 
+const healthThresholdAvailableBandwidthInKbps = "availableBandwidthInKbps"
+const healthThresholdLoadAverage = "loadavg"
+const healthThresholdQueryTime = "queryTime"
+
 // ToLegacyConfig converts TrafficMonitorConfig to LegacyTrafficMonitorConfig.
 func (tmc *TrafficMonitorConfig) ToLegacyConfig() LegacyTrafficMonitorConfig {
        var servers []LegacyTrafficServer
@@ -87,6 +91,23 @@ func (tmc *TrafficMonitorConfig) ToLegacyConfig() 
LegacyTrafficMonitorConfig {
                servers = append(servers, s.ToLegacyServer())
        }
 
+       for profileIndex, profile := range tmc.Profiles {
+               thresholds := profile.Parameters.Thresholds
+               if _, exists := 
thresholds[healthThresholdAvailableBandwidthInKbps]; exists {
+                       
tmc.Profiles[profileIndex].Parameters.AvailableBandwidthInKbps = 
thresholds[healthThresholdAvailableBandwidthInKbps].String()
+                       
delete(tmc.Profiles[profileIndex].Parameters.Thresholds, 
healthThresholdAvailableBandwidthInKbps)
+               }
+               if _, exists := thresholds[healthThresholdLoadAverage]; exists {
+                       tmc.Profiles[profileIndex].Parameters.LoadAverage = 
thresholds[healthThresholdLoadAverage].String()
+                       
delete(tmc.Profiles[profileIndex].Parameters.Thresholds, 
healthThresholdLoadAverage)
+               }
+               if _, exists := thresholds[healthThresholdQueryTime]; exists {
+                       //tmc.Profiles[profileIndex].Parameters.QueryTime = 
int(thresholds[healthThresholdQueryTime].Val)
+                       tmc.Profiles[profileIndex].Parameters.QueryTime = 
thresholds[healthThresholdQueryTime].String()
+                       
delete(tmc.Profiles[profileIndex].Parameters.Thresholds, 
healthThresholdQueryTime)
+               }
+       }
+
        legacy := LegacyTrafficMonitorConfig{
                CacheGroups:      tmc.CacheGroups,
                Config:           tmc.Config,
@@ -426,7 +447,25 @@ type TMParameters struct {
        HealthPollingType       string `json:"health.polling.type"`
        HistoryCount            int    `json:"history.count"`
        MinFreeKbps             int64
-       Thresholds              map[string]HealthThreshold 
`json:"health_threshold"`
+       // HealthThresholdJSONParameters contains the Parameters contained in 
the
+       // Thresholds field, formatted as individual string Parameters, rather 
than as
+       // a JSON object.
+       Thresholds map[string]HealthThreshold 
`json:"health_threshold,omitempty"`
+       HealthThresholdJSONParameters
+}
+
+// HealthThresholdJSONParameters contains Parameters whose Thresholds must be 
met in order for
+// Caches using the Profile containing these Parameters to be marked as 
Healthy.
+type HealthThresholdJSONParameters struct {
+       // AvailableBandwidthInKbps is The total amount of bandwidth that 
servers using this profile are
+       // allowed, in Kilobits per second. This is a string and using 
comparison operators to specify
+       // ranges, e.g. ">10" means "more than 10 kbps".
+       AvailableBandwidthInKbps string 
`json:"health.threshold.availableBandwidthInKbps,omitempty"`
+       // LoadAverage is the UNIX loadavg at which the server should be marked 
"unhealthy".
+       LoadAverage string `json:"health.threshold.loadavg,omitempty"`
+       // QueryTime is the highest allowed length of time for completing 
health queries (after
+       // connection has been established) in milliseconds.
+       QueryTime string `json:"health.threshold.queryTime,omitempty"`
 }
 
 const DefaultHealthThresholdComparator = "<"
@@ -446,11 +485,11 @@ func (t HealthThreshold) String() string {
        return fmt.Sprintf("%s%f", t.Comparator, t.Val)
 }
 
-// strToThreshold takes a string like ">=42" and returns a HealthThreshold with
+// StrToThreshold takes a string like ">=42" and returns a HealthThreshold with
 // a Val of `42` and a Comparator of `">="`. If no comparator exists,
 // `DefaultHealthThresholdComparator` is used. If the string does not match
 // "(>|<|)(=|)\d+" an error is returned.
-func strToThreshold(s string) (HealthThreshold, error) {
+func StrToThreshold(s string) (HealthThreshold, error) {
        // The order of these is important - don't re-order without considering 
the
        // consequences.
        comparators := []string{">=", "<=", ">", "<", "="}
@@ -523,7 +562,7 @@ func (params *TMParameters) UnmarshalJSON(bytes []byte) 
(err error) {
                if strings.HasPrefix(k, ThresholdPrefix) {
                        stat := k[len(ThresholdPrefix):]
                        vStr := fmt.Sprintf("%v", v) // allows string or 
numeric JSON types. TODO check if a type switch is faster.
-                       if t, err := strToThreshold(vStr); err != nil {
+                       if t, err := StrToThreshold(vStr); err != nil {
                                return fmt.Errorf("Unmarshalling TMParameters 
`%s` parameter value not of the form `(>|)(=|)\\d+`: stat '%s' value '%v': %v", 
ThresholdPrefix, k, v, err)
                        } else {
                                params.Thresholds[stat] = t
diff --git a/traffic_ops/testing/api/v1/crconfig_test.go 
b/traffic_ops/testing/api/v1/crconfig_test.go
index e02a0c8..d964029 100644
--- a/traffic_ops/testing/api/v1/crconfig_test.go
+++ b/traffic_ops/testing/api/v1/crconfig_test.go
@@ -26,6 +26,7 @@ import (
 func TestCRConfig(t *testing.T) {
        WithObjs(t, []TCObj{CDNs, Types, Tenants, Parameters, Profiles, 
Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, 
DeliveryServices}, func() {
                UpdateTestCRConfigSnapshot(t)
+               MonitoringConfig(t)
                SnapshotTestCDNbyName(t)
                SnapshotTestCDNbyInvalidName(t)
                SnapshotTestCDNbyID(t)
@@ -35,7 +36,7 @@ func TestCRConfig(t *testing.T) {
 
 func UpdateTestCRConfigSnapshot(t *testing.T) {
        if len(testData.CDNs) < 1 {
-               t.Error("no cdn test data")
+               t.Fatalf("no cdn test data")
        }
        cdn := testData.CDNs[0].Name
 
@@ -156,6 +157,86 @@ func UpdateTestCRConfigSnapshot(t *testing.T) {
        }
 }
 
+func MonitoringConfig(t *testing.T) {
+       if len(testData.CDNs) < 1 {
+               t.Fatalf("no cdn test data")
+       }
+       const cdnName = "cdn1"
+       const profileName = "EDGE1"
+       cdns, _, err := TOSession.GetCDNByName(cdnName)
+       if err != nil {
+               t.Fatalf("getting CDNs with name '%s': %s", cdnName, 
err.Error())
+       }
+       if len(cdns) < 1 {
+               t.Fatalf("expected to find a CDN named %s", cdnName)
+       }
+       if len(cdns) > 1 {
+               t.Fatalf("expected exactly 1 CDN named %s but found %d CDNs", 
cdnName, len(cdns))
+       }
+       profiles, _, err := TOSession.GetProfileByName(profileName)
+       if err != nil {
+               t.Fatalf("getting Profiles with name '%s': %s", profileName, 
err.Error())
+       }
+       if len(profiles) != 1 {
+               t.Fatalf("expected exactly 1 Profiles named %s but found %d 
Profiles", profileName, len(profiles))
+       }
+       parameters, _, err := TOSession.GetParametersByProfileName(profileName)
+       if err != nil {
+               t.Fatalf("getting Parameters by Profile name '%s': %s", 
profileName, err.Error())
+       }
+       parameterMap := map[string]tc.HealthThreshold{}
+       parameterFound := map[string]bool{}
+       const thresholdPrefixLength = len(tc.ThresholdPrefix)
+       for _, parameter := range parameters {
+               if !strings.HasPrefix(parameter.Name, tc.ThresholdPrefix) {
+                       continue
+               }
+               parameterName := parameter.Name[thresholdPrefixLength:]
+               parameterMap[parameterName], err = 
tc.StrToThreshold(parameter.Value)
+               if err != nil {
+                       t.Fatalf("converting string '%s' to HealthThreshold: 
%s", parameter.Value, err.Error())
+               }
+               parameterFound[parameterName] = false
+       }
+       const expectedThresholdParameters = 3
+       if len(parameterMap) != expectedThresholdParameters {
+               t.Fatalf("expected Profile '%s' to contain %d Parameters with 
names starting with '%s' but %d such Parameters were found", profileName, 
expectedThresholdParameters, tc.ThresholdPrefix, len(parameterMap))
+       }
+       tmConfig, _, err := TOSession.GetTrafficMonitorConfig(cdnName)
+       if err != nil {
+               t.Fatalf("getting Traffic Monitor Config: %s", err.Error())
+       }
+       profileFound := false
+       var profile tc.TMProfile
+       for _, profile = range tmConfig.Profiles {
+               if profile.Name == profileName {
+                       profileFound = true
+                       break
+               }
+       }
+       if !profileFound {
+               t.Fatalf("Traffic Monitor Config contained no Profile named 
'%s", profileName)
+       }
+       for parameterName, value := range profile.Parameters.Thresholds {
+               if _, ok := parameterFound[parameterName]; !ok {
+                       t.Fatalf("unexpected Threshold Parameter name '%s' 
found in Profile '%s' in Traffic Monitor Config", parameterName, profileName)
+               }
+               parameterFound[parameterName] = true
+               if parameterMap[parameterName].String() != value.String() {
+                       t.Fatalf("expected '%s' but received '%s' for Threshold 
Parameter '%s' in Profile '%s' in Traffic Monitor Config", 
parameterMap[parameterName].String(), value.String(), parameterName, 
profileName)
+               }
+       }
+       missingParameters := []string{}
+       for parameterName, found := range parameterFound {
+               if !found {
+                       missingParameters = append(missingParameters, 
parameterName)
+               }
+       }
+       if len(missingParameters) != 0 {
+               t.Fatalf("Threshold parameters defined for Profile '%s' but 
missing for Profile '%s' in Traffic Monitor Config: %s", profileName, 
profileName, strings.Join(missingParameters, ", "))
+       }
+}
+
 func SnapshotTestCDNbyName(t *testing.T) {
 
        firstCDN := testData.CDNs[0]
diff --git a/traffic_ops/testing/api/v1/tc-fixtures.json 
b/traffic_ops/testing/api/v1/tc-fixtures.json
index 20af859..1c45592 100644
--- a/traffic_ops/testing/api/v1/tc-fixtures.json
+++ b/traffic_ops/testing/api/v1/tc-fixtures.json
@@ -794,20 +794,6 @@
     "parameters": [
         {
             "configFile": "rascal.properties",
-            "lastUpdated": "2018-01-19T19:01:21.455131+00:00",
-            "name": "health.threshold.loadavg",
-            "secure": false,
-            "value": "25.0"
-        },
-        {
-            "configFile": "rascal.properties",
-            "lastUpdated": "2018-01-19T19:01:21.472279+00:00",
-            "name": "health.threshold.availableBandwidthInKbps",
-            "secure": false,
-            "value": ">1750000"
-        },
-        {
-            "configFile": "rascal.properties",
             "lastUpdated": "2018-01-19T19:01:21.489534+00:00",
             "name": "history.count",
             "secure": false,
@@ -1363,7 +1349,27 @@
             "lastUpdated": "2018-03-02T17:27:11.818418+00:00",
             "name": "EDGE1",
             "routing_disabled": false,
-            "type": "ATS_PROFILE"
+            "type": "ATS_PROFILE",
+            "params": [
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.loadavg",
+                    "secure": false,
+                    "value": "25.0"
+                },
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.availableBandwidthInKbps",
+                    "secure": false,
+                    "value": ">1750000"
+                },
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.queryTime",
+                    "secure": false,
+                    "value": "1000"
+                }
+            ]
         },
         {
             "cdnName": "cdn2",
diff --git a/traffic_ops/testing/api/v2/crconfig_test.go 
b/traffic_ops/testing/api/v2/crconfig_test.go
index c5d2c57..ab9dae5 100644
--- a/traffic_ops/testing/api/v2/crconfig_test.go
+++ b/traffic_ops/testing/api/v2/crconfig_test.go
@@ -26,6 +26,7 @@ import (
 func TestCRConfig(t *testing.T) {
        WithObjs(t, []TCObj{CDNs, Types, Tenants, Parameters, Profiles, 
Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, 
DeliveryServices}, func() {
                UpdateTestCRConfigSnapshot(t)
+               MonitoringConfig(t)
                SnapshotTestCDNbyName(t)
                SnapshotTestCDNbyInvalidName(t)
                SnapshotTestCDNbyID(t)
@@ -35,7 +36,7 @@ func TestCRConfig(t *testing.T) {
 
 func UpdateTestCRConfigSnapshot(t *testing.T) {
        if len(testData.CDNs) < 1 {
-               t.Error("no cdn test data")
+               t.Fatalf("no cdn test data")
        }
        cdn := testData.CDNs[0].Name
 
@@ -156,6 +157,86 @@ func UpdateTestCRConfigSnapshot(t *testing.T) {
        }
 }
 
+func MonitoringConfig(t *testing.T) {
+       if len(testData.CDNs) < 1 {
+               t.Fatalf("no cdn test data")
+       }
+       const cdnName = "cdn1"
+       const profileName = "EDGE1"
+       cdns, _, err := TOSession.GetCDNByName(cdnName)
+       if err != nil {
+               t.Fatalf("getting CDNs with name '%s': %s", cdnName, 
err.Error())
+       }
+       if len(cdns) < 1 {
+               t.Fatalf("expected to find a CDN named %s", cdnName)
+       }
+       if len(cdns) > 1 {
+               t.Fatalf("expected exactly 1 CDN named %s but found %d CDNs", 
cdnName, len(cdns))
+       }
+       profiles, _, err := TOSession.GetProfileByName(profileName)
+       if err != nil {
+               t.Fatalf("getting Profiles with name '%s': %s", profileName, 
err.Error())
+       }
+       if len(profiles) != 1 {
+               t.Fatalf("expected exactly 1 Profiles named %s but found %d 
Profiles", profileName, len(profiles))
+       }
+       parameters, _, err := TOSession.GetParametersByProfileName(profileName)
+       if err != nil {
+               t.Fatalf("getting Parameters by Profile name '%s': %s", 
profileName, err.Error())
+       }
+       parameterMap := map[string]tc.HealthThreshold{}
+       parameterFound := map[string]bool{}
+       const thresholdPrefixLength = len(tc.ThresholdPrefix)
+       for _, parameter := range parameters {
+               if !strings.HasPrefix(parameter.Name, tc.ThresholdPrefix) {
+                       continue
+               }
+               parameterName := parameter.Name[thresholdPrefixLength:]
+               parameterMap[parameterName], err = 
tc.StrToThreshold(parameter.Value)
+               if err != nil {
+                       t.Fatalf("converting string '%s' to HealthThreshold: 
%s", parameter.Value, err.Error())
+               }
+               parameterFound[parameterName] = false
+       }
+       const expectedThresholdParameters = 3
+       if len(parameterMap) != expectedThresholdParameters {
+               t.Fatalf("expected Profile '%s' to contain %d Parameters with 
names starting with '%s' but %d such Parameters were found", profileName, 
expectedThresholdParameters, tc.ThresholdPrefix, len(parameterMap))
+       }
+       tmConfig, _, err := TOSession.GetTrafficMonitorConfig(cdnName)
+       if err != nil {
+               t.Fatalf("getting Traffic Monitor Config: %s", err.Error())
+       }
+       profileFound := false
+       var profile tc.TMProfile
+       for _, profile = range tmConfig.Profiles {
+               if profile.Name == profileName {
+                       profileFound = true
+                       break
+               }
+       }
+       if !profileFound {
+               t.Fatalf("Traffic Monitor Config contained no Profile named 
'%s", profileName)
+       }
+       for parameterName, value := range profile.Parameters.Thresholds {
+               if _, ok := parameterFound[parameterName]; !ok {
+                       t.Fatalf("unexpected Threshold Parameter name '%s' 
found in Profile '%s' in Traffic Monitor Config", parameterName, profileName)
+               }
+               parameterFound[parameterName] = true
+               if parameterMap[parameterName].String() != value.String() {
+                       t.Fatalf("expected '%s' but received '%s' for Threshold 
Parameter '%s' in Profile '%s' in Traffic Monitor Config", 
parameterMap[parameterName].String(), value.String(), parameterName, 
profileName)
+               }
+       }
+       missingParameters := []string{}
+       for parameterName, found := range parameterFound {
+               if !found {
+                       missingParameters = append(missingParameters, 
parameterName)
+               }
+       }
+       if len(missingParameters) != 0 {
+               t.Fatalf("Threshold parameters defined for Profile '%s' but 
missing for Profile '%s' in Traffic Monitor Config: %s", profileName, 
profileName, strings.Join(missingParameters, ", "))
+       }
+}
+
 func SnapshotTestCDNbyName(t *testing.T) {
 
        firstCDN := testData.CDNs[0]
diff --git a/traffic_ops/testing/api/v2/tc-fixtures.json 
b/traffic_ops/testing/api/v2/tc-fixtures.json
index e8046de..cb5e1ac 100644
--- a/traffic_ops/testing/api/v2/tc-fixtures.json
+++ b/traffic_ops/testing/api/v2/tc-fixtures.json
@@ -825,20 +825,6 @@
     "parameters": [
         {
             "configFile": "rascal.properties",
-            "lastUpdated": "2018-01-19T19:01:21.455131+00:00",
-            "name": "health.threshold.loadavg",
-            "secure": false,
-            "value": "25.0"
-        },
-        {
-            "configFile": "rascal.properties",
-            "lastUpdated": "2018-01-19T19:01:21.472279+00:00",
-            "name": "health.threshold.availableBandwidthInKbps",
-            "secure": false,
-            "value": ">1750000"
-        },
-        {
-            "configFile": "rascal.properties",
             "lastUpdated": "2018-01-19T19:01:21.489534+00:00",
             "name": "history.count",
             "secure": false,
@@ -1387,7 +1373,27 @@
             "lastUpdated": "2018-03-02T17:27:11.818418+00:00",
             "name": "EDGE1",
             "routing_disabled": false,
-            "type": "ATS_PROFILE"
+            "type": "ATS_PROFILE",
+            "params": [
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.loadavg",
+                    "secure": false,
+                    "value": "25.0"
+                },
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.availableBandwidthInKbps",
+                    "secure": false,
+                    "value": ">1750000"
+                },
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.queryTime",
+                    "secure": false,
+                    "value": "1000"
+                }
+            ]
         },
         {
             "cdnName": "cdn2",
diff --git a/traffic_ops/testing/api/v3/crconfig_test.go 
b/traffic_ops/testing/api/v3/crconfig_test.go
index 1a651f7..b3db34c 100644
--- a/traffic_ops/testing/api/v3/crconfig_test.go
+++ b/traffic_ops/testing/api/v3/crconfig_test.go
@@ -26,6 +26,7 @@ import (
 func TestCRConfig(t *testing.T) {
        WithObjs(t, []TCObj{CDNs, Types, Tenants, Parameters, Profiles, 
Statuses, Divisions, Regions, PhysLocations, CacheGroups, Servers, Topologies, 
DeliveryServices}, func() {
                UpdateTestCRConfigSnapshot(t)
+               MonitoringConfig(t)
                SnapshotTestCDNbyName(t)
                SnapshotTestCDNbyInvalidName(t)
                SnapshotTestCDNbyID(t)
@@ -157,6 +158,86 @@ func UpdateTestCRConfigSnapshot(t *testing.T) {
        }
 }
 
+func MonitoringConfig(t *testing.T) {
+       if len(testData.CDNs) < 1 {
+               t.Fatalf("no cdn test data")
+       }
+       const cdnName = "cdn1"
+       const profileName = "EDGE1"
+       cdns, _, err := TOSession.GetCDNByNameWithHdr(cdnName, nil)
+       if err != nil {
+               t.Fatalf("getting CDNs with name '%s': %s", cdnName, 
err.Error())
+       }
+       if len(cdns) < 1 {
+               t.Fatalf("expected to find a CDN named %s", cdnName)
+       }
+       if len(cdns) > 1 {
+               t.Fatalf("expected exactly 1 CDN named %s but found %d CDNs", 
cdnName, len(cdns))
+       }
+       profiles, _, err := TOSession.GetProfileByNameWithHdr(profileName, nil)
+       if err != nil {
+               t.Fatalf("getting Profiles with name '%s': %s", profileName, 
err.Error())
+       }
+       if len(profiles) != 1 {
+               t.Fatalf("expected exactly 1 Profiles named %s but found %d 
Profiles", profileName, len(profiles))
+       }
+       parameters, _, err := 
TOSession.GetParametersByProfileNameWithHdr(profileName, nil)
+       if err != nil {
+               t.Fatalf("getting Parameters by Profile name '%s': %s", 
profileName, err.Error())
+       }
+       parameterMap := map[string]tc.HealthThreshold{}
+       parameterFound := map[string]bool{}
+       const thresholdPrefixLength = len(tc.ThresholdPrefix)
+       for _, parameter := range parameters {
+               if !strings.HasPrefix(parameter.Name, tc.ThresholdPrefix) {
+                       continue
+               }
+               parameterName := parameter.Name[thresholdPrefixLength:]
+               parameterMap[parameterName], err = 
tc.StrToThreshold(parameter.Value)
+               if err != nil {
+                       t.Fatalf("converting string '%s' to HealthThreshold: 
%s", parameter.Value, err.Error())
+               }
+               parameterFound[parameterName] = false
+       }
+       const expectedThresholdParameters = 3
+       if len(parameterMap) != expectedThresholdParameters {
+               t.Fatalf("expected Profile '%s' to contain %d Parameters with 
names starting with '%s' but %d such Parameters were found", profileName, 
expectedThresholdParameters, tc.ThresholdPrefix, len(parameterMap))
+       }
+       tmConfig, _, err := TOSession.GetTrafficMonitorConfig(cdnName)
+       if err != nil {
+               t.Fatalf("getting Traffic Monitor Config: %s", err.Error())
+       }
+       profileFound := false
+       var profile tc.TMProfile
+       for _, profile = range tmConfig.Profiles {
+               if profile.Name == profileName {
+                       profileFound = true
+                       break
+               }
+       }
+       if !profileFound {
+               t.Fatalf("Traffic Monitor Config contained no Profile named 
'%s", profileName)
+       }
+       for parameterName, value := range profile.Parameters.Thresholds {
+               if _, ok := parameterFound[parameterName]; !ok {
+                       t.Fatalf("unexpected Threshold Parameter name '%s' 
found in Profile '%s' in Traffic Monitor Config", parameterName, profileName)
+               }
+               parameterFound[parameterName] = true
+               if parameterMap[parameterName].String() != value.String() {
+                       t.Fatalf("expected '%s' but received '%s' for Threshold 
Parameter '%s' in Profile '%s' in Traffic Monitor Config", 
parameterMap[parameterName].String(), value.String(), parameterName, 
profileName)
+               }
+       }
+       missingParameters := []string{}
+       for parameterName, found := range parameterFound {
+               if !found {
+                       missingParameters = append(missingParameters, 
parameterName)
+               }
+       }
+       if len(missingParameters) != 0 {
+               t.Fatalf("Threshold parameters defined for Profile '%s' but 
missing for Profile '%s' in Traffic Monitor Config: %s", profileName, 
profileName, strings.Join(missingParameters, ", "))
+       }
+}
+
 func SnapshotTestCDNbyName(t *testing.T) {
 
        firstCDN := testData.CDNs[0]
diff --git a/traffic_ops/testing/api/v3/tc-fixtures.json 
b/traffic_ops/testing/api/v3/tc-fixtures.json
index bb24c57..10c2d0f 100644
--- a/traffic_ops/testing/api/v3/tc-fixtures.json
+++ b/traffic_ops/testing/api/v3/tc-fixtures.json
@@ -1668,20 +1668,6 @@
     "parameters": [
         {
             "configFile": "rascal.properties",
-            "lastUpdated": "2018-01-19T19:01:21.455131+00:00",
-            "name": "health.threshold.loadavg",
-            "secure": false,
-            "value": "25.0"
-        },
-        {
-            "configFile": "rascal.properties",
-            "lastUpdated": "2018-01-19T19:01:21.472279+00:00",
-            "name": "health.threshold.availableBandwidthInKbps",
-            "secure": false,
-            "value": ">1750000"
-        },
-        {
-            "configFile": "rascal.properties",
             "lastUpdated": "2018-01-19T19:01:21.489534+00:00",
             "name": "history.count",
             "secure": false,
@@ -2248,7 +2234,27 @@
             "lastUpdated": "2018-03-02T17:27:11.818418+00:00",
             "name": "EDGE1",
             "routing_disabled": false,
-            "type": "ATS_PROFILE"
+            "type": "ATS_PROFILE",
+            "params": [
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.loadavg",
+                    "secure": false,
+                    "value": "25.0"
+                },
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.availableBandwidthInKbps",
+                    "secure": false,
+                    "value": ">1750000"
+                },
+                {
+                    "configFile": "rascal.properties",
+                    "name": "health.threshold.queryTime",
+                    "secure": false,
+                    "value": "1000"
+                }
+            ]
         },
         {
             "cdnName": "cdn2",

Reply via email to