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

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


The following commit(s) were added to refs/heads/master by this push:
     new e2fecc1  Adding check for safer conversion between types (#5600)
e2fecc1 is described below

commit e2fecc1997cb5539590b94d534027ef530de2777
Author: Srijeet Chatterjee <[email protected]>
AuthorDate: Tue Mar 9 14:45:49 2021 -0700

    Adding check for safer conversion between types (#5600)
    
    * Adding check for safer conversion between types
    
    * code review
    
    * code review
    
    * code review
---
 CHANGELOG.md                                       |   1 +
 .../traffic_ops_golang/cachesstats/cachesstats.go  |  29 +++-
 .../cachesstats/cachesstats_test.go                | 182 +++++++++++++++++++++
 3 files changed, 206 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e9bc0b..703e8dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -30,6 +30,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - Added an endpoint for statuses on asynchronous jobs and applied it to the 
ACME renewal endpoint.
 
 ### Fixed
+- [#5565](https://github.com/apache/trafficcontrol/issues/5565) - TO GET 
/caches/stats panic converting string to uint64
 - [#5558](https://github.com/apache/trafficcontrol/issues/5558) - Fixed `TM 
UI` and `/api/cache-statuses` to report aggregate `bandwidth_kbps` correctly.
 - [#5288](https://github.com/apache/trafficcontrol/issues/5288) - Fixed the 
ability to create and update a server with MTU value >= 1280.
 - [#5445](https://github.com/apache/trafficcontrol/issues/5445) - When 
updating a registered user, ignore updates on registration_sent field.
diff --git a/traffic_ops/traffic_ops_golang/cachesstats/cachesstats.go 
b/traffic_ops/traffic_ops_golang/cachesstats/cachesstats.go
index 540755d..cf3e175 100644
--- a/traffic_ops/traffic_ops_golang/cachesstats/cachesstats.go
+++ b/traffic_ops/traffic_ops_golang/cachesstats/cachesstats.go
@@ -79,19 +79,21 @@ func getCachesStats(tx *sql.Tx) ([]CacheData, error) {
                        }
 
                        var cacheStats tc.Stats
+                       var url string
                        stats := []string{ATSCurrentConnectionsStat, 
tc.StatNameBandwidth}
-                       cacheStats, _, err = 
monitorhlp.GetCacheStats(monitorFQDN, client, stats)
+                       cacheStats, url, err = 
monitorhlp.GetCacheStats(monitorFQDN, client, stats)
                        if err != nil {
-                               legacyCacheStats, _, err := 
monitorhlp.GetLegacyCacheStats(monitorFQDN, client, stats)
+                               legacyCacheStats, legacyUrl, err := 
monitorhlp.GetLegacyCacheStats(monitorFQDN, client, stats)
                                if err != nil {
                                        errs = append(errs, errors.New("getting 
CacheStats for CDN '"+string(cdn)+"' monitor '"+monitorFQDN+"': "+err.Error()))
                                        continue
                                }
+                               url = legacyUrl
                                cacheStats = 
monitorhlp.UpgradeLegacyStats(legacyCacheStats)
                        }
 
                        cacheData = addHealth(cacheData, crStates)
-                       cacheData = addStats(cacheData, cacheStats)
+                       cacheData = addStats(cacheData, cacheStats, url)
                        success = true
                        break
                }
@@ -135,7 +137,8 @@ func addTotals(data []CacheData) []CacheData {
        return data
 }
 
-func addStats(cacheData []CacheData, stats tc.Stats) []CacheData {
+func addStats(cacheData []CacheData, stats tc.Stats, url string) []CacheData {
+       var err error
        if stats.Caches == nil {
                return cacheData // TODO warn?
        }
@@ -146,11 +149,25 @@ func addStats(cacheData []CacheData, stats tc.Stats) 
[]CacheData {
                }
                bandwidth, ok := stat.Stats[tc.StatNameBandwidth]
                if ok && len(bandwidth) > 0 {
-                       cache.KBPS = bandwidth[0].Val.(uint64)
+                       if kbps, ok := bandwidth[0].Val.(string); !ok {
+                               log.Warnf("bandwidth %v of cache %s from url %s 
couldn't be converted into string", bandwidth[0].Val, string(cache.HostName), 
url)
+                       } else {
+                               cache.KBPS, err = strconv.ParseUint(kbps, 10, 
64)
+                               if err != nil {
+                                       log.Warnf("'bandwidth' stat %v of cache 
%s from url %s couldn't be converted into uint64", kbps, 
string(cache.HostName), url)
+                               }
+                       }
                }
                connections, ok := stat.Stats[ATSCurrentConnectionsStat]
                if ok && len(connections) > 0 {
-                       cache.Connections = connections[0].Val.(uint64)
+                       if conn, ok := connections[0].Val.(string); !ok {
+                               log.Warnf("'connections' stat %v of cache %s 
from url %s couldn't be converted into string", connections[0].Val, 
string(cache.HostName), url)
+                       } else {
+                               cache.Connections, err = 
strconv.ParseUint(conn, 10, 64)
+                               if err != nil {
+                                       log.Warnf("'connections' stat %v of 
cache %s from url %s couldn't be converted into uint64", conn, 
string(cache.HostName), url)
+                               }
+                       }
                }
                cacheData[i] = cache
        }
diff --git a/traffic_ops/traffic_ops_golang/cachesstats/cachesstats_test.go 
b/traffic_ops/traffic_ops_golang/cachesstats/cachesstats_test.go
new file mode 100644
index 0000000..4233949
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/cachesstats/cachesstats_test.go
@@ -0,0 +1,182 @@
+package cachesstats
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 (
+       "encoding/json"
+       "testing"
+       "time"
+
+       "github.com/apache/trafficcontrol/lib/go-tc"
+       "github.com/apache/trafficcontrol/lib/go-util"
+)
+
+func TestAddStatsInvalidString(t *testing.T) {
+       cacheData := make([]CacheData, 0)
+       cacheServerStats := make(map[string]tc.ServerStats, 0)
+       stats := make(map[string][]tc.ResultStatVal, 0)
+       resultStatVals := make([]tc.ResultStatVal, 0)
+       resultStatVal := tc.ResultStatVal{
+               Span: 0,
+               Time: time.Now(),
+               Val:  "invalid bandwidth",
+       }
+       resultStatVals = append(resultStatVals, resultStatVal)
+       stats[tc.StatNameBandwidth] = resultStatVals
+
+       resultStatVal = tc.ResultStatVal{
+               Span: 0,
+               Time: time.Now(),
+               Val:  "invalid ats current connection stat",
+       }
+       resultStatVals = make([]tc.ResultStatVal, 0)
+       resultStatVals = append(resultStatVals, resultStatVal)
+       stats[ATSCurrentConnectionsStat] = resultStatVals
+
+       cacheServerStats["hostName"] = tc.ServerStats{
+               Interfaces: nil,
+               Stats:      stats,
+       }
+       cacheStats := tc.Stats{
+               CommonAPIData: tc.CommonAPIData{},
+               Caches:        cacheServerStats,
+       }
+       data := CacheData{
+               HostName:    "hostName",
+               CacheGroup:  "cacheGroup",
+               Status:      "ONLINE",
+               Profile:     "profile",
+               IP:          util.StrPtr("127.30.30.30"),
+               Healthy:     true,
+               KBPS:        0,
+               Connections: 0,
+       }
+       cacheData = append(cacheData, data)
+       result := addStats(cacheData, cacheStats, "url")
+       if len(result) != 1 {
+               t.Fatalf("expected a cache stat in the response, but got 
nothing")
+       }
+       if result[0].KBPS != 0 || result[0].Connections != 0 {
+               t.Errorf("expected 0 KBPS and 0 connections, but got %v and %v 
respectively", result[0].KBPS, result[0].Connections)
+       }
+}
+
+func TestAddStatsValidString(t *testing.T) {
+       cacheData := make([]CacheData, 0)
+       cacheServerStats := make(map[string]tc.ServerStats, 0)
+       stats := make(map[string][]tc.ResultStatVal, 0)
+       resultStatVals := make([]tc.ResultStatVal, 0)
+       resultStatVal := tc.ResultStatVal{
+               Span: 0,
+               Time: time.Now(),
+               Val:  "200",
+       }
+       resultStatVals = append(resultStatVals, resultStatVal)
+       stats[tc.StatNameBandwidth] = resultStatVals
+
+       resultStatVal = tc.ResultStatVal{
+               Span: 0,
+               Time: time.Now(),
+               Val:  "100",
+       }
+       resultStatVals = make([]tc.ResultStatVal, 0)
+       resultStatVals = append(resultStatVals, resultStatVal)
+       stats[ATSCurrentConnectionsStat] = resultStatVals
+
+       cacheServerStats["hostName"] = tc.ServerStats{
+               Interfaces: nil,
+               Stats:      stats,
+       }
+       cacheStats := tc.Stats{
+               CommonAPIData: tc.CommonAPIData{},
+               Caches:        cacheServerStats,
+       }
+       data := CacheData{
+               HostName:    "hostName",
+               CacheGroup:  "cacheGroup",
+               Status:      "ONLINE",
+               Profile:     "profile",
+               IP:          util.StrPtr("127.30.30.30"),
+               Healthy:     true,
+               KBPS:        0,
+               Connections: 0,
+       }
+       cacheData = append(cacheData, data)
+       result := addStats(cacheData, cacheStats, "url")
+       if len(result) != 1 {
+               t.Fatalf("expected a cache stat in the response, but got 
nothing")
+       }
+       if result[0].KBPS != 200 || result[0].Connections != 100 {
+               t.Errorf("expected 200 KBPS and 100 connections, but got %v and 
%v respectively", result[0].KBPS, result[0].Connections)
+       }
+}
+
+func TestAddStatsEmptyJsonObject(t *testing.T) {
+       cacheData := make([]CacheData, 0)
+       cacheServerStats := make(map[string]tc.ServerStats, 0)
+       stats := make(map[string][]tc.ResultStatVal, 0)
+       resultStatVals := make([]tc.ResultStatVal, 0)
+       type testJson struct{}
+       var req testJson
+       _ = json.Unmarshal([]byte(""), &req)
+       resultStatVal := tc.ResultStatVal{
+               Span: 0,
+               Time: time.Now(),
+               Val:  req,
+       }
+       resultStatVals = append(resultStatVals, resultStatVal)
+       stats[tc.StatNameBandwidth] = resultStatVals
+
+       resultStatVal = tc.ResultStatVal{
+               Span: 0,
+               Time: time.Now(),
+               Val:  req,
+       }
+       resultStatVals = make([]tc.ResultStatVal, 0)
+       resultStatVals = append(resultStatVals, resultStatVal)
+       stats[ATSCurrentConnectionsStat] = resultStatVals
+
+       cacheServerStats["hostName"] = tc.ServerStats{
+               Interfaces: nil,
+               Stats:      stats,
+       }
+       cacheStats := tc.Stats{
+               CommonAPIData: tc.CommonAPIData{},
+               Caches:        cacheServerStats,
+       }
+       data := CacheData{
+               HostName:    "hostName",
+               CacheGroup:  "cacheGroup",
+               Status:      "ONLINE",
+               Profile:     "profile",
+               IP:          util.StrPtr("127.30.30.30"),
+               Healthy:     true,
+               KBPS:        0,
+               Connections: 0,
+       }
+       cacheData = append(cacheData, data)
+       result := addStats(cacheData, cacheStats, "url")
+       if len(result) != 1 {
+               t.Fatalf("expected a cache stat in the response, but got 
nothing")
+       }
+       if result[0].KBPS != 0 || result[0].Connections != 0 {
+               t.Errorf("expected 0 KBPS and 0 connections, but got %v and %v 
respectively", result[0].KBPS, result[0].Connections)
+       }
+}

Reply via email to