blob: af8bbcb6c7cc02754f75f70a62c1f9f1e8c13f43 [file] [log] [blame]
package monitoring
import (
"context"
"reflect"
"sort"
"strconv"
"strings"
"testing"
"time"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/lib/go-util"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
"github.com/jmoiron/sqlx"
"github.com/lib/pq"
"gopkg.in/DATA-DOG/go-sqlmock.v1"
)
/*
* 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.
*/
func TestGetMonitoringServers(t *testing.T) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
cdn := "mycdn"
monitor := createMockMonitor()
router := createMockRouter()
cache := createMockCache("test")
// Different caches with the 'same' interfaces (in value only)
otherCache := createMockCache("test")
otherCache.Type = "MID"
cacheID := uint64(1)
otherCacheID := uint64(2)
cache3 := createMockCache("test")
cache3.Type = "MID"
cache3.Status = string(tc.CacheStatusOffline) // should be ignored
cache3ID := uint64(3)
mock.ExpectBegin()
setupMockGetMonitoringServers(mock, monitor, router, []Cache{cache, otherCache, cache3}, []uint64{cacheID, otherCacheID, cache3ID}, cdn)
dbCtx, f := context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
monitors, caches, routers, err := getMonitoringServers(tx, cdn)
if err != nil {
t.Fatalf("getMonitoringServers expected: nil error, actual: %v", err)
}
if len(caches) != 2 {
t.Fatalf("got %v caches, expecting 2", len(caches))
}
for _, cacheServer := range caches {
var testCache Cache
if cacheServer.Type == cache.Type {
testCache = cache
} else {
testCache = otherCache
}
for _, interf := range testCache.Interfaces {
if len(interf.IPAddresses) != 4 {
t.Errorf("cache: %v, interface: %v, expected 4 ip addresses, got %v", testCache.HostName, interf.Name, len(interf.IPAddresses))
}
}
}
if len(monitors) != 1 {
t.Fatalf("getMonitoringServers expected: len(monitors) == 1, actual: %v", len(monitors))
}
sqlMonitor := monitors[0]
if sqlMonitor != monitor {
t.Errorf("getMonitoringServers expected: monitor == %+v, actual: %+v", monitor, sqlMonitor)
}
if len(routers) != 1 {
t.Errorf("getMonitoringServers expected: len(routers) == 1, actual: %v", len(routers))
}
sqlRouter := routers[0]
if sqlRouter != router {
t.Errorf("getMonitoringServers expected: router == %+v, actual: %+v", router, sqlRouter)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
// Now test by setting the monitor without an IPv4 address
monitor.IP = ""
mock.ExpectBegin()
setupMockGetMonitoringServersWithoutIPv4(mock, monitor, router, []Cache{cache, otherCache, cache3}, []uint64{cacheID, otherCacheID, cache3ID}, cdn)
dbCtx, f = context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
defer f()
tx, err = db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
monitors, _, _, err = getMonitoringServers(tx, cdn)
if err != nil {
t.Fatalf("getMonitoringServers expected: nil error, actual: %v", err)
}
if len(monitors) != 1 {
t.Fatalf("getMonitoringServers expected: len(monitors) == 1, actual: %v", len(monitors))
}
sqlMonitor = monitors[0]
if sqlMonitor != monitor {
t.Errorf("getMonitoringServers expected: monitor == %+v, actual: %+v", monitor, sqlMonitor)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
}
func TestGetProfileWithParams(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
cdn := "mycdn"
mock.ExpectBegin()
expected := ExpectedGetParams()
mockGetParams(mock, expected, cdn)
mock.ExpectCommit()
dbCtx, f := context.WithTimeout(context.TODO(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
defer tx.Commit()
actual, err := getConfig(tx, cdn)
if err != nil {
t.Fatalf("getConfig err expected: nil, actual: %v", err)
}
// Should be just one
for k, v := range actual {
if *expected[0].Name != k {
t.Fatalf("Expected param name %s doesn't match actual %s", *expected[0].Name, k)
}
if *expected[0].Value != strconv.Itoa(v.(int)) {
t.Fatalf("Expected param value %s doesn't match actual %s", *expected[0].Value, v)
}
}
}
func TestGetCachegroups(t *testing.T) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
cdn := "mycdn"
cachegroup := Cachegroup{
Name: "myCachegroup",
Coordinates: Coordinates{
Latitude: 42.42,
Longitude: 24.24,
},
}
mock.ExpectBegin()
rows := sqlmock.NewRows([]string{"name", "latitude", "longitude"})
rows = rows.AddRow(cachegroup.Name, cachegroup.Coordinates.Latitude, cachegroup.Coordinates.Longitude)
mock.ExpectQuery("SELECT").WithArgs(cdn).WillReturnRows(rows)
dbCtx, f := context.WithTimeout(context.TODO(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
sqlCachegroups, err := getCachegroups(tx, cdn)
if err != nil {
t.Errorf("getCachegroups expected: nil error, actual: %v", err)
}
if len(sqlCachegroups) != 1 {
t.Errorf("getCachegroups expected: len(monitors) == 1, actual: %v", len(sqlCachegroups))
}
sqlCachegroup := sqlCachegroups[0]
if sqlCachegroup != cachegroup {
t.Errorf("getMonitoringServers expected: cachegroup == %+v, actual: %+v", cachegroup, sqlCachegroup)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
}
func TestGetProfiles(t *testing.T) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
cache := createMockCache("test")
router := createMockRouter()
profiles := []Profile{
{
Name: router.Profile,
Type: RouterType,
Parameters: map[string]interface{}{
"param0": "param0Val",
"param1": "param1Val",
},
},
{
Name: cache.Profile,
Type: "myType2",
Parameters: map[string]interface{}{
"2param0": "2param0Val",
"2param1": "2param1Val",
},
},
}
mock.ExpectBegin()
rows := sqlmock.NewRows([]string{"profile", "name", "value"})
for _, profile := range profiles {
for paramName, paramVal := range profile.Parameters {
rows = rows.AddRow(profile.Name, paramName, paramVal)
}
}
caches := []Cache{cache}
routers := []Router{router}
profileNames := []string{"cacheProfile"}
mock.ExpectQuery("SELECT").WithArgs(pq.Array(profileNames), CacheMonitorConfigFile).WillReturnRows(rows)
dbCtx, f := context.WithTimeout(context.TODO(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
sqlProfiles, err := getProfiles(tx, caches, routers)
if err != nil {
t.Errorf("getProfiles expected: nil error, actual: %v", err)
}
if len(sqlProfiles) != len(profiles) {
t.Errorf("getProfiles expected: %+v actual: %+v", profiles, sqlProfiles)
}
profiles = sortProfiles(profiles)
sqlProfiles = sortProfiles(sqlProfiles)
for i, profile := range profiles {
if profile.Name != sqlProfiles[i].Name {
t.Errorf("getProfiles expected: profiles[%v].Name %v, actual: %v", i, profile.Name, sqlProfiles[i].Name)
}
for paramName, paramVal := range profile.Parameters {
val, ok := sqlProfiles[i].Parameters[paramName]
if !ok {
t.Errorf("getProfiles expected: profiles[%v].Parameters[%v] = %v, actual: %v", i, paramName, paramVal, val)
}
if val != paramVal {
t.Errorf("getProfiles expected: profiles[%v].Parameters[%v] = %v, actual: %v", i, paramName, paramVal, val)
}
}
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
}
func TestGetDeliveryServices(t *testing.T) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
deliveryservice := DeliveryService{
XMLID: "myDsid",
TotalTPSThreshold: 42.42,
Status: DeliveryServiceStatus,
TotalKBPSThreshold: 24.24,
Type: "HTTP",
Topology: "foo",
HostRegexes: []string{`.*\.example\..*`},
}
deliveryservices := []DeliveryService{deliveryservice}
mock.ExpectBegin()
rows := sqlmock.NewRows([]string{"xml_id", "global_max_tps", "global_max_mbps", "ds_type", "topology", "host_regexes"})
for _, deliveryservice := range deliveryservices {
rows = rows.AddRow(deliveryservice.XMLID, deliveryservice.TotalTPSThreshold, deliveryservice.TotalKBPSThreshold/KilobitsPerMegabit,
deliveryservice.Type, deliveryservice.Topology, "{"+strings.Join(deliveryservice.HostRegexes, ",")+"}")
}
mock.ExpectQuery("SELECT").WillReturnRows(rows)
dbCtx, f := context.WithTimeout(context.TODO(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
sqlDeliveryservices, err := getDeliveryServices(tx, "cdn")
if err != nil {
t.Errorf("getDeliveryServices expected: nil error, actual: %v", err)
}
if len(deliveryservices) != len(sqlDeliveryservices) {
t.Fatalf("getDeliveryServices expected: %+v actual: %+v", deliveryservices, sqlDeliveryservices)
}
for i, sqlDeliveryservice := range sqlDeliveryservices {
deliveryservice := deliveryservices[i]
if !reflect.DeepEqual(deliveryservice, sqlDeliveryservice) {
t.Errorf("getDeliveryServices expected: %v, actual: %v", deliveryservice, sqlDeliveryservice)
}
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
}
func TestGetConfig(t *testing.T) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
config := map[string]interface{}{
"name0": "val0",
"name1": "val1",
}
mock.ExpectBegin()
rows := sqlmock.NewRows([]string{"name", "value"})
for name, val := range config {
rows = rows.AddRow(name, val)
}
mock.ExpectQuery("SELECT").WithArgs(tc.MonitorProfilePrefix+"%%", MonitorConfigFile, "mycdn").WillReturnRows(rows)
dbCtx, f := context.WithTimeout(context.TODO(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
sqlConfig, err := getConfig(tx, "mycdn")
if err != nil {
t.Errorf("getProfiles expected: nil error, actual: %v", err)
}
if !reflect.DeepEqual(config, sqlConfig) {
t.Errorf("getConfig expected: %+v actual: %+v", config, sqlConfig)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
}
func TestGetMonitoringJSON(t *testing.T) {
resp := MonitoringResponse{}
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
cdn := "mycdn"
mock.ExpectBegin()
{
monitor := createMockMonitor()
cache := createMockCache("test")
router := createMockRouter()
setupMockGetMonitoringServers(mock, monitor, router, []Cache{cache}, []uint64{1}, cdn)
resp.Response.TrafficServers = []Cache{cache}
resp.Response.TrafficMonitors = []Monitor{monitor}
}
{
//
// getCachegroups
//
cachegroup := Cachegroup{
Name: "myCachegroup",
Coordinates: Coordinates{
Latitude: 42.42,
Longitude: 24.24,
},
}
rows := sqlmock.NewRows([]string{"name", "latitude", "longitude"})
rows = rows.AddRow(cachegroup.Name, cachegroup.Coordinates.Latitude, cachegroup.Coordinates.Longitude)
mock.ExpectQuery("SELECT").WithArgs(cdn).WillReturnRows(rows)
resp.Response.Cachegroups = []Cachegroup{cachegroup}
}
{
//
// getProfiles
//
cache := createMockCache("test")
router := createMockRouter()
profiles := []Profile{
Profile{
Name: router.Profile,
Type: RouterType,
Parameters: map[string]interface{}{
"param0": "param0Val",
"param1": "param1Val",
},
},
Profile{
Name: cache.Profile,
Type: "EDGE",
Parameters: map[string]interface{}{
"2param0": "2param0Val",
"2param1": "2param1Val",
},
},
}
rows := sqlmock.NewRows([]string{"profile", "name", "value"})
for _, profile := range profiles {
for paramName, paramVal := range profile.Parameters {
rows = rows.AddRow(profile.Name, paramName, paramVal)
}
}
// caches := []Cache{cache}
// routers := []Router{router}
profileNames := []string{"cacheProfile"}
mock.ExpectQuery("SELECT").WithArgs(pq.Array(profileNames), CacheMonitorConfigFile).WillReturnRows(rows)
resp.Response.Profiles = profiles
}
{
//
// getDeliveryServices
//
deliveryservice := DeliveryService{
XMLID: "myDsid",
TotalTPSThreshold: 42.42,
Status: DeliveryServiceStatus,
TotalKBPSThreshold: 24.24,
Type: "HTTP",
Topology: "foo",
HostRegexes: []string{`.*\.example\..*`},
}
deliveryservices := []DeliveryService{deliveryservice}
// routers := []Router{router}
rows := sqlmock.NewRows([]string{"xml_id", "global_max_tps", "global_max_mbps", "ds_type", "topology", "host_regexes"})
for _, deliveryservice := range deliveryservices {
rows = rows.AddRow(deliveryservice.XMLID, deliveryservice.TotalTPSThreshold, deliveryservice.TotalKBPSThreshold/KilobitsPerMegabit,
deliveryservice.Type, deliveryservice.Topology, "{"+strings.Join(deliveryservice.HostRegexes, ",")+"}")
}
mock.ExpectQuery("SELECT").WillReturnRows(rows)
resp.Response.DeliveryServices = deliveryservices
}
{
//
// getConfig
//
config := map[string]interface{}{
"name0": "val0",
"name1": "val1",
}
rows := sqlmock.NewRows([]string{"name", "value"})
for name, val := range config {
rows = rows.AddRow(name, val)
}
mock.ExpectQuery("SELECT").WillReturnRows(rows)
resp.Response.Config = config
}
{
//
// topologies
//
topologies := map[string]tc.CRConfigTopology{
"foo": {Nodes: []string{"cg1"}},
}
rows := sqlmock.NewRows([]string{"name", "nodes"})
for name, nodes := range topologies {
rows = rows.AddRow(name, "{"+strings.Join(nodes.Nodes, ",")+"}")
}
mock.ExpectQuery("SELECT").WillReturnRows(rows)
resp.Response.Topologies = topologies
}
dbCtx, f := context.WithTimeout(context.TODO(), time.Duration(10)*time.Second)
defer f()
tx, err := db.BeginTx(dbCtx, nil)
if err != nil {
t.Fatalf("creating transaction: %v", err)
}
sqlResp, err := GetMonitoringJSON(tx, cdn)
if err != nil {
t.Fatalf("GetMonitoringJSON expected: nil error, actual: %v", err)
}
for _, cache := range resp.Response.TrafficServers {
cache.Interfaces = sortInterfaces(cache.Interfaces)
}
for _, cache := range sqlResp.TrafficServers {
cache.Interfaces = sortInterfaces(cache.Interfaces)
}
resp.Response.TrafficServers = sortCaches(resp.Response.TrafficServers)
sqlResp.TrafficServers = sortCaches(sqlResp.TrafficServers)
resp.Response.TrafficMonitors = sortMonitors(resp.Response.TrafficMonitors)
sqlResp.TrafficMonitors = sortMonitors(sqlResp.TrafficMonitors)
resp.Response.Cachegroups = sortCachegroups(resp.Response.Cachegroups)
sqlResp.Cachegroups = sortCachegroups(sqlResp.Cachegroups)
resp.Response.Profiles = sortProfiles(resp.Response.Profiles)
sqlResp.Profiles = sortProfiles(sqlResp.Profiles)
resp.Response.DeliveryServices = sortDeliveryServices(resp.Response.DeliveryServices)
sqlResp.DeliveryServices = sortDeliveryServices(sqlResp.DeliveryServices)
if !reflect.DeepEqual(sqlResp.TrafficServers, resp.Response.TrafficServers) {
t.Errorf("GetMonitoringJSON expected TrafficServers: %+v actual: %+v", resp.Response.TrafficServers, sqlResp.TrafficServers)
}
if !reflect.DeepEqual(sqlResp.TrafficMonitors, resp.Response.TrafficMonitors) {
t.Errorf("GetMonitoringJSON expected TrafficMonitors: %+v actual: %+v", resp.Response.TrafficMonitors, sqlResp.TrafficMonitors)
}
if !reflect.DeepEqual(sqlResp.Cachegroups, resp.Response.Cachegroups) {
t.Errorf("GetMonitoringJSON expected Cachegroups: %+v actual: %+v", resp.Response.Cachegroups, sqlResp.Cachegroups)
}
if !reflect.DeepEqual(sqlResp.Profiles, resp.Response.Profiles) {
t.Errorf("GetMonitoringJSON expected Profiles: %+v actual: %+v", resp.Response.Profiles, sqlResp.Profiles)
}
if !reflect.DeepEqual(sqlResp.DeliveryServices, resp.Response.DeliveryServices) {
t.Errorf("GetMonitoringJSON expected DeliveryServices: %+v actual: %+v", resp.Response.DeliveryServices, sqlResp.DeliveryServices)
}
if !reflect.DeepEqual(sqlResp.Config, resp.Response.Config) {
t.Errorf("GetMonitoringJSON expected Config: %+v actual: %+v", resp.Response.Config, sqlResp.Config)
}
if !reflect.DeepEqual(sqlResp.Topologies, resp.Response.Topologies) {
t.Errorf("GetMonitoringJSON expected Topologies: %+v actual: %+v", resp.Response.Topologies, sqlResp.Topologies)
}
}
type SortableProfiles []Profile
func (s SortableProfiles) Len() int {
return len(s)
}
func (s SortableProfiles) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableProfiles) Less(i, j int) bool {
return s[i].Name < s[j].Name
}
func sortProfiles(p []Profile) []Profile {
sort.Sort(SortableProfiles(p))
return p
}
type SortableMonitors []Monitor
func (s SortableMonitors) Len() int {
return len(s)
}
func (s SortableMonitors) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableMonitors) Less(i, j int) bool {
return s[i].HostName < s[j].HostName
}
func sortMonitors(p []Monitor) []Monitor {
sort.Sort(SortableMonitors(p))
return p
}
type SortableCaches []Cache
func (s SortableCaches) Len() int {
return len(s)
}
func (s SortableCaches) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableCaches) Less(i, j int) bool {
return s[i].HostName < s[j].HostName
}
type SortableInterfaces []tc.ServerInterfaceInfo
func (s SortableInterfaces) Len() int {
return len(s)
}
func (s SortableInterfaces) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableInterfaces) Less(i, j int) bool {
return s[i].Name < s[j].Name
}
func sortInterfaces(i []tc.ServerInterfaceInfo) []tc.ServerInterfaceInfo {
sort.Sort(SortableInterfaces(i))
return i
}
func sortCaches(p []Cache) []Cache {
sort.Sort(SortableCaches(p))
return p
}
type SortableCachegroups []Cachegroup
func (s SortableCachegroups) Len() int {
return len(s)
}
func (s SortableCachegroups) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableCachegroups) Less(i, j int) bool {
return s[i].Name < s[j].Name
}
func sortCachegroups(p []Cachegroup) []Cachegroup {
sort.Sort(SortableCachegroups(p))
return p
}
type SortableDeliveryServices []DeliveryService
func (s SortableDeliveryServices) Len() int {
return len(s)
}
func (s SortableDeliveryServices) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s SortableDeliveryServices) Less(i, j int) bool {
return s[i].XMLID < s[j].XMLID
}
func sortDeliveryServices(p []DeliveryService) []DeliveryService {
sort.Sort(SortableDeliveryServices(p))
return p
}
func createMockMonitor() Monitor {
return Monitor{
BasicServer: BasicServer{
CommonServerProperties: CommonServerProperties{
Profile: "monitorProfile",
Status: "monitorStatus",
Port: 8081,
Cachegroup: "monitorCachegroup",
HostName: "monitorHost",
FQDN: "monitorFqdn.me",
},
IP: "5.6.7.10",
IP6: "2020::10",
},
}
}
func setupMockGetMonitoringServersWithoutIPv4(mock sqlmock.Sqlmock, monitor Monitor, router Router, caches []Cache, cacheIDs []uint64, cdn string) {
serverRows := sqlmock.NewRows([]string{"hostName", "fqdn", "status", "cachegroup", "port", "profile", "type", "hashId", "serverID"})
interfaceRows := sqlmock.NewRows([]string{"name", "max_bandwidth", "mtu", "monitor", "server"})
ipAddressRows := sqlmock.NewRows([]string{"address", "gateway", "service_address", "server", "interface"})
dssRows := sqlmock.NewRows([]string{"host_name", "xml_id"})
serverRows = serverRows.AddRow(monitor.HostName, monitor.FQDN, monitor.Status, monitor.Cachegroup, monitor.Port, monitor.Profile, MonitorType, "noHash", 5)
for index, cache := range caches {
serverRows = serverRows.AddRow(cache.HostName, cache.FQDN, cache.Status, cache.Cachegroup, cache.Port, cache.Profile, cache.Type, cache.HashID, cacheIDs[index])
dssRows = dssRows.AddRow(cache.HostName, "xml_id_foo")
interfaceRows = interfaceRows.AddRow("none", nil, 1500, false, 0)
for _, interf := range cache.Interfaces {
interfaceRows = interfaceRows.AddRow(interf.Name, interf.MaxBandwidth, interf.MTU, interf.Monitor, cacheIDs[index])
for _, ip := range interf.IPAddresses {
ipAddressRows = ipAddressRows.AddRow(ip.Address, ip.Gateway, ip.ServiceAddress, cacheIDs[index], interf.Name)
//Create two orphaned records
ipAddressRows = ipAddressRows.AddRow("0.0.0.0", "0.0.0.0", false, 0, interf.Name)
ipAddressRows = ipAddressRows.AddRow("0.0.0.0", "0.0.0.0", false, cacheIDs[index], "none")
}
}
}
// Add an interface and only ipv6 ip address for the monitor cache
interfaceRows = interfaceRows.AddRow("monitorCacheInterface", nil, 1500, false, 5)
ipAddressRows = ipAddressRows.AddRow("2020::10", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", false, 5, "monitorCacheInterface")
serverRows = serverRows.AddRow("noHostname", "noFqdn", "noStatus", "noGroup", 0, router.Profile, RouterType, "noHashid", 3)
mock.ExpectQuery("SELECT (.+) FROM interface i (.+)").WithArgs(cdn).WillReturnRows(interfaceRows)
mock.ExpectQuery("SELECT (.+) FROM ip_address ip (.+)").WillReturnRows(ipAddressRows)
mock.ExpectQuery("SELECT (.+) FROM deliveryservice_server AS dss (.+)").WillReturnRows(dssRows)
mock.ExpectQuery("SELECT (.+) FROM server me (.+)").WithArgs(cdn).WillReturnRows(serverRows)
}
func setupMockGetMonitoringServers(mock sqlmock.Sqlmock, monitor Monitor, router Router, caches []Cache, cacheIDs []uint64, cdn string) {
serverRows := sqlmock.NewRows([]string{"hostName", "fqdn", "status", "cachegroup", "port", "profile", "type", "hashId", "serverID"})
interfaceRows := sqlmock.NewRows([]string{"name", "max_bandwidth", "mtu", "monitor", "server"})
ipAddressRows := sqlmock.NewRows([]string{"address", "gateway", "service_address", "server", "interface"})
dssRows := sqlmock.NewRows([]string{"host_name", "xml_id"})
serverRows = serverRows.AddRow(monitor.HostName, monitor.FQDN, monitor.Status, monitor.Cachegroup, monitor.Port, monitor.Profile, MonitorType, "noHash", 5)
for index, cache := range caches {
serverRows = serverRows.AddRow(cache.HostName, cache.FQDN, cache.Status, cache.Cachegroup, cache.Port, cache.Profile, cache.Type, cache.HashID, cacheIDs[index])
dssRows = dssRows.AddRow(cache.HostName, "xml_id_foo")
interfaceRows = interfaceRows.AddRow("none", nil, 1500, false, 0)
for _, interf := range cache.Interfaces {
interfaceRows = interfaceRows.AddRow(interf.Name, interf.MaxBandwidth, interf.MTU, interf.Monitor, cacheIDs[index])
for _, ip := range interf.IPAddresses {
ipAddressRows = ipAddressRows.AddRow(ip.Address, ip.Gateway, ip.ServiceAddress, cacheIDs[index], interf.Name)
//Create two orphaned records
ipAddressRows = ipAddressRows.AddRow("0.0.0.0", "0.0.0.0", false, 0, interf.Name)
ipAddressRows = ipAddressRows.AddRow("0.0.0.0", "0.0.0.0", false, cacheIDs[index], "none")
}
}
}
// Add an interface and ip addresses for the monitor cache
interfaceRows = interfaceRows.AddRow("monitorCacheInterface", nil, 1500, false, 5)
ipAddressRows = ipAddressRows.AddRow("5.6.7.10", "10.0.0.0", true, 5, "monitorCacheInterface")
ipAddressRows = ipAddressRows.AddRow("2020::10", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", false, 5, "monitorCacheInterface")
serverRows = serverRows.AddRow("noHostname", "noFqdn", "noStatus", "noGroup", 0, router.Profile, RouterType, "noHashid", 3)
mock.ExpectQuery("SELECT (.+) FROM interface i (.+)").WithArgs(cdn).WillReturnRows(interfaceRows)
mock.ExpectQuery("SELECT (.+) FROM ip_address ip (.+)").WillReturnRows(ipAddressRows)
mock.ExpectQuery("SELECT (.+) FROM deliveryservice_server AS dss (.+)").WillReturnRows(dssRows)
mock.ExpectQuery("SELECT (.+) FROM server me (.+)").WithArgs(cdn).WillReturnRows(serverRows)
}
func mockGetParams(mock sqlmock.Sqlmock, expected []parameter.TOParameter, cdn string) {
rows := sqlmock.NewRows([]string{"name", "value"})
for _, param := range expected {
n := param.Name
v := param.Value
rows = rows.AddRow(*n, *v)
}
mock.ExpectQuery("SELECT").WithArgs(tc.MonitorProfilePrefix+"%%", MonitorConfigFile, cdn).WillReturnRows(rows)
}
func createMockCache(interfaceName string) Cache {
return Cache{
CommonServerProperties: CommonServerProperties{
Profile: "cacheProfile",
Status: "REPORTED",
Port: 8081,
Cachegroup: "cacheCachegroup",
HostName: "cacheHost",
FQDN: "cacheFqdn.me",
},
Interfaces: []tc.ServerInterfaceInfo{
{
IPAddresses: []tc.ServerIPAddress{
{
Address: "5.6.7.8",
Gateway: util.StrPtr("5.6.7.0/24"),
ServiceAddress: true,
},
{
Address: "2020::4",
Gateway: util.StrPtr("fd53::9"),
ServiceAddress: true,
},
{
Address: "5.6.7.9",
Gateway: util.StrPtr("5.6.7.0/24"),
ServiceAddress: false,
},
{
Address: "2021::4",
Gateway: util.StrPtr("fd53::9"),
ServiceAddress: false,
},
},
MaxBandwidth: util.UInt64Ptr(2500),
Monitor: true,
MTU: util.UInt64Ptr(1500),
Name: interfaceName + "1",
},
{
IPAddresses: []tc.ServerIPAddress{
{
Address: "6.7.8.9",
Gateway: util.StrPtr("6.7.8.0/24"),
ServiceAddress: true,
},
{
Address: "2021::4",
Gateway: util.StrPtr("fd54::9"),
ServiceAddress: true,
},
{
Address: "6.6.7.9",
Gateway: util.StrPtr("6.6.7.0/24"),
ServiceAddress: false,
},
{
Address: "2022::4",
Gateway: util.StrPtr("fd53::9"),
ServiceAddress: false,
},
},
MaxBandwidth: util.UInt64Ptr(1500),
Monitor: false,
MTU: util.UInt64Ptr(1500),
Name: interfaceName + "2",
},
},
Type: "EDGE",
HashID: "cacheHash",
DeliveryServices: []tc.TSDeliveryService{{XmlId: "xml_id_foo"}},
}
}
func createMockRouter() Router {
return Router{
Type: RouterType,
Profile: "routerProfile",
}
}
func ExpectedGetParams() []parameter.TOParameter {
name := "peers.polling.interval"
value := "3000"
return []parameter.TOParameter{
{
APIInfoImpl: api.APIInfoImpl{ReqInfo: nil},
ParameterNullable: tc.ParameterNullable{
ConfigFile: nil,
ID: nil,
LastUpdated: nil,
Name: &name,
Profiles: nil,
Secure: nil,
Value: &value,
},
},
}
}