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)
+ }
+}