From 58013dbd2c323845b0c8fc064eee46f7c003239f Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 26 May 2023 16:57:25 +0530 Subject: [PATCH 01/23] Fixes https://github.com/apache/trafficcontrol/issues/7544 Updated V5 APIs --- lib/go-tc/stats_summary.go | 112 ++++++++++++++++ .../traffic_ops_golang/routing/routes.go | 4 +- .../trafficstats/stats_summary.go | 126 ++++++++++++++++++ 3 files changed, 240 insertions(+), 2 deletions(-) diff --git a/lib/go-tc/stats_summary.go b/lib/go-tc/stats_summary.go index a516ae5a55..1c3af06e56 100644 --- a/lib/go-tc/stats_summary.go +++ b/lib/go-tc/stats_summary.go @@ -187,3 +187,115 @@ type StatsSummaryLastUpdatedAPIResponse struct { Response StatsSummaryLastUpdated `json:"response"` Alerts } + +// StatsSummaryV5 is an alias for the latest minor version for the major version 5. +type StatsSummaryV5 StatsSummaryV51 + +// StatsSummaryV51 is a summary of some kind of statistic for a CDN and/or +// Delivery Service. +type StatsSummaryV51 struct { + CDNName *string `json:"cdnName" db:"cdn_name"` + DeliveryService *string `json:"deliveryServiceName" db:"deliveryservice_name"` + StatName *string `json:"statName" db:"stat_name"` + StatValue *float64 `json:"statValue" db:"stat_value"` + SummaryTime time.Time `json:"summaryTime" db:"summary_time"` + StatDate *time.Time `json:"statDate" db:"stat_date"` +} + +// Validate implements the +// github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api.ParseValidator +// interface. +func (ss StatsSummaryV5) Validate(tx *sql.Tx) error { + errs := tovalidate.ToErrors(validation.Errors{ + "statName": validation.Validate(ss.StatName, validation.Required), + "statValue": validation.Validate(ss.StatValue, validation.Required), + }) + return util.JoinErrs(errs) +} + +// UnmarshalJSON implements the encoding/json.Unmarshaler interface with a +// customized decoding to force the date format on StatDate. +func (ss *StatsSummaryV5) UnmarshalJSON(data []byte) error { + type Alias StatsSummary + resp := struct { + SummaryTime string `json:"summaryTime"` + StatDate *string `json:"statDate"` + *Alias + }{ + Alias: (*Alias)(ss), + } + err := json.Unmarshal(data, &resp) + if err != nil { + return err + } + if resp.StatDate != nil { + statDate, err := parseTimeV5(*resp.StatDate) + if err != nil { + return errors.New("invalid timestamp given for statDate") + } + ss.StatDate = &statDate + } + + ss.SummaryTime, err = parseTimeV5(resp.SummaryTime) + if err != nil { + return errors.New("invalid timestamp given for summaryTime") + } + return nil +} + +func parseTimeV5(ts string) (time.Time, error) { + rt, err := time.Parse(time.RFC3339, ts) + if err == nil { + return rt, err + } + return time.Parse(dateFormat, ts) +} + +// MarshalJSON implements the encoding/json.Marshaler interface with a +// customized encoding to force the date format on StatDate. +func (ss StatsSummaryV5) MarshalJSON() ([]byte, error) { + type Alias StatsSummaryV5 + resp := struct { + StatDate *string `json:"statDate"` + SummaryTime string `json:"summaryTime"` + Alias + }{ + SummaryTime: ss.SummaryTime.Format(time.RFC3339), + Alias: (Alias)(ss), + } + if ss.StatDate != nil { + resp.StatDate = util.Ptr(ss.StatDate.Format(dateFormat)) + } + return json.Marshal(&resp) +} + +// StatsSummaryResponseV5 is an alias for the latest minor version for the major version 5. +type StatsSummaryResponseV5 StatsSummaryResponseV51 + +// StatsSummaryResponseV51 is the structure of a response from Traffic Ops to +// GET requests made to its /stats_summary V5 API endpoint. +type StatsSummaryResponseV51 struct { + Response []StatsSummaryV5 `json:"response"` + Alerts +} + +// StatsSummaryLastUpdatedV5 is an alias for the latest minor version for the major version 5. +type StatsSummaryLastUpdatedV5 StatsSummaryLastUpdatedV51 + +// StatsSummaryLastUpdatedV51 is the type of the `response` property of a response +// from Traffic Ops to a GET request made to its /stats_summary endpoint when +// the 'lastSummaryDate' query string parameter is passed as 'true'. +type StatsSummaryLastUpdatedV51 struct { + SummaryTime *time.Time `json:"summaryTime" db:"summary_time"` +} + +// StatsSummaryLastUpdatedAPIResponseV5 is an alias for the latest minor version for the major version 5. +type StatsSummaryLastUpdatedAPIResponseV5 StatsSummaryLastUpdatedAPIResponseV51 + +// StatsSummaryLastUpdatedAPIResponseV51 is the type of a response from Traffic +// Ops to a request to its /stats_summary endpoint with the 'lastSummaryDate' +// query string parameter set to 'true'. +type StatsSummaryLastUpdatedAPIResponseV51 struct { + Response StatsSummaryLastUpdatedV5 `json:"response"` + Alerts +} diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index fd92566d82..8fb491e493 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -511,8 +511,8 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodDelete, Path: `steering/{deliveryservice}/targets/{target}/?$`, Handler: api.DeleteHandler(&steeringtargets.TOSteeringTargetV11{}), RequiredPrivLevel: auth.PrivLevelSteering, RequiredPermissions: []string{"STEERING:DELETE", "STEERING:READ", "DELIVERY-SERVICE:READ", "TYPE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 428802151531}, // Stats Summary - {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `stats_summary/?$`, Handler: trafficstats.GetStatsSummary, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049859831}, - {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `stats_summary/?$`, Handler: trafficstats.CreateStatsSummary, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:CREATE", "STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049159831}, + {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `stats_summary/?$`, Handler: trafficstats.GetStatsSummaryV5, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049859831}, + {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `stats_summary/?$`, Handler: trafficstats.CreateStatsSummaryV5, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:CREATE", "STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049159831}, //Pattern based consistent hashing endpoint {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `consistenthash/?$`, Handler: consistenthash.Post, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDN:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 46075507631}, diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go index 347e7861cc..a57eb7cc31 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go @@ -186,3 +186,129 @@ VALUES ( :stat_date) RETURNING id ` } + +// GetStatsSummaryV5 handler for getting stats summaries +func GetStatsSummaryV5(w http.ResponseWriter, r *http.Request) { + inf, userErr, sysErr, errCode := api.NewInfo(r, []string{}, []string{}) + if userErr != nil || sysErr != nil { + api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) + return + } + defer inf.Close() + + lastSummaryDateStr := inf.Params["lastSummaryDate"] + if len(lastSummaryDateStr) != 0 { // Perl only checked for existence of query param + getLastSummaryDateV5(w, r, inf) + return + } + + getStatsSummaryV5(w, r, inf) + return +} + +func getLastSummaryDateV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { + queryParamsToSQLCols := map[string]dbhelpers.WhereColumnInfo{ + "statName": dbhelpers.WhereColumnInfo{Column: "stat_name"}, + } + where, _, _, queryValues, errs := dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToSQLCols) + if len(errs) > 0 { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, util.JoinErrs(errs)) + return + } + query := selectQuery() + where + " ORDER BY summary_time DESC" + statsSummaries, err := queryStatsSummaryV5(inf.Tx, query, queryValues) + if err != nil { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) + return + } + resp := tc.StatsSummaryLastUpdatedV5{} + if len(statsSummaries) >= 1 { + resp.SummaryTime = &statsSummaries[0].SummaryTime + } + api.WriteResp(w, r, resp) +} + +func getStatsSummaryV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { + queryParamsToSQLCols := map[string]dbhelpers.WhereColumnInfo{ + "statName": dbhelpers.WhereColumnInfo{Column: "stat_name"}, + "cdnName": dbhelpers.WhereColumnInfo{Column: "cdn_name"}, + "deliveryServiceName": dbhelpers.WhereColumnInfo{Column: "deliveryservice_name"}, + } + where, orderBy, pagination, queryValues, errs := dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToSQLCols) + if len(errs) > 0 { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, util.JoinErrs(errs)) + return + } + query := selectQuery() + where + orderBy + pagination + statsSummaries, err := queryStatsSummaryV5(inf.Tx, query, queryValues) + if err != nil { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) + return + } + + api.WriteResp(w, r, statsSummaries) +} + +func queryStatsSummaryV5(tx *sqlx.Tx, q string, queryValues map[string]interface{}) ([]tc.StatsSummaryV5, error) { + rows, err := tx.NamedQuery(q, queryValues) + if err != nil { + return nil, fmt.Errorf("querying stats summary: %v", err) + } + defer rows.Close() + + statsSummaries := []tc.StatsSummaryV5{} + for rows.Next() { + s := tc.StatsSummaryV5{} + if err = rows.StructScan(&s); err != nil { + return nil, fmt.Errorf("scanning stats summary: %v", err) + } + statsSummaries = append(statsSummaries, s) + } + return statsSummaries, nil +} + +// CreateStatsSummaryV5 handler for creating stats summaries +func CreateStatsSummaryV5(w http.ResponseWriter, r *http.Request) { + inf, userErr, sysErr, errCode := api.NewInfo(r, []string{}, []string{}) + if userErr != nil || sysErr != nil { + api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) + return + } + defer inf.Close() + + ss := tc.StatsSummaryV5{} + + if err := api.Parse(r.Body, inf.Tx.Tx, &ss); err != nil { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil) + return + } + + // CDN Name and Delivery service name are defaulted to "all" if not defined + if ss.CDNName == nil || len(*ss.CDNName) == 0 { + ss.CDNName = util.Ptr("all") + } + + if ss.DeliveryService == nil || len(*ss.DeliveryService) == 0 { + ss.DeliveryService = util.Ptr("all") + } + + id := -1 + rows, err := inf.Tx.NamedQuery(insertQuery(), &ss) + if err != nil { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("inserting stats summary: %v", err)) + return + } + for rows.Next() { + if err := rows.Scan(&id); err != nil { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("scanning created stats summary id: %v", err)) + return + } + } + if id == -1 { + api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("sstats summary id: %v", err)) + return + } + + successMsg := "Stats Summary was successfully created" + api.WriteRespAlert(w, r, tc.SuccessLevel, successMsg) +} From cf68b8576b744ac8ebf0f1e2774e64a7e136aec5 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 26 May 2023 17:00:28 +0530 Subject: [PATCH 02/23] Fixes https://github.com/apache/trafficcontrol/issues/7544 Updated Integration testing based on RFC3339 Format --- traffic_ops/testing/api/v5/stats_summary_test.go | 6 +++--- traffic_ops/testing/api/v5/traffic_control_test.go | 2 +- traffic_ops/v5-client/stats_summary.go | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/traffic_ops/testing/api/v5/stats_summary_test.go b/traffic_ops/testing/api/v5/stats_summary_test.go index d7525050ee..d4b4357e85 100644 --- a/traffic_ops/testing/api/v5/stats_summary_test.go +++ b/traffic_ops/testing/api/v5/stats_summary_test.go @@ -34,7 +34,7 @@ func TestStatsSummary(t *testing.T) { CreateTestStatsSummaries(t) - methodTests := utils.TestCase[client.Session, client.RequestOptions, tc.StatsSummary]{ + methodTests := utils.TestCase[client.Session, client.RequestOptions, tc.StatsSummaryV5]{ "GET": { "OK when VALID request": { ClientSession: TOSession, @@ -115,7 +115,7 @@ func TestStatsSummary(t *testing.T) { func validateStatsSummaryFields(expectedResp map[string]interface{}) utils.CkReqFunc { return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) { assert.RequireNotNil(t, resp, "Expected Stats Summary response to not be nil.") - statsSummaryResp := resp.([]tc.StatsSummary) + statsSummaryResp := resp.([]tc.StatsSummaryV5) for field, expected := range expectedResp { for _, statsSummary := range statsSummaryResp { switch field { @@ -141,7 +141,7 @@ func validateStatsSummaryFields(expectedResp map[string]interface{}) utils.CkReq func validateStatsSummaryLastUpdatedField(expectedTime time.Time) utils.CkReqFunc { return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) { assert.RequireNotNil(t, resp, "Expected StatsSummaryLastUpdated response to not be nil.") - statsSummaryLastUpdated := resp.(tc.StatsSummaryLastUpdated) + statsSummaryLastUpdated := resp.(tc.StatsSummaryLastUpdatedV5) assert.RequireNotNil(t, statsSummaryLastUpdated.SummaryTime, "Expected SummaryTime to not be nil.") assert.Equal(t, expectedTime, *statsSummaryLastUpdated.SummaryTime, "Expected SummaryTime to be %v, but got %v", expectedTime, *statsSummaryLastUpdated.SummaryTime) } diff --git a/traffic_ops/testing/api/v5/traffic_control_test.go b/traffic_ops/testing/api/v5/traffic_control_test.go index 59048da291..409da97887 100644 --- a/traffic_ops/testing/api/v5/traffic_control_test.go +++ b/traffic_ops/testing/api/v5/traffic_control_test.go @@ -51,7 +51,7 @@ type TrafficControl struct { ServiceCategories []tc.ServiceCategoryV5 `json:"serviceCategories"` Statuses []tc.StatusNullable `json:"statuses"` StaticDNSEntries []tc.StaticDNSEntry `json:"staticdnsentries"` - StatsSummaries []tc.StatsSummary `json:"statsSummaries"` + StatsSummaries []tc.StatsSummaryV5 `json:"statsSummaries"` Tenants []tc.Tenant `json:"tenants"` ServerCheckExtensions []tc.ServerCheckExtensionNullable `json:"servercheck_extensions"` Topologies []tc.Topology `json:"topologies"` diff --git a/traffic_ops/v5-client/stats_summary.go b/traffic_ops/v5-client/stats_summary.go index 9b8e9a683d..03b7597cff 100644 --- a/traffic_ops/v5-client/stats_summary.go +++ b/traffic_ops/v5-client/stats_summary.go @@ -24,8 +24,8 @@ const apiStatsSummary = "/stats_summary" // GetSummaryStats gets a list of Summary Stats with the ability to filter on // CDN, Delivery Service, and/or stat name. -func (to *Session) GetSummaryStats(opts RequestOptions) (tc.StatsSummaryResponse, toclientlib.ReqInf, error) { - var resp tc.StatsSummaryResponse +func (to *Session) GetSummaryStats(opts RequestOptions) (tc.StatsSummaryResponseV5, toclientlib.ReqInf, error) { + var resp tc.StatsSummaryResponseV5 reqInf, err := to.get(apiStatsSummary, opts, &resp) return resp, reqInf, err } @@ -34,19 +34,19 @@ func (to *Session) GetSummaryStats(opts RequestOptions) (tc.StatsSummaryResponse // updated. // If 'statName' isn't nil, the response will be limited to the stat thereby // named. -func (to *Session) GetSummaryStatsLastUpdated(opts RequestOptions) (tc.StatsSummaryLastUpdatedAPIResponse, toclientlib.ReqInf, error) { +func (to *Session) GetSummaryStatsLastUpdated(opts RequestOptions) (tc.StatsSummaryLastUpdatedAPIResponseV5, toclientlib.ReqInf, error) { if opts.QueryParameters == nil { opts.QueryParameters = url.Values{} } opts.QueryParameters.Set("lastSummaryDate", "true") - var resp tc.StatsSummaryLastUpdatedAPIResponse + var resp tc.StatsSummaryLastUpdatedAPIResponseV5 reqInf, err := to.get(apiStatsSummary, opts, &resp) return resp, reqInf, err } // CreateSummaryStats creates the given Stats Summary. -func (to *Session) CreateSummaryStats(statsSummary tc.StatsSummary, opts RequestOptions) (tc.Alerts, toclientlib.ReqInf, error) { +func (to *Session) CreateSummaryStats(statsSummary tc.StatsSummaryV5, opts RequestOptions) (tc.Alerts, toclientlib.ReqInf, error) { var alerts tc.Alerts reqInf, err := to.post(apiStatsSummary, opts, statsSummary, &alerts) return alerts, reqInf, err From 002d80f5f7ecdbce0c7d70f1d2a2fae326799799 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Sun, 28 May 2023 18:51:50 +0530 Subject: [PATCH 03/23] Fixes https://github.com/apache/trafficcontrol/issues/7544 Added Unit test Cases wherever possible. --- .../trafficstats/stats_summary.go | 76 +++++++++---------- .../trafficstats/stats_summary_test.go | 68 +++++++++++++++++ 2 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go index a57eb7cc31..96f41bed76 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go @@ -157,36 +157,6 @@ func CreateStatsSummary(w http.ResponseWriter, r *http.Request) { api.WriteRespAlert(w, r, tc.SuccessLevel, successMsg) } -func selectQuery() string { - return `SELECT -cdn_name, -deliveryservice_name, -stat_name, -stat_value, -summary_time, -stat_date -FROM stats_summary` -} - -func insertQuery() string { - return ` -INSERT INTO stats_summary ( - cdn_name, - deliveryservice_name, - stat_name, - stat_value, - summary_time, - stat_date) -VALUES ( - :cdn_name, - :deliveryservice_name, - :stat_name, - :stat_value, - :summary_time, - :stat_date) RETURNING id -` -} - // GetStatsSummaryV5 handler for getting stats summaries func GetStatsSummaryV5(w http.ResponseWriter, r *http.Request) { inf, userErr, sysErr, errCode := api.NewInfo(r, []string{}, []string{}) @@ -198,15 +168,15 @@ func GetStatsSummaryV5(w http.ResponseWriter, r *http.Request) { lastSummaryDateStr := inf.Params["lastSummaryDate"] if len(lastSummaryDateStr) != 0 { // Perl only checked for existence of query param - getLastSummaryDateV5(w, r, inf) + GetLastSummaryDateV5(w, r, inf) return } - getStatsSummaryV5(w, r, inf) + GetStatsSummariesV5(w, r, inf) return } -func getLastSummaryDateV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { +func GetLastSummaryDateV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { queryParamsToSQLCols := map[string]dbhelpers.WhereColumnInfo{ "statName": dbhelpers.WhereColumnInfo{Column: "stat_name"}, } @@ -216,7 +186,7 @@ func getLastSummaryDateV5(w http.ResponseWriter, r *http.Request, inf *api.APIIn return } query := selectQuery() + where + " ORDER BY summary_time DESC" - statsSummaries, err := queryStatsSummaryV5(inf.Tx, query, queryValues) + statsSummaries, err := QueryStatsSummaryV5(inf.Tx, query, queryValues) if err != nil { api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) return @@ -228,7 +198,7 @@ func getLastSummaryDateV5(w http.ResponseWriter, r *http.Request, inf *api.APIIn api.WriteResp(w, r, resp) } -func getStatsSummaryV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { +func GetStatsSummariesV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { queryParamsToSQLCols := map[string]dbhelpers.WhereColumnInfo{ "statName": dbhelpers.WhereColumnInfo{Column: "stat_name"}, "cdnName": dbhelpers.WhereColumnInfo{Column: "cdn_name"}, @@ -240,7 +210,7 @@ func getStatsSummaryV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) return } query := selectQuery() + where + orderBy + pagination - statsSummaries, err := queryStatsSummaryV5(inf.Tx, query, queryValues) + statsSummaries, err := QueryStatsSummaryV5(inf.Tx, query, queryValues) if err != nil { api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) return @@ -249,14 +219,14 @@ func getStatsSummaryV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) api.WriteResp(w, r, statsSummaries) } -func queryStatsSummaryV5(tx *sqlx.Tx, q string, queryValues map[string]interface{}) ([]tc.StatsSummaryV5, error) { +func QueryStatsSummaryV5(tx *sqlx.Tx, q string, queryValues map[string]interface{}) ([]tc.StatsSummaryV5, error) { rows, err := tx.NamedQuery(q, queryValues) if err != nil { return nil, fmt.Errorf("querying stats summary: %v", err) } defer rows.Close() - statsSummaries := []tc.StatsSummaryV5{} + var statsSummaries []tc.StatsSummaryV5 for rows.Next() { s := tc.StatsSummaryV5{} if err = rows.StructScan(&s); err != nil { @@ -312,3 +282,33 @@ func CreateStatsSummaryV5(w http.ResponseWriter, r *http.Request) { successMsg := "Stats Summary was successfully created" api.WriteRespAlert(w, r, tc.SuccessLevel, successMsg) } + +func selectQuery() string { + return `SELECT +cdn_name, +deliveryservice_name, +stat_name, +stat_value, +summary_time, +stat_date +FROM stats_summary` +} + +func insertQuery() string { + return ` +INSERT INTO stats_summary ( + cdn_name, + deliveryservice_name, + stat_name, + stat_value, + summary_time, + stat_date) +VALUES ( + :cdn_name, + :deliveryservice_name, + :stat_name, + :stat_value, + :summary_time, + :stat_date) RETURNING id +` +} diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go new file mode 100644 index 0000000000..6448a7b929 --- /dev/null +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go @@ -0,0 +1,68 @@ +package trafficstats + +import ( + "testing" + "time" + + "github.com/apache/trafficcontrol/lib/go-util/assert" + + "github.com/jmoiron/sqlx" + "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 TestQueryStatsSummaryV5(t *testing.T) { + + query := "SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary" + queryValues := map[string]interface{}{ + "lastSummaryDate": "true", + } + + mockDB, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%v' was not expected when opening a stub database connection", err) + } + defer mockDB.Close() + + db := sqlx.NewDb(mockDB, "sqlmock") + defer db.Close() + + mock.ExpectBegin() + rows := sqlmock.NewRows([]string{ + "cdn_name", + "deliveryservice_name", + "stat_name", + "stat_value", + "summary_time", + "stat_date", + }) + + rows.AddRow("cdn1", "all", "daily_maxgbps", 5, time.Now().AddDate(0, 0, -5), time.Now().AddDate(0, 0, -5).Truncate(24*time.Hour)) + rows.AddRow("cdn2", "all", "daily_byteserved", 1000, time.Now().AddDate(0, 0, -10), time.Now().AddDate(0, 0, -10).Truncate(24*time.Hour)) + + mock.ExpectQuery("SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary").WithArgs().WillReturnRows(rows) + + statsSummaries1, err1 := QueryStatsSummaryV5(db.MustBegin(), query, queryValues) + + assert.NoError(t, err1) + assert.Equal(t, len(statsSummaries1), 2) + +} From db8a54bd5849a4bbff7e9dde189bae21be510c07 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Sun, 28 May 2023 19:16:12 +0530 Subject: [PATCH 04/23] CHANGELOG.md Update --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f7e10bb74..ca70b6e8e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [unreleased] ### Added -- [#7450](https://github.com/apache/trafficcontrol/pull/7450) *Traffic Ops* Removed hypnotoad section and added listen field to traffic_ops_golang section in order to simplify cdn config. - [#7290](https://github.com/apache/trafficcontrol/pull/7302) *Traffic Monitor* Update TM results with hostname from via header, syncronize health on caches with same service address - [#7291](https://github.com/apache/trafficcontrol/pull/7291) *Traffic Ops* Extended Layered Profile feature to aggregate parameters for all server profiles. - [#7314](https://github.com/apache/trafficcontrol/pull/7314) *Traffic Portal* Added capability feature to Delivery Service Form (HTTP, DNS). @@ -67,6 +66,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#7570](https://github.com/apache/trafficcontrol/pull/7570) *Traffic Ops* Fixes `deliveryservice_request_comments` v5 apis to respond with `RFC3339` date/time Format. - [#7312](https://github.com/apache/trafficcontrol/issues/7312) *Docs* Changing docs for CDN locks for DELETE response structure v4 and v5. - [#7572](https://github.com/apache/trafficcontrol/pull/7572) *Traffic Ops* Fixes Delivery Service Requests V5 apis docs with RFC3339 date/time Format +- [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. +- [#7544](https://github.com/apache/trafficcontrol/issues/7544) *Traffic Ops* Fixes stats_summary v5 apis to respond with RFC3339 date/time Format. - [#7542](https://github.com/apache/trafficcontrol/pull/7542) *Traffic Ops* Fixed `CDN Locks` documentation to reflect the correct RFC3339 timestamps. - [#6340](https://github.com/apache/trafficcontrol/issues/6340) *Traffic Ops* Fixed alert messages for POST and PUT invalidation job APIs. - [#7519] (https://github.com/apache/trafficcontrol/issues/7519) *Traffic Ops* Fixed TO API /servers/{id}/deliveryservices endpoint to responding with all DS's on cache that are directly assigned and inherited through topology. From f1c71ea0ae57c5b8c264c01a90ffd49b7bb2c826 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Tue, 30 May 2023 21:03:50 +0530 Subject: [PATCH 05/23] Documentation Update --- docs/source/api/v5/stats_summary.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/source/api/v5/stats_summary.rst b/docs/source/api/v5/stats_summary.rst index 60a45ee582..5628058685 100644 --- a/docs/source/api/v5/stats_summary.rst +++ b/docs/source/api/v5/stats_summary.rst @@ -110,7 +110,7 @@ Summary Stats :statName: Stat name summary stat represents :statValue: Summary stat value -:summaryTime: Timestamp of summary, in :ref:`non-rfc-datetime` +:summaryTime: Timestamp of summary, in :rfc:`3339` format :statDate: Date stat was taken, in ``YYYY-MM-DD`` format .. code-block:: http @@ -134,7 +134,7 @@ Summary Stats "deliveryServiceName": "all", "statName": "daily_maxgbps", "statValue": 5, - "summaryTime": "2019-11-19 00:04:06+00", + "summaryTime": "2019-11-19T03:37:33+05:30", "statDate": "2019-11-19" }, { @@ -142,7 +142,7 @@ Summary Stats "deliveryServiceName": "all", "statName": "daily_maxgbps", "statValue": 3, - "summaryTime": "2019-11-18 00:04:06+00", + "summaryTime": "2019-11-18T07:59:54+05:30", "statDate": "2019-11-18" }, { @@ -150,7 +150,7 @@ Summary Stats "deliveryServiceName": "all", "statName": "daily_bytesserved", "statValue": 1000, - "summaryTime": "2019-11-19 00:04:06+00", + "summaryTime": "2019-11-19T00:42:12+05:30", "statDate": "2019-11-19" } ]} @@ -158,7 +158,7 @@ Summary Stats Last Updated Summary Stat """"""""""""""""""""""""" -:summaryTime: Timestamp of the last updated summary, in :ref:`non-rfc-datetime` +:summaryTime: Timestamp of the last updated summary, in :rfc:`3339` format .. code-block:: http :caption: Response Example @@ -176,7 +176,7 @@ Last Updated Summary Stat Content-Length: 150 { "response": { - "summaryTime": "2019-11-19 00:04:06+00" + "summaryTime": "2019-11-19T06:12:34+05:30" }} ``POST`` @@ -201,7 +201,7 @@ Request Structure :statName: Stat name summary stat represents :statValue: Summary stat value -:summaryTime: Timestamp of summary, in :ref:`non-rfc-datetime` +:summaryTime: Timestamp of summary, in :rfc:`3339` format :statDate: Date stat was taken, in ``YYYY-MM-DD`` format .. note:: ``statName``, ``statValue`` and ``summaryTime`` are required. If ``cdnName`` and ``deliveryServiceName`` are not given they will default to ``all``. @@ -222,7 +222,7 @@ Request Structure "deliveryServiceName": "all", "statName": "daily_maxgbps", "statValue": 10, - "summaryTime": "2019-12-05 00:03:57+00", + "summaryTime": "2019-12-05T09:55:07+05:30", "statDate": "2019-12-05" } From 09f892498cde18d16f620e2a3317e9997e476ec4 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 2 Jun 2023 17:14:09 +0530 Subject: [PATCH 06/23] Fixed PR review comments --- lib/go-tc/stats_summary.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/go-tc/stats_summary.go b/lib/go-tc/stats_summary.go index 1c3af06e56..0f6ea6c4b3 100644 --- a/lib/go-tc/stats_summary.go +++ b/lib/go-tc/stats_summary.go @@ -270,32 +270,32 @@ func (ss StatsSummaryV5) MarshalJSON() ([]byte, error) { } // StatsSummaryResponseV5 is an alias for the latest minor version for the major version 5. -type StatsSummaryResponseV5 StatsSummaryResponseV51 +type StatsSummaryResponseV5 StatsSummaryResponseV50 -// StatsSummaryResponseV51 is the structure of a response from Traffic Ops to +// StatsSummaryResponseV50 is the structure of a response from Traffic Ops to // GET requests made to its /stats_summary V5 API endpoint. -type StatsSummaryResponseV51 struct { +type StatsSummaryResponseV50 struct { Response []StatsSummaryV5 `json:"response"` Alerts } // StatsSummaryLastUpdatedV5 is an alias for the latest minor version for the major version 5. -type StatsSummaryLastUpdatedV5 StatsSummaryLastUpdatedV51 +type StatsSummaryLastUpdatedV5 StatsSummaryLastUpdatedV50 -// StatsSummaryLastUpdatedV51 is the type of the `response` property of a response +// StatsSummaryLastUpdatedV50 is the type of the `response` property of a response // from Traffic Ops to a GET request made to its /stats_summary endpoint when // the 'lastSummaryDate' query string parameter is passed as 'true'. -type StatsSummaryLastUpdatedV51 struct { +type StatsSummaryLastUpdatedV50 struct { SummaryTime *time.Time `json:"summaryTime" db:"summary_time"` } // StatsSummaryLastUpdatedAPIResponseV5 is an alias for the latest minor version for the major version 5. -type StatsSummaryLastUpdatedAPIResponseV5 StatsSummaryLastUpdatedAPIResponseV51 +type StatsSummaryLastUpdatedAPIResponseV5 StatsSummaryLastUpdatedAPIResponseV50 -// StatsSummaryLastUpdatedAPIResponseV51 is the type of a response from Traffic +// StatsSummaryLastUpdatedAPIResponseV50 is the type of a response from Traffic // Ops to a request to its /stats_summary endpoint with the 'lastSummaryDate' // query string parameter set to 'true'. -type StatsSummaryLastUpdatedAPIResponseV51 struct { +type StatsSummaryLastUpdatedAPIResponseV50 struct { Response StatsSummaryLastUpdatedV5 `json:"response"` Alerts } From 4869b8e3613b200ad937ea933e3dc0069f902bdb Mon Sep 17 00:00:00 2001 From: Rima Shah <22248619+rimashah25@users.noreply.github.com> Date: Wed, 31 May 2023 17:09:42 -0600 Subject: [PATCH 07/23] Use SOH timestamp to calculate bandwidth in TM (#7539) * Added current_time_epoch_ms and changes calculation for timestamp for ms * assigning current_time_epoch_ms to result.Time in Handler * updated CHANGELOG.md * Added check for elapsedTime. * Addressed review comments. * Added prevResult check back * pointer assignment for structure. * updated cache unite test with another check. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca70b6e8e9..6b2cc5959a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#7572](https://github.com/apache/trafficcontrol/pull/7572) *Traffic Ops* Fixes Delivery Service Requests V5 apis docs with RFC3339 date/time Format - [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. - [#7544](https://github.com/apache/trafficcontrol/issues/7544) *Traffic Ops* Fixes stats_summary v5 apis to respond with RFC3339 date/time Format. +- [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. - [#7542](https://github.com/apache/trafficcontrol/pull/7542) *Traffic Ops* Fixed `CDN Locks` documentation to reflect the correct RFC3339 timestamps. - [#6340](https://github.com/apache/trafficcontrol/issues/6340) *Traffic Ops* Fixed alert messages for POST and PUT invalidation job APIs. - [#7519] (https://github.com/apache/trafficcontrol/issues/7519) *Traffic Ops* Fixed TO API /servers/{id}/deliveryservices endpoint to responding with all DS's on cache that are directly assigned and inherited through topology. From e79e87aaf171c5398afb564360d03d398a0b23db Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Thu, 8 Jun 2023 11:18:30 +0530 Subject: [PATCH 08/23] Fixed PR review comments for https://github.com/apache/trafficcontrol/issues/7544 --- lib/go-tc/stats_summary.go | 39 +++- .../traffic_ops_golang/routing/routes.go | 4 +- .../trafficstats/stats_summary.go | 169 ++++-------------- .../trafficstats/stats_summary_test.go | 2 +- 4 files changed, 75 insertions(+), 139 deletions(-) diff --git a/lib/go-tc/stats_summary.go b/lib/go-tc/stats_summary.go index 0f6ea6c4b3..94ef478392 100644 --- a/lib/go-tc/stats_summary.go +++ b/lib/go-tc/stats_summary.go @@ -189,11 +189,11 @@ type StatsSummaryLastUpdatedAPIResponse struct { } // StatsSummaryV5 is an alias for the latest minor version for the major version 5. -type StatsSummaryV5 StatsSummaryV51 +type StatsSummaryV5 StatsSummaryV50 -// StatsSummaryV51 is a summary of some kind of statistic for a CDN and/or +// StatsSummaryV50 is a summary of some kind of statistic for a CDN and/or // Delivery Service. -type StatsSummaryV51 struct { +type StatsSummaryV50 struct { CDNName *string `json:"cdnName" db:"cdn_name"` DeliveryService *string `json:"deliveryServiceName" db:"deliveryservice_name"` StatName *string `json:"statName" db:"stat_name"` @@ -289,6 +289,39 @@ type StatsSummaryLastUpdatedV50 struct { SummaryTime *time.Time `json:"summaryTime" db:"summary_time"` } +// MarshalJSON implements the encoding/json.Marshaler interface with a +// customized encoding to force the date format on SummaryTime. +func (ss StatsSummaryLastUpdatedV5) MarshalJSON() ([]byte, error) { + resp := struct { + SummaryTime *string `json:"summaryTime"` + }{} + if ss.SummaryTime != nil { + resp.SummaryTime = util.Ptr(ss.SummaryTime.Format(time.RFC3339)) + } + return json.Marshal(&resp) +} + +// UnmarshalJSON implements the encoding/json.Unmarshaler interface with a +// customized decoding to force the SummaryTime format. +func (ss *StatsSummaryLastUpdatedV5) UnmarshalJSON(data []byte) error { + resp := struct { + SummaryTime *string `json:"summaryTime"` + }{} + err := json.Unmarshal(data, &resp) + if err != nil { + return err + } + if resp.SummaryTime != nil { + var summaryTime time.Time + summaryTime, err = time.Parse(time.RFC3339, *resp.SummaryTime) + if err == nil { + ss.SummaryTime = &summaryTime + return nil + } + } + return nil +} + // StatsSummaryLastUpdatedAPIResponseV5 is an alias for the latest minor version for the major version 5. type StatsSummaryLastUpdatedAPIResponseV5 StatsSummaryLastUpdatedAPIResponseV50 diff --git a/traffic_ops/traffic_ops_golang/routing/routes.go b/traffic_ops/traffic_ops_golang/routing/routes.go index 8fb491e493..fd92566d82 100644 --- a/traffic_ops/traffic_ops_golang/routing/routes.go +++ b/traffic_ops/traffic_ops_golang/routing/routes.go @@ -511,8 +511,8 @@ func Routes(d ServerData) ([]Route, http.Handler, error) { {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodDelete, Path: `steering/{deliveryservice}/targets/{target}/?$`, Handler: api.DeleteHandler(&steeringtargets.TOSteeringTargetV11{}), RequiredPrivLevel: auth.PrivLevelSteering, RequiredPermissions: []string{"STEERING:DELETE", "STEERING:READ", "DELIVERY-SERVICE:READ", "TYPE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 428802151531}, // Stats Summary - {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `stats_summary/?$`, Handler: trafficstats.GetStatsSummaryV5, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049859831}, - {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `stats_summary/?$`, Handler: trafficstats.CreateStatsSummaryV5, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:CREATE", "STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049159831}, + {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodGet, Path: `stats_summary/?$`, Handler: trafficstats.GetStatsSummary, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049859831}, + {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `stats_summary/?$`, Handler: trafficstats.CreateStatsSummary, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"STAT:CREATE", "STAT:READ", "CDN:READ", "DELIVERY-SERVICE:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 48049159831}, //Pattern based consistent hashing endpoint {Version: api.Version{Major: 5, Minor: 0}, Method: http.MethodPost, Path: `consistenthash/?$`, Handler: consistenthash.Post, RequiredPrivLevel: auth.PrivLevelReadOnly, RequiredPermissions: []string{"CDN:READ"}, Authenticated: Authenticated, Middlewares: nil, ID: 46075507631}, diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go index 96f41bed76..f002105de1 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go @@ -25,10 +25,9 @@ import ( "github.com/apache/trafficcontrol/lib/go-tc" "github.com/apache/trafficcontrol/lib/go-util" - "github.com/jmoiron/sqlx" - "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api" "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers" + "github.com/jmoiron/sqlx" ) // GetStatsSummary handler for getting stats summaries @@ -65,11 +64,22 @@ func getLastSummaryDate(w http.ResponseWriter, r *http.Request, inf *api.APIInfo api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) return } - resp := tc.StatsSummaryLastUpdated{} - if len(statsSummaries) >= 1 { - resp.SummaryTime = &statsSummaries[0].SummaryTime + + if inf.Version.Major >= 5 { + resp := tc.StatsSummaryLastUpdatedV5{} + if len(statsSummaries) >= 1 { + resp.SummaryTime = &statsSummaries[0].SummaryTime + } + api.WriteResp(w, r, resp) + + } else { + resp := tc.StatsSummaryLastUpdated{} + if len(statsSummaries) >= 1 { + resp.SummaryTime = &statsSummaries[0].SummaryTime + } + api.WriteResp(w, r, resp) } - api.WriteResp(w, r, resp) + } func getStatsSummary(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { @@ -90,7 +100,26 @@ func getStatsSummary(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { return } - api.WriteResp(w, r, statsSummaries) + if inf.Version.Major >= 5 { + statsSummariesV5 := make([]tc.StatsSummaryV5, len(statsSummaries)) + for i, oldStat := range statsSummaries { + newStat := tc.StatsSummaryV5{ + CDNName: oldStat.CDNName, + DeliveryService: oldStat.DeliveryService, + StatName: oldStat.StatName, + StatValue: oldStat.StatValue, + SummaryTime: oldStat.SummaryTime, + StatDate: oldStat.StatDate, + } + statsSummariesV5[i] = newStat + } + + api.WriteResp(w, r, statsSummariesV5) + + } else { + api.WriteResp(w, r, statsSummaries) + } + } func queryStatsSummary(tx *sqlx.Tx, q string, queryValues map[string]interface{}) ([]tc.StatsSummary, error) { @@ -157,132 +186,6 @@ func CreateStatsSummary(w http.ResponseWriter, r *http.Request) { api.WriteRespAlert(w, r, tc.SuccessLevel, successMsg) } -// GetStatsSummaryV5 handler for getting stats summaries -func GetStatsSummaryV5(w http.ResponseWriter, r *http.Request) { - inf, userErr, sysErr, errCode := api.NewInfo(r, []string{}, []string{}) - if userErr != nil || sysErr != nil { - api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) - return - } - defer inf.Close() - - lastSummaryDateStr := inf.Params["lastSummaryDate"] - if len(lastSummaryDateStr) != 0 { // Perl only checked for existence of query param - GetLastSummaryDateV5(w, r, inf) - return - } - - GetStatsSummariesV5(w, r, inf) - return -} - -func GetLastSummaryDateV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { - queryParamsToSQLCols := map[string]dbhelpers.WhereColumnInfo{ - "statName": dbhelpers.WhereColumnInfo{Column: "stat_name"}, - } - where, _, _, queryValues, errs := dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToSQLCols) - if len(errs) > 0 { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, util.JoinErrs(errs)) - return - } - query := selectQuery() + where + " ORDER BY summary_time DESC" - statsSummaries, err := QueryStatsSummaryV5(inf.Tx, query, queryValues) - if err != nil { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) - return - } - resp := tc.StatsSummaryLastUpdatedV5{} - if len(statsSummaries) >= 1 { - resp.SummaryTime = &statsSummaries[0].SummaryTime - } - api.WriteResp(w, r, resp) -} - -func GetStatsSummariesV5(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { - queryParamsToSQLCols := map[string]dbhelpers.WhereColumnInfo{ - "statName": dbhelpers.WhereColumnInfo{Column: "stat_name"}, - "cdnName": dbhelpers.WhereColumnInfo{Column: "cdn_name"}, - "deliveryServiceName": dbhelpers.WhereColumnInfo{Column: "deliveryservice_name"}, - } - where, orderBy, pagination, queryValues, errs := dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToSQLCols) - if len(errs) > 0 { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, util.JoinErrs(errs)) - return - } - query := selectQuery() + where + orderBy + pagination - statsSummaries, err := QueryStatsSummaryV5(inf.Tx, query, queryValues) - if err != nil { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) - return - } - - api.WriteResp(w, r, statsSummaries) -} - -func QueryStatsSummaryV5(tx *sqlx.Tx, q string, queryValues map[string]interface{}) ([]tc.StatsSummaryV5, error) { - rows, err := tx.NamedQuery(q, queryValues) - if err != nil { - return nil, fmt.Errorf("querying stats summary: %v", err) - } - defer rows.Close() - - var statsSummaries []tc.StatsSummaryV5 - for rows.Next() { - s := tc.StatsSummaryV5{} - if err = rows.StructScan(&s); err != nil { - return nil, fmt.Errorf("scanning stats summary: %v", err) - } - statsSummaries = append(statsSummaries, s) - } - return statsSummaries, nil -} - -// CreateStatsSummaryV5 handler for creating stats summaries -func CreateStatsSummaryV5(w http.ResponseWriter, r *http.Request) { - inf, userErr, sysErr, errCode := api.NewInfo(r, []string{}, []string{}) - if userErr != nil || sysErr != nil { - api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) - return - } - defer inf.Close() - - ss := tc.StatsSummaryV5{} - - if err := api.Parse(r.Body, inf.Tx.Tx, &ss); err != nil { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil) - return - } - - // CDN Name and Delivery service name are defaulted to "all" if not defined - if ss.CDNName == nil || len(*ss.CDNName) == 0 { - ss.CDNName = util.Ptr("all") - } - - if ss.DeliveryService == nil || len(*ss.DeliveryService) == 0 { - ss.DeliveryService = util.Ptr("all") - } - - id := -1 - rows, err := inf.Tx.NamedQuery(insertQuery(), &ss) - if err != nil { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("inserting stats summary: %v", err)) - return - } - for rows.Next() { - if err := rows.Scan(&id); err != nil { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("scanning created stats summary id: %v", err)) - return - } - } - if id == -1 { - api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, fmt.Errorf("sstats summary id: %v", err)) - return - } - - successMsg := "Stats Summary was successfully created" - api.WriteRespAlert(w, r, tc.SuccessLevel, successMsg) -} - func selectQuery() string { return `SELECT cdn_name, diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go index 6448a7b929..cb56916daa 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go @@ -60,7 +60,7 @@ func TestQueryStatsSummaryV5(t *testing.T) { mock.ExpectQuery("SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary").WithArgs().WillReturnRows(rows) - statsSummaries1, err1 := QueryStatsSummaryV5(db.MustBegin(), query, queryValues) + statsSummaries1, err1 := queryStatsSummary(db.MustBegin(), query, queryValues) assert.NoError(t, err1) assert.Equal(t, len(statsSummaries1), 2) From 7a008a9c133e913e314b1b178735ed06a24cc1e8 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Thu, 8 Jun 2023 11:20:15 +0530 Subject: [PATCH 09/23] Fixed CHANGELOG.md for https://github.com/apache/trafficcontrol/issues/7544 --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b2cc5959a..ca70b6e8e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,7 +68,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#7572](https://github.com/apache/trafficcontrol/pull/7572) *Traffic Ops* Fixes Delivery Service Requests V5 apis docs with RFC3339 date/time Format - [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. - [#7544](https://github.com/apache/trafficcontrol/issues/7544) *Traffic Ops* Fixes stats_summary v5 apis to respond with RFC3339 date/time Format. -- [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. - [#7542](https://github.com/apache/trafficcontrol/pull/7542) *Traffic Ops* Fixed `CDN Locks` documentation to reflect the correct RFC3339 timestamps. - [#6340](https://github.com/apache/trafficcontrol/issues/6340) *Traffic Ops* Fixed alert messages for POST and PUT invalidation job APIs. - [#7519] (https://github.com/apache/trafficcontrol/issues/7519) *Traffic Ops* Fixed TO API /servers/{id}/deliveryservices endpoint to responding with all DS's on cache that are directly assigned and inherited through topology. From 04f6f741f711efa5820b887cff54d5a2fce95fce Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Thu, 8 Jun 2023 11:29:01 +0530 Subject: [PATCH 10/23] Fixed CHANGELOG.md for https://github.com/apache/trafficcontrol/issues/7544 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca70b6e8e9..e64fe13fd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [unreleased] ### Added +- [#7450](https://github.com/apache/trafficcontrol/pull/7450) *Traffic Ops* Removed hypnotoad section and added listen field to traffic_ops_golang section in order to simplify cdn config. - [#7290](https://github.com/apache/trafficcontrol/pull/7302) *Traffic Monitor* Update TM results with hostname from via header, syncronize health on caches with same service address - [#7291](https://github.com/apache/trafficcontrol/pull/7291) *Traffic Ops* Extended Layered Profile feature to aggregate parameters for all server profiles. - [#7314](https://github.com/apache/trafficcontrol/pull/7314) *Traffic Portal* Added capability feature to Delivery Service Form (HTTP, DNS). From f87d6937185ff2524ea0255857379f16c01f9a54 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Thu, 8 Jun 2023 11:30:44 +0530 Subject: [PATCH 11/23] Fixed CHANGELOG.md for https://github.com/apache/trafficcontrol/issues/7544 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e64fe13fd4..101fb07383 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#7516](https://github.com/apache/trafficcontrol/pull/7516) *t3c* added command line arg to control go_direct in parent.config - [#7602](https://github.com/apache/trafficcontrol/pull/7602) *t3c* added installed package data to t3c-apply-metadata.json + ### Changed - [#7584](https://github.com/apache/trafficcontrol/pull/7584) *Documentation* Upgrade Traffic Control Sphinx documentation Makefile OS intelligent. - [#7521](https://github.com/apache/trafficcontrol/pull/7521) *Traffic Ops* Returns empty array instead of null when no permissions are given for roles endpoint using POST or PUT request. From bb287ccae0944acd3d612f857c5a9f2cd3c5c792 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Thu, 8 Jun 2023 11:32:11 +0530 Subject: [PATCH 12/23] Fixed PR review comments for https://github.com/apache/trafficcontrol/issues/7544 --- .../traffic_ops_golang/trafficstats/stats_summary_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go index cb56916daa..b94f623864 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go @@ -29,7 +29,7 @@ import ( * under the License. */ -func TestQueryStatsSummaryV5(t *testing.T) { +func TestQueryStatsSummary(t *testing.T) { query := "SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary" queryValues := map[string]interface{}{ From 9f8fe05b4cf93204333d9853d5dd90f6371cc865 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Wed, 14 Jun 2023 21:27:41 +0530 Subject: [PATCH 13/23] Fixed PR Review comments --- lib/go-tc/stats_summary.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/go-tc/stats_summary.go b/lib/go-tc/stats_summary.go index 94ef478392..47ab78d941 100644 --- a/lib/go-tc/stats_summary.go +++ b/lib/go-tc/stats_summary.go @@ -23,6 +23,7 @@ import ( "database/sql" "encoding/json" "errors" + "fmt" "time" "github.com/apache/trafficcontrol/lib/go-tc/tovalidate" @@ -231,14 +232,14 @@ func (ss *StatsSummaryV5) UnmarshalJSON(data []byte) error { if resp.StatDate != nil { statDate, err := parseTimeV5(*resp.StatDate) if err != nil { - return errors.New("invalid timestamp given for statDate") + return fmt.Errorf("invalid timestamp given for statDate: %v", err) } ss.StatDate = &statDate } ss.SummaryTime, err = parseTimeV5(resp.SummaryTime) if err != nil { - return errors.New("invalid timestamp given for summaryTime") + return fmt.Errorf("invalid timestamp given for summaryTime: %v", err) } return nil } From 6974d897a958a6d5b65dfed2f619560abf7c15be Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Wed, 14 Jun 2023 21:32:37 +0530 Subject: [PATCH 14/23] Fixed CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 101fb07383..e64fe13fd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#7516](https://github.com/apache/trafficcontrol/pull/7516) *t3c* added command line arg to control go_direct in parent.config - [#7602](https://github.com/apache/trafficcontrol/pull/7602) *t3c* added installed package data to t3c-apply-metadata.json - ### Changed - [#7584](https://github.com/apache/trafficcontrol/pull/7584) *Documentation* Upgrade Traffic Control Sphinx documentation Makefile OS intelligent. - [#7521](https://github.com/apache/trafficcontrol/pull/7521) *Traffic Ops* Returns empty array instead of null when no permissions are given for roles endpoint using POST or PUT request. From 02c4a5393b35079db774c46e8127888e3b6c991a Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Wed, 21 Jun 2023 11:54:52 +0530 Subject: [PATCH 15/23] Update stats_summary lib --- lib/go-tc/stats_summary.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/go-tc/stats_summary.go b/lib/go-tc/stats_summary.go index 47ab78d941..bee02eba19 100644 --- a/lib/go-tc/stats_summary.go +++ b/lib/go-tc/stats_summary.go @@ -217,7 +217,7 @@ func (ss StatsSummaryV5) Validate(tx *sql.Tx) error { // UnmarshalJSON implements the encoding/json.Unmarshaler interface with a // customized decoding to force the date format on StatDate. func (ss *StatsSummaryV5) UnmarshalJSON(data []byte) error { - type Alias StatsSummary + type Alias StatsSummaryV5 resp := struct { SummaryTime string `json:"summaryTime"` StatDate *string `json:"statDate"` @@ -319,6 +319,7 @@ func (ss *StatsSummaryLastUpdatedV5) UnmarshalJSON(data []byte) error { ss.SummaryTime = &summaryTime return nil } + return err } return nil } From a7e490a364cc3e94a0eb1467e36508998ff8b9de Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 23 Jun 2023 10:44:34 +0530 Subject: [PATCH 16/23] Updated statessummary file --- .../trafficstats/stats_summary.go | 92 ++++++++++++++----- .../trafficstats/stats_summary_test.go | 2 +- 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go index f002105de1..deb4c7d346 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary.go @@ -59,7 +59,7 @@ func getLastSummaryDate(w http.ResponseWriter, r *http.Request, inf *api.APIInfo return } query := selectQuery() + where + " ORDER BY summary_time DESC" - statsSummaries, err := queryStatsSummary(inf.Tx, query, queryValues) + statsSummaries, err := queryStatsSummary(inf.Tx, inf.Version.Major, query, queryValues) if err != nil { api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) return @@ -68,14 +68,18 @@ func getLastSummaryDate(w http.ResponseWriter, r *http.Request, inf *api.APIInfo if inf.Version.Major >= 5 { resp := tc.StatsSummaryLastUpdatedV5{} if len(statsSummaries) >= 1 { - resp.SummaryTime = &statsSummaries[0].SummaryTime + if summary, ok := statsSummaries[0].(tc.StatsSummaryV5); ok { + resp.SummaryTime = &summary.SummaryTime + } } api.WriteResp(w, r, resp) } else { resp := tc.StatsSummaryLastUpdated{} if len(statsSummaries) >= 1 { - resp.SummaryTime = &statsSummaries[0].SummaryTime + if summary, ok := statsSummaries[0].(tc.StatsSummary); ok { + resp.SummaryTime = &summary.SummaryTime + } } api.WriteResp(w, r, resp) } @@ -94,50 +98,90 @@ func getStatsSummary(w http.ResponseWriter, r *http.Request, inf *api.APIInfo) { return } query := selectQuery() + where + orderBy + pagination - statsSummaries, err := queryStatsSummary(inf.Tx, query, queryValues) + queryStatsSummaries, err := queryStatsSummary(inf.Tx, inf.Version.Major, query, queryValues) if err != nil { api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, err) return } + //api.WriteResp(w, r, statsSummaries) + if inf.Version.Major >= 5 { - statsSummariesV5 := make([]tc.StatsSummaryV5, len(statsSummaries)) - for i, oldStat := range statsSummaries { - newStat := tc.StatsSummaryV5{ - CDNName: oldStat.CDNName, - DeliveryService: oldStat.DeliveryService, - StatName: oldStat.StatName, - StatValue: oldStat.StatValue, - SummaryTime: oldStat.SummaryTime, - StatDate: oldStat.StatDate, + statsSummariesV5 := make([]tc.StatsSummaryV5, len(queryStatsSummaries)) + for i, oldStat := range queryStatsSummaries { + if summary, ok := oldStat.(tc.StatsSummaryV5); ok { + newStat := tc.StatsSummaryV5{ + CDNName: summary.CDNName, + DeliveryService: summary.DeliveryService, + StatName: summary.StatName, + StatValue: summary.StatValue, + SummaryTime: summary.SummaryTime, + StatDate: summary.StatDate, + } + statsSummariesV5[i] = newStat } - statsSummariesV5[i] = newStat } - api.WriteResp(w, r, statsSummariesV5) - } else { + statsSummaries := make([]tc.StatsSummary, len(queryStatsSummaries)) + for i, oldStat := range queryStatsSummaries { + if summary, ok := oldStat.(tc.StatsSummary); ok { + newStat := tc.StatsSummary{ + CDNName: summary.CDNName, + DeliveryService: summary.DeliveryService, + StatName: summary.StatName, + StatValue: summary.StatValue, + SummaryTime: summary.SummaryTime, + StatDate: summary.StatDate, + } + statsSummaries[i] = newStat + } + } api.WriteResp(w, r, statsSummaries) } } -func queryStatsSummary(tx *sqlx.Tx, q string, queryValues map[string]interface{}) ([]tc.StatsSummary, error) { +func queryStatsSummary(tx *sqlx.Tx, version uint64, q string, queryValues map[string]interface{}) ([]interface{}, error) { rows, err := tx.NamedQuery(q, queryValues) if err != nil { return nil, fmt.Errorf("querying stats summary: %v", err) } defer rows.Close() - statsSummaries := []tc.StatsSummary{} - for rows.Next() { - s := tc.StatsSummary{} - if err = rows.StructScan(&s); err != nil { - return nil, fmt.Errorf("scanning stats summary: %v", err) + var returnStatsSummaries []interface{} + + if version >= 5 { + var statsSummariesV5 []tc.StatsSummaryV5 + for rows.Next() { + s := tc.StatsSummaryV5{} + if err = rows.StructScan(&s); err != nil { + return nil, fmt.Errorf("scanning stats summary: %v", err) + } + statsSummariesV5 = append(statsSummariesV5, s) + } + returnStatsSummaries = make([]interface{}, len(statsSummariesV5)) + for i, v := range statsSummariesV5 { + returnStatsSummaries[i] = v + } + + } else { + var statsSummaries []tc.StatsSummary + for rows.Next() { + s := tc.StatsSummary{} + if err = rows.StructScan(&s); err != nil { + return nil, fmt.Errorf("scanning stats summary: %v", err) + } + statsSummaries = append(statsSummaries, s) + } + + returnStatsSummaries = make([]interface{}, len(statsSummaries)) + for i, v := range statsSummaries { + returnStatsSummaries[i] = v } - statsSummaries = append(statsSummaries, s) } - return statsSummaries, nil + return returnStatsSummaries, nil + } // CreateStatsSummary handler for creating stats summaries diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go index b94f623864..e585499cf8 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go @@ -60,7 +60,7 @@ func TestQueryStatsSummary(t *testing.T) { mock.ExpectQuery("SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary").WithArgs().WillReturnRows(rows) - statsSummaries1, err1 := queryStatsSummary(db.MustBegin(), query, queryValues) + statsSummaries1, err1 := queryStatsSummary(db.MustBegin(), 5, query, queryValues) assert.NoError(t, err1) assert.Equal(t, len(statsSummaries1), 2) From 1676dc6c4fca44b67bac491c4abda79ccc512ecf Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 23 Jun 2023 11:11:58 +0530 Subject: [PATCH 17/23] Updated unit test cases --- .../trafficstats/stats_summary_test.go | 74 +++++++++++-------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go index e585499cf8..45dbfa7b79 100644 --- a/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go +++ b/traffic_ops/traffic_ops_golang/trafficstats/stats_summary_test.go @@ -1,15 +1,5 @@ package trafficstats -import ( - "testing" - "time" - - "github.com/apache/trafficcontrol/lib/go-util/assert" - - "github.com/jmoiron/sqlx" - "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 @@ -29,40 +19,60 @@ import ( * under the License. */ +import ( + "testing" + "time" + + "github.com/apache/trafficcontrol/lib/go-util/assert" + + "github.com/jmoiron/sqlx" + "gopkg.in/DATA-DOG/go-sqlmock.v1" +) + func TestQueryStatsSummary(t *testing.T) { + type testStruct struct { + version uint64 + } + + var testData = []testStruct{ + {4}, + {5}, + } query := "SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary" queryValues := map[string]interface{}{ "lastSummaryDate": "true", } - mockDB, mock, err := sqlmock.New() - if err != nil { - t.Fatalf("an error '%v' was not expected when opening a stub database connection", err) - } - defer mockDB.Close() + for i, _ := range testData { + mockDB, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%v' was not expected when opening a stub database connection", err) + } + defer mockDB.Close() - db := sqlx.NewDb(mockDB, "sqlmock") - defer db.Close() + db := sqlx.NewDb(mockDB, "sqlmock") + defer db.Close() - mock.ExpectBegin() - rows := sqlmock.NewRows([]string{ - "cdn_name", - "deliveryservice_name", - "stat_name", - "stat_value", - "summary_time", - "stat_date", - }) + mock.ExpectBegin() + rows := sqlmock.NewRows([]string{ + "cdn_name", + "deliveryservice_name", + "stat_name", + "stat_value", + "summary_time", + "stat_date", + }) - rows.AddRow("cdn1", "all", "daily_maxgbps", 5, time.Now().AddDate(0, 0, -5), time.Now().AddDate(0, 0, -5).Truncate(24*time.Hour)) - rows.AddRow("cdn2", "all", "daily_byteserved", 1000, time.Now().AddDate(0, 0, -10), time.Now().AddDate(0, 0, -10).Truncate(24*time.Hour)) + rows.AddRow("cdn1", "all", "daily_maxgbps", 5, time.Now().AddDate(0, 0, -5), time.Now().AddDate(0, 0, -5).Truncate(24*time.Hour)) + rows.AddRow("cdn2", "all", "daily_byteserved", 1000, time.Now().AddDate(0, 0, -10), time.Now().AddDate(0, 0, -10).Truncate(24*time.Hour)) - mock.ExpectQuery("SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary").WithArgs().WillReturnRows(rows) + mock.ExpectQuery("SELECT cdn_name, deliveryservice_name, stat_name, stat_value, summary_time, stat_date FROM stats_summary").WithArgs().WillReturnRows(rows) - statsSummaries1, err1 := queryStatsSummary(db.MustBegin(), 5, query, queryValues) + statsSummaries1, err1 := queryStatsSummary(db.MustBegin(), testData[i].version, query, queryValues) - assert.NoError(t, err1) - assert.Equal(t, len(statsSummaries1), 2) + assert.NoError(t, err1) + assert.Equal(t, len(statsSummaries1), 2) + } } From 33088b7321f4acf1132995e4538b1705930f8606 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 23 Jun 2023 22:20:32 +0530 Subject: [PATCH 18/23] Temp changes to check GHA --- traffic_ops/testing/api/v4/stats_summary_test.go | 8 ++++++++ traffic_ops/testing/api/v5/stats_summary_test.go | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/traffic_ops/testing/api/v4/stats_summary_test.go b/traffic_ops/testing/api/v4/stats_summary_test.go index 3a68783b4a..f28abfcdbd 100644 --- a/traffic_ops/testing/api/v4/stats_summary_test.go +++ b/traffic_ops/testing/api/v4/stats_summary_test.go @@ -16,6 +16,7 @@ package v4 */ import ( + "fmt" "net/http" "net/url" "testing" @@ -89,6 +90,13 @@ func TestStatsSummary(t *testing.T) { t.Run(name, func(t *testing.T) { if name == "OK when VALID LASTSUMMARYDATE parameter" { resp, reqInf, err := testCase.ClientSession.GetSummaryStatsLastUpdated(testCase.RequestOpts) + + fmt.Println("reqInf", reqInf) + fmt.Println("resp", resp) + fmt.Println("resp.Alerts", resp.Alerts) + fmt.Println("Expected SummaryTime", resp.Response.SummaryTime) + fmt.Println("Actual SummaryTime:", latestTime) + for _, check := range testCase.Expectations { check(t, reqInf, resp.Response, resp.Alerts, err) } diff --git a/traffic_ops/testing/api/v5/stats_summary_test.go b/traffic_ops/testing/api/v5/stats_summary_test.go index d4b4357e85..de4cc492ef 100644 --- a/traffic_ops/testing/api/v5/stats_summary_test.go +++ b/traffic_ops/testing/api/v5/stats_summary_test.go @@ -16,6 +16,7 @@ package v5 */ import ( + "fmt" "net/http" "net/url" "testing" @@ -89,6 +90,13 @@ func TestStatsSummary(t *testing.T) { t.Run(name, func(t *testing.T) { if name == "OK when VALID LASTSUMMARYDATE parameter" { resp, reqInf, err := testCase.ClientSession.GetSummaryStatsLastUpdated(testCase.RequestOpts) + + fmt.Println("reqInf", reqInf) + fmt.Println("resp", resp) + fmt.Println("resp.Alerts", resp.Alerts) + fmt.Println("Expected SummaryTime", resp.Response.SummaryTime) + fmt.Println("Actual SummaryTime:", latestTime) + for _, check := range testCase.Expectations { check(t, reqInf, resp.Response, resp.Alerts, err) } From 789d98bccaba17cb49a10ea89864d293fb3c1640 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 23 Jun 2023 22:41:29 +0530 Subject: [PATCH 19/23] Temp changes to check GHA --- .github/workflows/to.integration.tests.yml | 310 ++++++++++----------- 1 file changed, 155 insertions(+), 155 deletions(-) diff --git a/.github/workflows/to.integration.tests.yml b/.github/workflows/to.integration.tests.yml index 2be60a5f1c..57750cb495 100644 --- a/.github/workflows/to.integration.tests.yml +++ b/.github/workflows/to.integration.tests.yml @@ -57,161 +57,161 @@ on: jobs: - APIv3Tests: - if: github.event.pull_request.draft == false - runs-on: ubuntu-latest - - services: - postgres: - image: postgres:13 - env: - POSTGRES_USER: traffic_ops - POSTGRES_PASSWORD: twelve - POSTGRES_DB: traffic_ops - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - - smtp: - image: maildev/maildev:2.0.0-beta3 - ports: - - 25:25 - options: >- - --entrypoint=bin/maildev - --user=root - --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" - -- - maildev/maildev:2.0.0-beta3 - --smtp=25 - --hide-extensions=STARTTLS - --web=80 - - steps: - - name: Checkout - uses: actions/checkout@master - - name: Cache Alpine Docker image - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/docker-images - key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz - - name: Import cached Alpine Docker image - run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} - - name: Initialize Traffic Ops Database - id: todb - uses: ./.github/actions/todb-init - - name: Initialize Traffic Vault Database - id: tvdb - uses: ./.github/actions/tvdb-init - - name: Check Go Version - run: echo "::set-output name=value::$(cat GO_VERSION)" - id: go-version - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: ${{ steps.go-version.outputs.value }} - - name: Run API v3 tests - id: v3Tests - if: ${{ steps.todb.outcome == 'success' && always() }} - uses: ./.github/actions/to-integration-tests - with: - version: 3 - smtp_address: 172.17.0.1 - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - files: v3-coverage.out - flags: traffic_ops_integration,v3 - - name: Upload v3 Vault logs - if: ${{ steps.v3Tests.outcome != 'success' && always() }} - uses: actions/upload-artifact@v2 - with: - name: v3 Traffic Vault logs - path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs - - name: Upload v3 Ops logs - if: ${{ steps.v3Tests.outcome != 'success' && always() }} - uses: actions/upload-artifact@v2 - with: - name: v3 Traffic Ops logs - path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log - - APIv4Tests: - if: github.event.pull_request.draft == false - runs-on: ubuntu-latest - - services: - postgres: - image: postgres:13 - env: - POSTGRES_USER: traffic_ops - POSTGRES_PASSWORD: twelve - POSTGRES_DB: traffic_ops - ports: - - 5432:5432 - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - - smtp: - image: maildev/maildev:2.0.0-beta3 - ports: - - 25:25 - options: >- - --entrypoint=bin/maildev - --user=root - --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" - -- - maildev/maildev:2.0.0-beta3 - --smtp=25 - --hide-extensions=STARTTLS - --web=80 - - steps: - - name: Checkout - uses: actions/checkout@master - - name: Cache Alpine Docker image - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/docker-images - key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz - - name: Import cached Alpine Docker image - run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} - - name: Initialize Traffic Ops Database - id: todb - uses: ./.github/actions/todb-init - - name: Initialize Traffic Vault Database - id: tvdb - uses: ./.github/actions/tvdb-init - - name: Check Go Version - run: echo "::set-output name=value::$(cat GO_VERSION)" - id: go-version - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: ${{ steps.go-version.outputs.value }} - - name: Run API v4 tests - id: v4Tests - if: ${{ steps.todb.outcome == 'success' && always() }} - uses: ./.github/actions/to-integration-tests - with: - version: 4 - smtp_address: 172.17.0.1 - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - files: v4-coverage.out - flags: traffic_ops_integration,v4 - - name: Upload v4 Vault logs - if: ${{ steps.v4Tests.outcome != 'success' && always() }} - uses: actions/upload-artifact@v2 - with: - name: v4 Traffic Vault logs - path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs - - name: Upload v4 Ops logs - if: ${{ steps.v4Tests.outcome != 'success' && always() }} - uses: actions/upload-artifact@v2 - with: - name: v4 Traffic Ops logs - path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log - - name: Save Alpine Docker image - run: .github/actions/save-alpine-tar/entrypoint.sh save ${{ env.ALPINE_VERSION }} +# APIv3Tests: +# if: github.event.pull_request.draft == false +# runs-on: ubuntu-latest +# +# services: +# postgres: +# image: postgres:13 +# env: +# POSTGRES_USER: traffic_ops +# POSTGRES_PASSWORD: twelve +# POSTGRES_DB: traffic_ops +# ports: +# - 5432:5432 +# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 +# +# smtp: +# image: maildev/maildev:2.0.0-beta3 +# ports: +# - 25:25 +# options: >- +# --entrypoint=bin/maildev +# --user=root +# --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" +# -- +# maildev/maildev:2.0.0-beta3 +# --smtp=25 +# --hide-extensions=STARTTLS +# --web=80 +# +# steps: +# - name: Checkout +# uses: actions/checkout@master +# - name: Cache Alpine Docker image +# uses: actions/cache@v2 +# with: +# path: ${{ github.workspace }}/docker-images +# key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz +# - name: Import cached Alpine Docker image +# run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} +# - name: Initialize Traffic Ops Database +# id: todb +# uses: ./.github/actions/todb-init +# - name: Initialize Traffic Vault Database +# id: tvdb +# uses: ./.github/actions/tvdb-init +# - name: Check Go Version +# run: echo "::set-output name=value::$(cat GO_VERSION)" +# id: go-version +# - name: Install Go +# uses: actions/setup-go@v2 +# with: +# go-version: ${{ steps.go-version.outputs.value }} +# - name: Run API v3 tests +# id: v3Tests +# if: ${{ steps.todb.outcome == 'success' && always() }} +# uses: ./.github/actions/to-integration-tests +# with: +# version: 3 +# smtp_address: 172.17.0.1 +# - name: Upload coverage to Codecov +# uses: codecov/codecov-action@v3 +# with: +# files: v3-coverage.out +# flags: traffic_ops_integration,v3 +# - name: Upload v3 Vault logs +# if: ${{ steps.v3Tests.outcome != 'success' && always() }} +# uses: actions/upload-artifact@v2 +# with: +# name: v3 Traffic Vault logs +# path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs +# - name: Upload v3 Ops logs +# if: ${{ steps.v3Tests.outcome != 'success' && always() }} +# uses: actions/upload-artifact@v2 +# with: +# name: v3 Traffic Ops logs +# path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log +# +# APIv4Tests: +# if: github.event.pull_request.draft == false +# runs-on: ubuntu-latest +# +# services: +# postgres: +# image: postgres:13 +# env: +# POSTGRES_USER: traffic_ops +# POSTGRES_PASSWORD: twelve +# POSTGRES_DB: traffic_ops +# ports: +# - 5432:5432 +# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 +# +# smtp: +# image: maildev/maildev:2.0.0-beta3 +# ports: +# - 25:25 +# options: >- +# --entrypoint=bin/maildev +# --user=root +# --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" +# -- +# maildev/maildev:2.0.0-beta3 +# --smtp=25 +# --hide-extensions=STARTTLS +# --web=80 +# +# steps: +# - name: Checkout +# uses: actions/checkout@master +# - name: Cache Alpine Docker image +# uses: actions/cache@v2 +# with: +# path: ${{ github.workspace }}/docker-images +# key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz +# - name: Import cached Alpine Docker image +# run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} +# - name: Initialize Traffic Ops Database +# id: todb +# uses: ./.github/actions/todb-init +# - name: Initialize Traffic Vault Database +# id: tvdb +# uses: ./.github/actions/tvdb-init +# - name: Check Go Version +# run: echo "::set-output name=value::$(cat GO_VERSION)" +# id: go-version +# - name: Install Go +# uses: actions/setup-go@v2 +# with: +# go-version: ${{ steps.go-version.outputs.value }} +# - name: Run API v4 tests +# id: v4Tests +# if: ${{ steps.todb.outcome == 'success' && always() }} +# uses: ./.github/actions/to-integration-tests +# with: +# version: 4 +# smtp_address: 172.17.0.1 +# - name: Upload coverage to Codecov +# uses: codecov/codecov-action@v3 +# with: +# files: v4-coverage.out +# flags: traffic_ops_integration,v4 +# - name: Upload v4 Vault logs +# if: ${{ steps.v4Tests.outcome != 'success' && always() }} +# uses: actions/upload-artifact@v2 +# with: +# name: v4 Traffic Vault logs +# path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs +# - name: Upload v4 Ops logs +# if: ${{ steps.v4Tests.outcome != 'success' && always() }} +# uses: actions/upload-artifact@v2 +# with: +# name: v4 Traffic Ops logs +# path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log +# - name: Save Alpine Docker image +# run: .github/actions/save-alpine-tar/entrypoint.sh save ${{ env.ALPINE_VERSION }} APIv5Tests: if: github.event.pull_request.draft == false From 200b082d1da06149c82a12b8549c28d4afa0f520 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Fri, 23 Jun 2023 22:55:19 +0530 Subject: [PATCH 20/23] revert Temp changes to check GHA --- .github/workflows/to.integration.tests.yml | 310 +++++++++--------- .../testing/api/v4/stats_summary_test.go | 8 - .../testing/api/v5/stats_summary_test.go | 8 - 3 files changed, 155 insertions(+), 171 deletions(-) diff --git a/.github/workflows/to.integration.tests.yml b/.github/workflows/to.integration.tests.yml index 57750cb495..2be60a5f1c 100644 --- a/.github/workflows/to.integration.tests.yml +++ b/.github/workflows/to.integration.tests.yml @@ -57,161 +57,161 @@ on: jobs: -# APIv3Tests: -# if: github.event.pull_request.draft == false -# runs-on: ubuntu-latest -# -# services: -# postgres: -# image: postgres:13 -# env: -# POSTGRES_USER: traffic_ops -# POSTGRES_PASSWORD: twelve -# POSTGRES_DB: traffic_ops -# ports: -# - 5432:5432 -# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 -# -# smtp: -# image: maildev/maildev:2.0.0-beta3 -# ports: -# - 25:25 -# options: >- -# --entrypoint=bin/maildev -# --user=root -# --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" -# -- -# maildev/maildev:2.0.0-beta3 -# --smtp=25 -# --hide-extensions=STARTTLS -# --web=80 -# -# steps: -# - name: Checkout -# uses: actions/checkout@master -# - name: Cache Alpine Docker image -# uses: actions/cache@v2 -# with: -# path: ${{ github.workspace }}/docker-images -# key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz -# - name: Import cached Alpine Docker image -# run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} -# - name: Initialize Traffic Ops Database -# id: todb -# uses: ./.github/actions/todb-init -# - name: Initialize Traffic Vault Database -# id: tvdb -# uses: ./.github/actions/tvdb-init -# - name: Check Go Version -# run: echo "::set-output name=value::$(cat GO_VERSION)" -# id: go-version -# - name: Install Go -# uses: actions/setup-go@v2 -# with: -# go-version: ${{ steps.go-version.outputs.value }} -# - name: Run API v3 tests -# id: v3Tests -# if: ${{ steps.todb.outcome == 'success' && always() }} -# uses: ./.github/actions/to-integration-tests -# with: -# version: 3 -# smtp_address: 172.17.0.1 -# - name: Upload coverage to Codecov -# uses: codecov/codecov-action@v3 -# with: -# files: v3-coverage.out -# flags: traffic_ops_integration,v3 -# - name: Upload v3 Vault logs -# if: ${{ steps.v3Tests.outcome != 'success' && always() }} -# uses: actions/upload-artifact@v2 -# with: -# name: v3 Traffic Vault logs -# path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs -# - name: Upload v3 Ops logs -# if: ${{ steps.v3Tests.outcome != 'success' && always() }} -# uses: actions/upload-artifact@v2 -# with: -# name: v3 Traffic Ops logs -# path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log -# -# APIv4Tests: -# if: github.event.pull_request.draft == false -# runs-on: ubuntu-latest -# -# services: -# postgres: -# image: postgres:13 -# env: -# POSTGRES_USER: traffic_ops -# POSTGRES_PASSWORD: twelve -# POSTGRES_DB: traffic_ops -# ports: -# - 5432:5432 -# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 -# -# smtp: -# image: maildev/maildev:2.0.0-beta3 -# ports: -# - 25:25 -# options: >- -# --entrypoint=bin/maildev -# --user=root -# --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" -# -- -# maildev/maildev:2.0.0-beta3 -# --smtp=25 -# --hide-extensions=STARTTLS -# --web=80 -# -# steps: -# - name: Checkout -# uses: actions/checkout@master -# - name: Cache Alpine Docker image -# uses: actions/cache@v2 -# with: -# path: ${{ github.workspace }}/docker-images -# key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz -# - name: Import cached Alpine Docker image -# run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} -# - name: Initialize Traffic Ops Database -# id: todb -# uses: ./.github/actions/todb-init -# - name: Initialize Traffic Vault Database -# id: tvdb -# uses: ./.github/actions/tvdb-init -# - name: Check Go Version -# run: echo "::set-output name=value::$(cat GO_VERSION)" -# id: go-version -# - name: Install Go -# uses: actions/setup-go@v2 -# with: -# go-version: ${{ steps.go-version.outputs.value }} -# - name: Run API v4 tests -# id: v4Tests -# if: ${{ steps.todb.outcome == 'success' && always() }} -# uses: ./.github/actions/to-integration-tests -# with: -# version: 4 -# smtp_address: 172.17.0.1 -# - name: Upload coverage to Codecov -# uses: codecov/codecov-action@v3 -# with: -# files: v4-coverage.out -# flags: traffic_ops_integration,v4 -# - name: Upload v4 Vault logs -# if: ${{ steps.v4Tests.outcome != 'success' && always() }} -# uses: actions/upload-artifact@v2 -# with: -# name: v4 Traffic Vault logs -# path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs -# - name: Upload v4 Ops logs -# if: ${{ steps.v4Tests.outcome != 'success' && always() }} -# uses: actions/upload-artifact@v2 -# with: -# name: v4 Traffic Ops logs -# path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log -# - name: Save Alpine Docker image -# run: .github/actions/save-alpine-tar/entrypoint.sh save ${{ env.ALPINE_VERSION }} + APIv3Tests: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:13 + env: + POSTGRES_USER: traffic_ops + POSTGRES_PASSWORD: twelve + POSTGRES_DB: traffic_ops + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + smtp: + image: maildev/maildev:2.0.0-beta3 + ports: + - 25:25 + options: >- + --entrypoint=bin/maildev + --user=root + --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" + -- + maildev/maildev:2.0.0-beta3 + --smtp=25 + --hide-extensions=STARTTLS + --web=80 + + steps: + - name: Checkout + uses: actions/checkout@master + - name: Cache Alpine Docker image + uses: actions/cache@v2 + with: + path: ${{ github.workspace }}/docker-images + key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz + - name: Import cached Alpine Docker image + run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} + - name: Initialize Traffic Ops Database + id: todb + uses: ./.github/actions/todb-init + - name: Initialize Traffic Vault Database + id: tvdb + uses: ./.github/actions/tvdb-init + - name: Check Go Version + run: echo "::set-output name=value::$(cat GO_VERSION)" + id: go-version + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ steps.go-version.outputs.value }} + - name: Run API v3 tests + id: v3Tests + if: ${{ steps.todb.outcome == 'success' && always() }} + uses: ./.github/actions/to-integration-tests + with: + version: 3 + smtp_address: 172.17.0.1 + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + files: v3-coverage.out + flags: traffic_ops_integration,v3 + - name: Upload v3 Vault logs + if: ${{ steps.v3Tests.outcome != 'success' && always() }} + uses: actions/upload-artifact@v2 + with: + name: v3 Traffic Vault logs + path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs + - name: Upload v3 Ops logs + if: ${{ steps.v3Tests.outcome != 'success' && always() }} + uses: actions/upload-artifact@v2 + with: + name: v3 Traffic Ops logs + path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log + + APIv4Tests: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:13 + env: + POSTGRES_USER: traffic_ops + POSTGRES_PASSWORD: twelve + POSTGRES_DB: traffic_ops + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + smtp: + image: maildev/maildev:2.0.0-beta3 + ports: + - 25:25 + options: >- + --entrypoint=bin/maildev + --user=root + --health-cmd="sh -c \"[[ \$(wget -qO- http://smtp/healthz) == true ]]\"" + -- + maildev/maildev:2.0.0-beta3 + --smtp=25 + --hide-extensions=STARTTLS + --web=80 + + steps: + - name: Checkout + uses: actions/checkout@master + - name: Cache Alpine Docker image + uses: actions/cache@v2 + with: + path: ${{ github.workspace }}/docker-images + key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz + - name: Import cached Alpine Docker image + run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }} + - name: Initialize Traffic Ops Database + id: todb + uses: ./.github/actions/todb-init + - name: Initialize Traffic Vault Database + id: tvdb + uses: ./.github/actions/tvdb-init + - name: Check Go Version + run: echo "::set-output name=value::$(cat GO_VERSION)" + id: go-version + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ steps.go-version.outputs.value }} + - name: Run API v4 tests + id: v4Tests + if: ${{ steps.todb.outcome == 'success' && always() }} + uses: ./.github/actions/to-integration-tests + with: + version: 4 + smtp_address: 172.17.0.1 + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + files: v4-coverage.out + flags: traffic_ops_integration,v4 + - name: Upload v4 Vault logs + if: ${{ steps.v4Tests.outcome != 'success' && always() }} + uses: actions/upload-artifact@v2 + with: + name: v4 Traffic Vault logs + path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs + - name: Upload v4 Ops logs + if: ${{ steps.v4Tests.outcome != 'success' && always() }} + uses: actions/upload-artifact@v2 + with: + name: v4 Traffic Ops logs + path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log + - name: Save Alpine Docker image + run: .github/actions/save-alpine-tar/entrypoint.sh save ${{ env.ALPINE_VERSION }} APIv5Tests: if: github.event.pull_request.draft == false diff --git a/traffic_ops/testing/api/v4/stats_summary_test.go b/traffic_ops/testing/api/v4/stats_summary_test.go index f28abfcdbd..3a68783b4a 100644 --- a/traffic_ops/testing/api/v4/stats_summary_test.go +++ b/traffic_ops/testing/api/v4/stats_summary_test.go @@ -16,7 +16,6 @@ package v4 */ import ( - "fmt" "net/http" "net/url" "testing" @@ -90,13 +89,6 @@ func TestStatsSummary(t *testing.T) { t.Run(name, func(t *testing.T) { if name == "OK when VALID LASTSUMMARYDATE parameter" { resp, reqInf, err := testCase.ClientSession.GetSummaryStatsLastUpdated(testCase.RequestOpts) - - fmt.Println("reqInf", reqInf) - fmt.Println("resp", resp) - fmt.Println("resp.Alerts", resp.Alerts) - fmt.Println("Expected SummaryTime", resp.Response.SummaryTime) - fmt.Println("Actual SummaryTime:", latestTime) - for _, check := range testCase.Expectations { check(t, reqInf, resp.Response, resp.Alerts, err) } diff --git a/traffic_ops/testing/api/v5/stats_summary_test.go b/traffic_ops/testing/api/v5/stats_summary_test.go index de4cc492ef..d4b4357e85 100644 --- a/traffic_ops/testing/api/v5/stats_summary_test.go +++ b/traffic_ops/testing/api/v5/stats_summary_test.go @@ -16,7 +16,6 @@ package v5 */ import ( - "fmt" "net/http" "net/url" "testing" @@ -90,13 +89,6 @@ func TestStatsSummary(t *testing.T) { t.Run(name, func(t *testing.T) { if name == "OK when VALID LASTSUMMARYDATE parameter" { resp, reqInf, err := testCase.ClientSession.GetSummaryStatsLastUpdated(testCase.RequestOpts) - - fmt.Println("reqInf", reqInf) - fmt.Println("resp", resp) - fmt.Println("resp.Alerts", resp.Alerts) - fmt.Println("Expected SummaryTime", resp.Response.SummaryTime) - fmt.Println("Actual SummaryTime:", latestTime) - for _, check := range testCase.Expectations { check(t, reqInf, resp.Response, resp.Alerts, err) } From d0574850c98108b30c1e1cdc8cf0a8896331c17a Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Mon, 3 Jul 2023 17:30:24 +0530 Subject: [PATCH 21/23] Updated CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e64fe13fd4..94646cd1eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,7 +67,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#7570](https://github.com/apache/trafficcontrol/pull/7570) *Traffic Ops* Fixes `deliveryservice_request_comments` v5 apis to respond with `RFC3339` date/time Format. - [#7312](https://github.com/apache/trafficcontrol/issues/7312) *Docs* Changing docs for CDN locks for DELETE response structure v4 and v5. - [#7572](https://github.com/apache/trafficcontrol/pull/7572) *Traffic Ops* Fixes Delivery Service Requests V5 apis docs with RFC3339 date/time Format -- [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. - [#7544](https://github.com/apache/trafficcontrol/issues/7544) *Traffic Ops* Fixes stats_summary v5 apis to respond with RFC3339 date/time Format. - [#7542](https://github.com/apache/trafficcontrol/pull/7542) *Traffic Ops* Fixed `CDN Locks` documentation to reflect the correct RFC3339 timestamps. - [#6340](https://github.com/apache/trafficcontrol/issues/6340) *Traffic Ops* Fixed alert messages for POST and PUT invalidation job APIs. From 9f3a6dd8410d35c5937d009d4df65ac718ecd4b5 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Mon, 3 Jul 2023 22:12:37 +0530 Subject: [PATCH 22/23] Updated GHA failing test case for testing. --- traffic_ops/testing/api/v5/stats_summary_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/traffic_ops/testing/api/v5/stats_summary_test.go b/traffic_ops/testing/api/v5/stats_summary_test.go index d4b4357e85..02cac2f98a 100644 --- a/traffic_ops/testing/api/v5/stats_summary_test.go +++ b/traffic_ops/testing/api/v5/stats_summary_test.go @@ -143,7 +143,8 @@ func validateStatsSummaryLastUpdatedField(expectedTime time.Time) utils.CkReqFun assert.RequireNotNil(t, resp, "Expected StatsSummaryLastUpdated response to not be nil.") statsSummaryLastUpdated := resp.(tc.StatsSummaryLastUpdatedV5) assert.RequireNotNil(t, statsSummaryLastUpdated.SummaryTime, "Expected SummaryTime to not be nil.") - assert.Equal(t, expectedTime, *statsSummaryLastUpdated.SummaryTime, "Expected SummaryTime to be %v, but got %v", expectedTime, *statsSummaryLastUpdated.SummaryTime) + equality := expectedTime.Equal(*statsSummaryLastUpdated.SummaryTime) + assert.Equal(t, equality, true, "Expected SummaryTime to be %v, but got %v", expectedTime, *statsSummaryLastUpdated.SummaryTime) } } From 2c7b7d4baa0adf8da2614d0fc8e97c1d9cfe6625 Mon Sep 17 00:00:00 2001 From: Jagan Parthiban Date: Mon, 3 Jul 2023 22:31:48 +0530 Subject: [PATCH 23/23] Updated GHA failing test case. --- traffic_ops/testing/api/v5/stats_summary_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/traffic_ops/testing/api/v5/stats_summary_test.go b/traffic_ops/testing/api/v5/stats_summary_test.go index 02cac2f98a..cd4a94d657 100644 --- a/traffic_ops/testing/api/v5/stats_summary_test.go +++ b/traffic_ops/testing/api/v5/stats_summary_test.go @@ -143,8 +143,8 @@ func validateStatsSummaryLastUpdatedField(expectedTime time.Time) utils.CkReqFun assert.RequireNotNil(t, resp, "Expected StatsSummaryLastUpdated response to not be nil.") statsSummaryLastUpdated := resp.(tc.StatsSummaryLastUpdatedV5) assert.RequireNotNil(t, statsSummaryLastUpdated.SummaryTime, "Expected SummaryTime to not be nil.") - equality := expectedTime.Equal(*statsSummaryLastUpdated.SummaryTime) - assert.Equal(t, equality, true, "Expected SummaryTime to be %v, but got %v", expectedTime, *statsSummaryLastUpdated.SummaryTime) + assert.Equal(t, true, expectedTime.Equal(*statsSummaryLastUpdated.SummaryTime), "Expected SummaryTime to be %v, but got %v", expectedTime, *statsSummaryLastUpdated.SummaryTime) + } }