1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00
sap-jenkins-library/pkg/telemetry/telemetry_test.go
ffeldmann 5f4cd838cf
Updates telemetry logging information for internal reporting (#3585)
* Add StepStartTime, Renames StepDuration, adds PiperCommithash, removes Branch, GitOwner, GitRepository from logged telemetry information

* Fixes test case for telemetry logging

* Activates step monitoring data in debug mode

* Pretty debug json printing

* Reduces log noise, setting warning to debug
2022-02-28 09:45:57 +01:00

351 lines
9.1 KiB
Go

package telemetry
import (
"encoding/json"
"fmt"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/orchestrator"
"github.com/jarcoal/httpmock"
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
"net/http"
"reflect"
"regexp"
"testing"
"time"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/stretchr/testify/assert"
)
func TestTelemetry_Initialize(t *testing.T) {
type fields struct {
baseData BaseData
baseMetaData BaseMetaData
data Data
provider orchestrator.OrchestratorSpecificConfigProviding
disabled bool
client *piperhttp.Client
CustomReportingDsn string
CustomReportingToken string
customClient *piperhttp.Client
BaseURL string
Endpoint string
SiteID string
}
type args struct {
telemetryDisabled bool
stepName string
}
tests := []struct {
name string
fields fields
args args
want *piperhttp.Client
}{
{
name: "telemetry disabled",
fields: fields{},
args: args{
telemetryDisabled: true,
stepName: "test",
},
want: nil,
},
{
name: "telemetry enabled",
fields: fields{},
args: args{
telemetryDisabled: false,
stepName: "test",
},
want: &piperhttp.Client{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
telemetryClient := &Telemetry{}
telemetryClient.Initialize(tt.args.telemetryDisabled, tt.args.stepName)
// assert
assert.NotEqual(t, tt.want, telemetryClient.client)
assert.Equal(t, tt.args.stepName, telemetryClient.baseData.StepName)
})
}
}
func TestTelemetry_Send(t *testing.T) {
type fields struct {
baseData BaseData
baseMetaData BaseMetaData
data Data
provider orchestrator.OrchestratorSpecificConfigProviding
disabled bool
client *piperhttp.Client
CustomReportingDsn string
CustomReportingToken string
BaseURL string
Endpoint string
SiteID string
}
tests := []struct {
name string
fields fields
swaCalls int
}{
{
name: "Telemetry disabled, reporting disabled",
fields: fields{
disabled: true,
},
swaCalls: 0,
},
{
name: "Telemetry enabled",
fields: fields{
disabled: false,
},
swaCalls: 1,
},
{
name: "Telemetry disabled",
fields: fields{
disabled: true,
},
swaCalls: 0,
},
}
httpmock.Activate()
defer httpmock.DeactivateAndReset()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpmock.Reset()
telemetryClient := &Telemetry{disabled: tt.fields.disabled}
telemetryClient.Initialize(tt.fields.disabled, tt.name)
telemetryClient.CustomReportingDsn = tt.fields.CustomReportingDsn
if telemetryClient.client == nil {
telemetryClient.client = &piperhttp.Client{}
}
url := telemetryClient.BaseURL + telemetryClient.Endpoint
telemetryClient.client.SetOptions(piperhttp.ClientOptions{
MaxRequestDuration: 5 * time.Second,
Token: "TOKEN",
TransportSkipVerification: true,
UseDefaultTransport: true,
MaxRetries: -1,
})
if tt.fields.CustomReportingDsn != "" {
telemetryClient.customClient = &piperhttp.Client{}
telemetryClient.customClient.SetOptions(piperhttp.ClientOptions{
MaxRequestDuration: 5 * time.Second,
Token: "TOKEN",
TransportSkipVerification: true,
UseDefaultTransport: true, // Needed for mocking
MaxRetries: -1,
})
}
httpmock.RegisterResponder(http.MethodGet, url,
func(req *http.Request) (*http.Response, error) {
return httpmock.NewStringResponse(200, "Ok"), nil
},
)
httpmock.RegisterResponder(http.MethodPost, telemetryClient.CustomReportingDsn,
func(req *http.Request) (*http.Response, error) {
return httpmock.NewStringResponse(200, "Ok"), nil
},
)
// test
telemetryClient.SetData(&CustomData{})
telemetryClient.Send()
// assert
info := httpmock.GetCallCountInfo()
if got := info["GET "+url]; !assert.Equal(t, got, tt.swaCalls) {
t.Errorf("Send() = swa calls %v, wanted %v", got, tt.swaCalls)
}
})
}
defer httpmock.DeactivateAndReset()
}
func TestSetData(t *testing.T) {
type args struct {
customData *CustomData
}
tests := []struct {
name string
args args
want Data
}{
{
name: "Test",
args: args{customData: &CustomData{
Duration: "100",
ErrorCode: "0",
ErrorCategory: "Undefined",
PiperCommitHash: "abcd12345",
},
},
want: Data{
BaseData: BaseData{
URL: "",
ActionName: "",
EventType: "",
StepName: "TestCreateDataObject",
SiteID: "",
PipelineURLHash: "",
BuildURLHash: "",
Orchestrator: "Unknown",
},
BaseMetaData: BaseMetaData{
StepNameLabel: "stepName",
StageNameLabel: "stageName",
PipelineURLHashLabel: "pipelineUrlHash",
BuildURLHashLabel: "buildUrlHash",
DurationLabel: "duration",
ExitCodeLabel: "exitCode",
ErrorCategoryLabel: "errorCategory",
OrchestratorLabel: "orchestrator",
PiperCommitHashLabel: "piperCommitHash",
},
CustomData: CustomData{
Duration: "100",
ErrorCode: "0",
ErrorCategory: "Undefined",
PiperCommitHash: "abcd12345",
Custom1Label: "",
Custom2Label: "",
Custom3Label: "",
Custom4Label: "",
Custom5Label: "",
Custom1: "",
Custom2: "",
Custom3: "",
Custom4: "",
Custom5: "",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
telemetryClient := Telemetry{}
telemetryClient.Initialize(false, "TestCreateDataObject")
telemetryClient.baseData = BaseData{
URL: "",
ActionName: "",
EventType: "",
StepName: "TestCreateDataObject",
SiteID: "",
PipelineURLHash: "",
BuildURLHash: "",
Orchestrator: "Unknown",
}
telemetryClient.baseMetaData = baseMetaData
telemetryClient.SetData(tt.args.customData)
fmt.Println(telemetryClient.data)
fmt.Println(tt.want)
if !reflect.DeepEqual(telemetryClient.data, tt.want) {
t.Errorf("CreateDataObject() t.data= %v, want %v", telemetryClient.data, tt.want)
}
})
}
}
func TestTelemetry_logStepTelemetryData(t *testing.T) {
provider := &orchestrator.UnknownOrchestratorConfigProvider{}
type fields struct {
data Data
provider orchestrator.OrchestratorSpecificConfigProviding
}
tests := []struct {
name string
fields fields
fatalError logrus.Fields
logOutput string
}{
{
name: "logging with error, no fatalError set",
fields: fields{
data: Data{
BaseData: BaseData{},
BaseMetaData: BaseMetaData{},
CustomData: CustomData{
ErrorCode: "1",
Duration: "200",
PiperCommitHash: "n/a",
},
},
provider: provider,
},
},
{
name: "logging with error, fatal error set",
fields: fields{
data: Data{
BaseData: BaseData{},
BaseMetaData: BaseMetaData{},
CustomData: CustomData{
ErrorCode: "1",
Duration: "200",
PiperCommitHash: "n/a",
},
},
provider: provider,
},
fatalError: logrus.Fields{
"message": "Some error happened",
"error": "Oh snap!",
"category": "undefined",
"result": "failure",
"correlationId": "test",
"time": "0000-00-00 00:00:00.000",
},
},
{
name: "logging without error",
fields: fields{
data: Data{
CustomData: CustomData{
ErrorCode: "0",
Duration: "200",
PiperCommitHash: "n/a",
},
},
provider: provider,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, hook := test.NewNullLogger()
log.RegisterHook(hook)
telemetry := &Telemetry{
data: tt.fields.data,
provider: tt.fields.provider,
}
var re *regexp.Regexp
if tt.fatalError != nil {
errDetails, _ := json.Marshal(&tt.fatalError)
log.SetFatalErrorDetail(errDetails)
re = regexp.MustCompile(`Step telemetry data:{"StepStartTime":".*?","PipelineURLHash":"","BuildURLHash":"","StageName":"","StepName":"","ErrorCode":"\d","StepDuration":"\d+","ErrorCategory":"","CorrelationID":"n/a","PiperCommitHash":"n/a","ErrorDetail":{"category":"undefined","correlationId":"test","error":"Oh snap!","message":"Some error happened","result":"failure","time":"0000-00-00 00:00:00.000"}}`)
} else {
re = regexp.MustCompile(`Step telemetry data:{"StepStartTime":".*?","PipelineURLHash":"","BuildURLHash":"","StageName":"","StepName":"","ErrorCode":"\d","StepDuration":"\d+","ErrorCategory":"","CorrelationID":"n/a","PiperCommitHash":"n/a","ErrorDetail":null}`)
}
telemetry.logStepTelemetryData()
assert.Regexp(t, re, hook.LastEntry().Message)
hook.Reset()
})
}
}