From bdd0c7e0d7fcf6420abc32a3e655db8092e97822 Mon Sep 17 00:00:00 2001 From: Mate Herber Date: Thu, 7 Apr 2022 17:40:10 +0200 Subject: [PATCH 1/3] Add convenience method to create a tracker in steps `step_execution_id` is automatically added to all events sent via this tracker. --- analytics/mocks/Repository.go | 68 +++++++++++++++++++++++++++++++ analytics/mocks/TrackerFactory.go | 35 ++++++++++++++++ analytics/track.go | 27 ++++++++++++ analytics/track_test.go | 29 +++++++++++++ go.mod | 8 ++-- go.sum | 19 ++++++--- 6 files changed, 176 insertions(+), 10 deletions(-) create mode 100644 analytics/mocks/Repository.go create mode 100644 analytics/mocks/TrackerFactory.go create mode 100644 analytics/track.go create mode 100644 analytics/track_test.go diff --git a/analytics/mocks/Repository.go b/analytics/mocks/Repository.go new file mode 100644 index 0000000..ebe1f83 --- /dev/null +++ b/analytics/mocks/Repository.go @@ -0,0 +1,68 @@ +// Code generated by mockery v2.10.4. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// Repository is an autogenerated mock type for the Repository type +type Repository struct { + mock.Mock +} + +// Get provides a mock function with given fields: key +func (_m *Repository) Get(key string) string { + ret := _m.Called(key) + + var r0 string + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(key) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// List provides a mock function with given fields: +func (_m *Repository) List() []string { + ret := _m.Called() + + var r0 []string + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + return r0 +} + +// Set provides a mock function with given fields: key, value +func (_m *Repository) Set(key string, value string) error { + ret := _m.Called(key, value) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(key, value) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Unset provides a mock function with given fields: key +func (_m *Repository) Unset(key string) error { + ret := _m.Called(key) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(key) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/analytics/mocks/TrackerFactory.go b/analytics/mocks/TrackerFactory.go new file mode 100644 index 0000000..17ee797 --- /dev/null +++ b/analytics/mocks/TrackerFactory.go @@ -0,0 +1,35 @@ +// Code generated by mockery v2.10.4. DO NOT EDIT. + +package mocks + +import ( + analytics "github.com/bitrise-io/go-utils/v2/analytics" + mock "github.com/stretchr/testify/mock" +) + +// TrackerFactory is an autogenerated mock type for the TrackerFactory type +type TrackerFactory struct { + mock.Mock +} + +// Execute provides a mock function with given fields: _a0 +func (_m *TrackerFactory) Execute(_a0 ...analytics.Properties) analytics.Tracker { + _va := make([]interface{}, len(_a0)) + for _i := range _a0 { + _va[_i] = _a0[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 analytics.Tracker + if rf, ok := ret.Get(0).(func(...analytics.Properties) analytics.Tracker); ok { + r0 = rf(_a0...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(analytics.Tracker) + } + } + + return r0 +} diff --git a/analytics/track.go b/analytics/track.go new file mode 100644 index 0000000..6bd6f4f --- /dev/null +++ b/analytics/track.go @@ -0,0 +1,27 @@ +package analytics + +import ( + "fmt" + + "github.com/bitrise-io/go-utils/v2/analytics" + "github.com/bitrise-io/go-utils/v2/env" +) + +type TrackerFactory func(...analytics.Properties) analytics.Tracker + +const ( + StepExecutionIDEnvKey = "BITRISE_STEP_EXECUTION_ID" + StepExecutionID = "step_execution_id" +) + +func NewStepTracker(repository env.Repository, trackerFactory TrackerFactory) (analytics.Tracker, error) { + stepExecutionID := repository.Get(StepExecutionIDEnvKey) + if stepExecutionID == "" { + return nil, fmt.Errorf("no step execution ID found") + } + return trackerFactory(analytics.Properties{StepExecutionID: stepExecutionID}), nil +} + +func NewDefaultStepTracker(repository env.Repository) (analytics.Tracker, error) { + return NewStepTracker(repository, analytics.NewDefaultTracker) +} diff --git a/analytics/track_test.go b/analytics/track_test.go new file mode 100644 index 0000000..fe87560 --- /dev/null +++ b/analytics/track_test.go @@ -0,0 +1,29 @@ +package analytics + +import ( + "testing" + + "github.com/bitrise-io/go-steputils/v2/analytics/mocks" + "github.com/bitrise-io/go-utils/v2/analytics" +) + +func TestNewStepTrackerFailsIfStepExecutionIDIsNotFound(t *testing.T) { + repository := new(mocks.Repository) + repository.On("Get", "BITRISE_STEP_EXECUTION_ID").Return("") + _, err := NewDefaultStepTracker(repository) + if err == nil { + t.Error("Expected error, got nil") + } +} + +func TestNewStepTrackerAddsStepExecutionIDToNewTracker(t *testing.T) { + repository := new(mocks.Repository) + repository.On("Get", "BITRISE_STEP_EXECUTION_ID").Return("123") + factory := new(mocks.TrackerFactory) + factory.On("Execute", analytics.Properties{"step_execution_id": "123"}).Return(nil, nil) + _, err := NewStepTracker(repository, factory.Execute) + if err != nil { + t.Errorf("Expected no error, got %s", err) + } + factory.AssertExpectations(t) +} diff --git a/go.mod b/go.mod index ea7af75..8147dbc 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/bitrise-io/go-steputils/v2 go 1.16 require ( - github.com/bitrise-io/go-steputils v1.0.1 - github.com/bitrise-io/go-utils v1.0.1 - github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.1 - github.com/stretchr/testify v1.7.0 + github.com/bitrise-io/go-steputils v1.0.2 + github.com/bitrise-io/go-utils v1.0.2 + github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.6 + github.com/stretchr/testify v1.7.1 ) diff --git a/go.sum b/go.sum index b3322c4..8ccdb00 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,21 @@ -github.com/bitrise-io/go-steputils v1.0.1 h1:lwPl2W1njfANrBoTCkuqOOYbTha263ZFqoWQH0fwhaY= -github.com/bitrise-io/go-steputils v1.0.1/go.mod h1:YIUaQnIAyK4pCvQG0hYHVkSzKNT9uL2FWmkFNW4mfNI= -github.com/bitrise-io/go-utils v1.0.1 h1:e7mepVBkVN1DXRPESNXb0djEw6bxB6B93p/Q74zzcvk= +github.com/bitrise-io/go-steputils v1.0.2 h1:BEFG87r7uA/Yabk4SmuxP2yOgjjO+YGsDOYXtUH8IJ0= +github.com/bitrise-io/go-steputils v1.0.2/go.mod h1:YIUaQnIAyK4pCvQG0hYHVkSzKNT9uL2FWmkFNW4mfNI= github.com/bitrise-io/go-utils v1.0.1/go.mod h1:ZY1DI+fEpZuFpO9szgDeICM4QbqoWVt0RSY3tRI1heY= -github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.1 h1:4PBBhTUl6NthNJCTCexe/22e/crE6FTmYfcMAM/UirY= -github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.1/go.mod h1:sy+Ir1X8P3tAAx/qU/r+hqDjHDcrMjIzDEvId1wqNc4= +github.com/bitrise-io/go-utils v1.0.2 h1:w4Mz2IvrgDzrFJECuHdvsK1LHO30cdtuy9bBa7Lw2c0= +github.com/bitrise-io/go-utils v1.0.2/go.mod h1:ZY1DI+fEpZuFpO9szgDeICM4QbqoWVt0RSY3tRI1heY= +github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.6 h1:hwxfNzeqqte0iMw558Z2n42WZwwuXAuuvluo766etQc= +github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.6/go.mod h1:mysJdafur1ytXda0TeRsV+GxYCJFDU0QcCmYBgQf2Fc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -18,8 +24,9 @@ github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 1d7d51d6e38ea60bc8d3ccd70ec923bdb1b92496 Mon Sep 17 00:00:00 2001 From: Mate Herber Date: Thu, 7 Apr 2022 17:58:05 +0200 Subject: [PATCH 2/3] Fix `errcheck` errors --- analytics/track.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/analytics/track.go b/analytics/track.go index 6bd6f4f..2fea914 100644 --- a/analytics/track.go +++ b/analytics/track.go @@ -7,21 +7,24 @@ import ( "github.com/bitrise-io/go-utils/v2/env" ) +// TrackerFactory ... type TrackerFactory func(...analytics.Properties) analytics.Tracker const ( - StepExecutionIDEnvKey = "BITRISE_STEP_EXECUTION_ID" - StepExecutionID = "step_execution_id" + stepExecutionIDEnvKey = "BITRISE_STEP_EXECUTION_ID" + stepExecutionID = "step_execution_id" ) +// NewStepTracker ... func NewStepTracker(repository env.Repository, trackerFactory TrackerFactory) (analytics.Tracker, error) { - stepExecutionID := repository.Get(StepExecutionIDEnvKey) - if stepExecutionID == "" { + id := repository.Get(stepExecutionIDEnvKey) + if id == "" { return nil, fmt.Errorf("no step execution ID found") } - return trackerFactory(analytics.Properties{StepExecutionID: stepExecutionID}), nil + return trackerFactory(analytics.Properties{stepExecutionID: id}), nil } +// NewDefaultStepTracker ... func NewDefaultStepTracker(repository env.Repository) (analytics.Tracker, error) { return NewStepTracker(repository, analytics.NewDefaultTracker) } From d5da4f2de03a0c0ba18e1622b5580624c8bab697 Mon Sep 17 00:00:00 2001 From: lpusok <7979773+lpusok@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:00:21 +0100 Subject: [PATCH 3/3] Update analytics/track.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivér Falvai --- analytics/track.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analytics/track.go b/analytics/track.go index 2fea914..f16894d 100644 --- a/analytics/track.go +++ b/analytics/track.go @@ -15,7 +15,7 @@ const ( stepExecutionID = "step_execution_id" ) -// NewStepTracker ... +// NewStepTracker creates a tracker that adds the `step_execution_id` property to all events logged with this instance. This is useful for joining the logged data with other tables on the execution ID. func NewStepTracker(repository env.Repository, trackerFactory TrackerFactory) (analytics.Tracker, error) { id := repository.Get(stepExecutionIDEnvKey) if id == "" {