diff --git a/.secrets.baseline b/.secrets.baseline index 82361e7..c074b09 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -101,5 +101,5 @@ } ], "results": {}, - "generated_at": "2025-03-28T15:16:31Z" + "generated_at": "2025-04-28T23:41:43Z" } diff --git a/changes/20250429002423.bugfix b/changes/20250429002423.bugfix new file mode 100644 index 0000000..3935577 --- /dev/null +++ b/changes/20250429002423.bugfix @@ -0,0 +1 @@ +:camel: Upgrade dependencies diff --git a/changes/20250429004302.feature b/changes/20250429004302.feature new file mode 100644 index 0000000..af43dd3 --- /dev/null +++ b/changes/20250429004302.feature @@ -0,0 +1 @@ +:sparkles: [api] Add a robust call method to deal with interfaces diff --git a/changes/20250429004339.bugfix b/changes/20250429004339.bugfix new file mode 100644 index 0000000..4b2c129 --- /dev/null +++ b/changes/20250429004339.bugfix @@ -0,0 +1 @@ +:recycle: Make all the calls more robust to marshaling errors diff --git a/utils/api/api.go b/utils/api/api.go index 998e28a..a650401 100644 --- a/utils/api/api.go +++ b/utils/api/api.go @@ -10,6 +10,7 @@ import ( "context" "fmt" _http "net/http" + "reflect" "strings" "github.com/ARM-software/embedded-development-services-client-utils/utils/errors" @@ -85,3 +86,34 @@ func CallAndCheckSuccess[T any](ctx context.Context, errorContext string, apiCal return } + +// GenericCallAndCheckSuccess is similar to CallAndCheckSuccess but for function returning interfaces rather than concrete types. +// T must be an interface. +// errorContext corresponds to the description of what led to the error if error there is e.g. `Failed adding a user`. +// apiCallFunc corresponds to a generic function that will be called to make the API call +func GenericCallAndCheckSuccess[T any](ctx context.Context, errorContext string, apiCallFunc func(ctx context.Context) (T, *_http.Response, error)) (result T, err error) { + if err = parallelisation.DetermineContextError(ctx); err != nil { + return + } + + result, resp, apiErr := apiCallFunc(ctx) + if resp != nil && resp.Body != nil { + _ = resp.Body.Close() + } + + if err = CheckAPICallSuccess(ctx, errorContext, resp, apiErr); err != nil { + return + } + + if reflect.ValueOf(result).Kind() != reflect.Ptr { + err = commonerrors.Newf(commonerrors.ErrConflict, "result of the call is of type [%T] and so, not a pointer as expected", result) + return + } + + if reflection.IsEmpty(result) { + err = commonerrors.New(commonerrors.ErrMarshalling, "unmarshalled response is empty") + return + } + + return +} diff --git a/utils/api/api_test.go b/utils/api/api_test.go index cf5960f..146c796 100644 --- a/utils/api/api_test.go +++ b/utils/api/api_test.go @@ -13,6 +13,7 @@ import ( _http "net/http" "testing" + "github.com/go-faker/faker/v4" "github.com/stretchr/testify/assert" "github.com/ARM-software/golang-utils/utils/commonerrors" @@ -123,3 +124,64 @@ func TestCallAndCheckSuccess(t *testing.T) { errortest.AssertError(t, err, commonerrors.ErrMarshalling) }) } + +func TestGenericCallAndCheckSuccess(t *testing.T) { + t.Run("context cancelled", func(t *testing.T) { + errMessage := "context cancelled" + parentCtx := context.Background() + ctx, cancelCtx := context.WithCancel(parentCtx) + cancelCtx() + _, actualErr := GenericCallAndCheckSuccess(ctx, errMessage, + func(ctx context.Context) (*struct{}, *_http.Response, error) { + return nil, &_http.Response{Body: io.NopCloser(bytes.NewReader(nil))}, errors.New(errMessage) + }) + errortest.AssertError(t, actualErr, commonerrors.ErrCancelled) + }) + + t.Run("api call not successful", func(t *testing.T) { + errMessage := "client error" + parentCtx := context.Background() + _, actualErr := GenericCallAndCheckSuccess(parentCtx, errMessage, + func(ctx context.Context) (*struct{}, *_http.Response, error) { + resp := _http.Response{StatusCode: 400, Body: io.NopCloser(bytes.NewReader([]byte("{\"message\": \"client error\",\"requestId\": \"761761721\"}")))} + return nil, &resp, errors.New(errMessage) + }) + expectedErr := "client error (400): API call error [request-id: 761761721] client error; client error" + assert.Equal(t, actualErr.Error(), expectedErr) + }) + + t.Run("no context error, api call successful", func(t *testing.T) { + errMessage := "no error" + parentCtx := context.Background() + _, err := GenericCallAndCheckSuccess(parentCtx, errMessage, + func(ctx context.Context) (any, *_http.Response, error) { + tmp := struct { + test string + }{ + test: faker.Word(), + } + return &tmp, &_http.Response{StatusCode: 200}, errors.New(errMessage) + }) + assert.NoError(t, err) + }) + + t.Run("api call successful, empty response", func(t *testing.T) { + errMessage := "response error" + parentCtx := context.Background() + _, err := GenericCallAndCheckSuccess(parentCtx, errMessage, + func(ctx context.Context) (*struct{}, *_http.Response, error) { + return &struct{}{}, &_http.Response{StatusCode: 200}, errors.New(errMessage) + }) + errortest.AssertError(t, err, commonerrors.ErrMarshalling) + }) + + t.Run("api call successful, incorrect response", func(t *testing.T) { + errMessage := "response error" + parentCtx := context.Background() + _, err := GenericCallAndCheckSuccess(parentCtx, errMessage, + func(ctx context.Context) (struct{}, *_http.Response, error) { + return struct{}{}, &_http.Response{StatusCode: 200}, errors.New(errMessage) + }) + errortest.AssertError(t, err, commonerrors.ErrConflict) + }) +} diff --git a/utils/artefacts/artefacts.go b/utils/artefacts/artefacts.go index fa3b76c..634afd9 100644 --- a/utils/artefacts/artefacts.go +++ b/utils/artefacts/artefacts.go @@ -16,11 +16,13 @@ import ( "github.com/ARM-software/embedded-development-services-client-utils/utils/api" paginationUtils "github.com/ARM-software/embedded-development-services-client-utils/utils/pagination" + "github.com/ARM-software/embedded-development-services-client/client" "github.com/ARM-software/golang-utils/utils/collection/pagination" "github.com/ARM-software/golang-utils/utils/commonerrors" "github.com/ARM-software/golang-utils/utils/filesystem" "github.com/ARM-software/golang-utils/utils/hashing" "github.com/ARM-software/golang-utils/utils/parallelisation" + "github.com/ARM-software/golang-utils/utils/reflection" "github.com/ARM-software/golang-utils/utils/safeio" ) @@ -39,12 +41,12 @@ type ( func determineArtefactDestination[M IManager](outputDir string, maintainTree bool, item M) (artefactFileName string, destinationDir string, err error) { if any(item) == nil { - err = fmt.Errorf("%w: missing artefact item", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("artefact item") return } artefactManagerName := item.GetName() if artefactManagerName == "" { - err = fmt.Errorf("%w: missing artefact name", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("artefact name") return } rawFileName := artefactManagerName @@ -115,13 +117,13 @@ func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactWithTree(ctx context.Co return } if m.getArtefactManagerFunc == nil || m.getArtefactContentFunc == nil { - err = fmt.Errorf("%w: function to retrieve an artefact manager was not properly defined", commonerrors.ErrUndefined) + err = commonerrors.New(commonerrors.ErrUndefined, "function to retrieve an artefact manager was not properly defined") return } err = filesystem.MkDir(outputDirectory) if err != nil { - err = fmt.Errorf("%w: failed creating the output directory [%v] for job artefact: %v", commonerrors.ErrUnexpected, outputDirectory, err.Error()) + err = commonerrors.WrapErrorf(commonerrors.ErrUnexpected, err, "failed creating the output directory [%v] for job artefact", outputDirectory) return } @@ -130,26 +132,26 @@ func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactWithTree(ctx context.Co return } if any(artefactManager) == nil { - err = fmt.Errorf("%w: missing artefact manager", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("artefact manager") return } artefactManagerName := artefactManager.GetName() if artefactManagerName == "" { - err = fmt.Errorf("%w: missing artefact name", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("artefact name") return } expectedSizePtr, ok := artefactManager.GetSizeOk() if !ok { - err = fmt.Errorf("%w: could not fetch artefact's size from artefact's manager [%v]", commonerrors.ErrUndefined, artefactManagerName) + err = commonerrors.Newf(commonerrors.ErrUndefined, "could not fetch artefact's size from artefact's manager [%v]", artefactManagerName) return } expectedSize := *expectedSizePtr expectedHashPtr, ok := artefactManager.GetHashOk() if !ok { - err = fmt.Errorf("%w: could not fetch artefact's hash from artefact's manager [%v]", commonerrors.ErrUndefined, artefactManagerName) + err = commonerrors.Newf(commonerrors.ErrUndefined, "could not fetch artefact's hash from artefact's manager [%v]", artefactManagerName) return } expectedHash := *expectedHashPtr @@ -158,61 +160,60 @@ func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactWithTree(ctx context.Co if err != nil { return } + if reflection.IsEmpty(artefactFilename) { + err = commonerrors.UndefinedVariable("artefact filename") + return + } err = filesystem.MkDir(artefactDestDir) if err != nil { - err = fmt.Errorf("%w: failed creating the output directory [%v] for job artefact: %v", commonerrors.ErrUnexpected, artefactDestDir, err.Error()) + err = commonerrors.WrapErrorf(commonerrors.ErrUnexpected, err, "failed creating the output directory [%v] for job artefact", artefactDestDir) return } - - artefact, resp, apierr := m.getArtefactContentFunc(ctx, jobName, artefactManagerName) + artefact, err := api.CallAndCheckSuccess[os.File](ctx, fmt.Sprintf("cannot fetch generated artefact [%v]", artefactFilename), func(fCtx context.Context) (*os.File, *http.Response, error) { + return m.getArtefactContentFunc(fCtx, jobName, artefactManagerName) + }) defer func() { - if resp != nil { - _ = resp.Body.Close() - } if artefact != nil { _ = artefact.Close() } }() - - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("cannot fetch generated artefact [%v]", artefactFilename), resp, apierr) if err != nil { return } - destination, err := filesystem.CreateFile(filepath.Join(artefactDestDir, artefactFilename)) if err != nil { - err = fmt.Errorf("%w: could not create a location to store generated artefact [%v]: %v", commonerrors.ErrUnexpected, artefactFilename, err.Error()) + err = commonerrors.WrapErrorf(commonerrors.ErrUnexpected, err, "could not create a location to store generated artefact [%v]", artefactFilename) return } defer func() { _ = destination.Close() }() actualSize, err := safeio.CopyDataWithContext(ctx, artefact, destination) if err != nil { - err = fmt.Errorf("%w: failed to copy artefact [%v]: %v", commonerrors.ErrUnexpected, artefactFilename, err.Error()) + err = commonerrors.WrapErrorf(commonerrors.ErrUnexpected, err, "failed to copy artefact [%v]", artefactFilename) return } if actualSize == 0 { - err = fmt.Errorf("%w: problem with artefact [%v]", commonerrors.ErrEmpty, artefactFilename) + err = commonerrors.Newf(commonerrors.ErrEmpty, "problem with artefact [%v]", artefactFilename) return } if actualSize != expectedSize { - err = fmt.Errorf("%w: artefact [%v] size '%v' does not match expected '%v'", commonerrors.ErrCondition, artefactFilename, actualSize, expectedSize) + err = commonerrors.Newf(commonerrors.ErrCondition, "artefact [%v] size '%v' does not match expected '%v'", artefactFilename, actualSize, expectedSize) return } // reset offset for hashing entire contents _, err = destination.Seek(0, 0) if err != nil { - err = fmt.Errorf("%w: could not reset destination file: %v", commonerrors.ErrUnexpected, err.Error()) + err = commonerrors.WrapError(commonerrors.ErrUnexpected, err, "could not reset destination file") return } actualHash, err := fileHasher.CalculateWithContext(ctx, destination) if err != nil { - err = fmt.Errorf("%w: could not calculate hash of destination file: %v", commonerrors.ErrUnexpected, err.Error()) + err = commonerrors.WrapError(commonerrors.ErrUnexpected, err, "could not calculate hash of destination file") } if actualHash != expectedHash { - err = fmt.Errorf("%w: artefact [%v] hash '%v' does not match expected '%v'", commonerrors.ErrCondition, artefactFilename, actualHash, expectedHash) + err = commonerrors.Newf(commonerrors.ErrCondition, "artefact [%v] hash '%v' does not match expected '%v'", artefactFilename, actualHash, expectedHash) return } @@ -230,27 +231,24 @@ func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactFromLinkWithTree(ctx co return } if m.getArtefactManagerFunc == nil || m.getArtefactContentFunc == nil { - err = fmt.Errorf("%w: function to retrieve an artefact manager was not properly defined", commonerrors.ErrUndefined) + err = commonerrors.New(commonerrors.ErrUndefined, "function to retrieve an artefact manager was not properly defined") return } if any(artefactManagerItemLink) == nil { - err = fmt.Errorf("%w: missing artefact link", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("artefact link") return } artefactManagerName := artefactManagerItemLink.GetName() - artefactManager, resp, apierr := m.getArtefactManagerFunc(ctx, jobName, artefactManagerName) - defer func() { - if resp != nil { - _ = resp.Body.Close() - } - }() - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("cannot fetch artefact's manager [%+v]", artefactManager), resp, apierr) - if err != nil { + if reflection.IsEmpty(artefactManagerName) { + err = commonerrors.UndefinedVariable("artefact name") return } - if resp != nil { - _ = resp.Body.Close() + artefactManager, err := api.GenericCallAndCheckSuccess[M](ctx, fmt.Sprintf("cannot fetch artefact's manager [%v]", artefactManagerName), func(fCtx context.Context) (M, *http.Response, error) { + return m.getArtefactManagerFunc(fCtx, jobName, artefactManagerName) + }) + if err != nil { + return } err = m.DownloadJobArtefactWithTree(ctx, jobName, maintainTreeLocation, outputDirectory, artefactManager) return @@ -268,14 +266,16 @@ func (m *ArtefactManager[M, D, L, C]) ListJobArtefacts(ctx context.Context, jobN func (m *ArtefactManager[M, D, L, C]) fetchJobArtefactsFirstPage(ctx context.Context, jobName string) (page pagination.IStaticPage, err error) { if m.getArtefactManagersFirstPageFunc == nil { - err = fmt.Errorf("%w: function to retrieve artefact managers was not properly defined", commonerrors.ErrUndefined) + err = commonerrors.New(commonerrors.ErrUndefined, "function to retrieve artefact managers was not properly defined") return } - clientPage, resp, apierr := m.getArtefactManagersFirstPageFunc(ctx, jobName) - if resp != nil { - _ = resp.Body.Close() + if reflection.IsEmpty(jobName) { + err = commonerrors.UndefinedVariable("job identifier") + return } - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("could not list artefact managers for job [%v]", jobName), resp, apierr) + clientPage, err := api.GenericCallAndCheckSuccess[client.IStaticPage](ctx, fmt.Sprintf("could not list artefact managers for job [%v]", jobName), func(fCtx context.Context) (client.IStaticPage, *http.Response, error) { + return m.getArtefactManagersFirstPageFunc(fCtx, jobName) + }) if err == nil { page = paginationUtils.ToPage(clientPage) } @@ -291,34 +291,36 @@ func (m *ArtefactManager[M, D, L, C]) fetchJobArtefactsNextPage(ctx context.Cont return } if m.getArtefactManagersFollowLinkFunc == nil { - err = fmt.Errorf("%w: function to retrieve artefact managers was not properly defined", commonerrors.ErrUndefined) + err = commonerrors.New(commonerrors.ErrUndefined, "function to retrieve artefact managers was not properly defined") return } unwrappedPage := paginationUtils.UnwrapPage(currentPage) if unwrappedPage == nil { - err = fmt.Errorf("%w: returned artefact managers page is empty", commonerrors.ErrUnexpected) + err = commonerrors.New(commonerrors.ErrUnexpected, "returned artefact managers page is empty") return } page, ok := unwrappedPage.(C) if !ok { - err = fmt.Errorf("%w: returned artefact managers page[%T] is not of the expected type [%v]", commonerrors.ErrUnexpected, currentPage, "*ArtefactManagerCollection") + err = commonerrors.Newf(commonerrors.ErrUnexpected, " returned artefact managers page[%T] is not of the expected type [%v]", currentPage, "*ArtefactManagerCollection") return } links, has := page.GetLinksOk() if !has { - err = fmt.Errorf("%w: returned page of artefact managers has no links", commonerrors.ErrUnexpected) + err = commonerrors.New(commonerrors.ErrUnexpected, "returned page of artefact managers has no links") return } if !links.HasNext() { - err = fmt.Errorf("%w: returned page of artefact managers has no `next` link", commonerrors.ErrUnexpected) + err = commonerrors.New(commonerrors.ErrUnexpected, "returned page of artefact managers has no `next` link") return } link := links.GetNextP() - clientPage, resp, apierr := m.getArtefactManagersFollowLinkFunc(ctx, link) - if resp != nil { - _ = resp.Body.Close() + if reflection.IsEmpty(link) { + err = commonerrors.UndefinedVariable("`next` link") + return } - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("could not follow `next` link [%v]", link), resp, apierr) + clientPage, err := api.GenericCallAndCheckSuccess[client.IStaticPage](ctx, fmt.Sprintf("could not follow `next` link [%v]", link), func(fCtx context.Context) (client.IStaticPage, *http.Response, error) { + return m.getArtefactManagersFollowLinkFunc(fCtx, link) + }) if err == nil { nextPage = paginationUtils.ToPage(clientPage) } @@ -336,7 +338,7 @@ func (m *ArtefactManager[M, D, L, C]) DownloadAllJobArtefactsWithTree(ctx contex } err = filesystem.MkDir(outputDirectory) if err != nil { - err = fmt.Errorf("%w: failed creating the output directory [%v] for job artefacts: %v", commonerrors.ErrUnexpected, outputDirectory, err.Error()) + err = commonerrors.WrapErrorf(commonerrors.ErrUnexpected, err, "failed creating the output directory [%v] for job artefacts", outputDirectory) return } paginator, err := m.ListJobArtefacts(ctx, jobName) @@ -351,7 +353,7 @@ func (m *ArtefactManager[M, D, L, C]) DownloadAllJobArtefactsWithTree(ctx contex } item, subErr := paginator.GetNext() if subErr != nil { - err = fmt.Errorf("%w: failed getting information about job artefacts: %v", commonerrors.ErrUnexpected, subErr.Error()) + err = commonerrors.WrapError(commonerrors.ErrUnexpected, subErr, "failed getting information about job artefacts") return } artefactLink, ok := item.(D) @@ -371,7 +373,7 @@ func (m *ArtefactManager[M, D, L, C]) DownloadAllJobArtefactsWithTree(ctx contex return } } else { - err = fmt.Errorf("%w: the type of the response from service cannot be interpreted", commonerrors.ErrMarshalling) + err = commonerrors.New(commonerrors.ErrMarshalling, "the type of the response from service cannot be interpreted") return } diff --git a/utils/artefacts/interface.go b/utils/artefacts/interface.go index 1618128..0ca6d57 100644 --- a/utils/artefacts/interface.go +++ b/utils/artefacts/interface.go @@ -11,7 +11,7 @@ import ( "github.com/ARM-software/golang-utils/utils/collection/pagination" ) -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IArtefactManager +//go:generate go tool mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IArtefactManager type IArtefactManager[ M IManager, diff --git a/utils/cache/interfaces.go b/utils/cache/interfaces.go index 22622f3..bebebe2 100644 --- a/utils/cache/interfaces.go +++ b/utils/cache/interfaces.go @@ -10,7 +10,7 @@ import "context" // Mocks are generated using `go generate ./...` // Add interfaces to the following command for a mock to be generated -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IServerCache +//go:generate go tool mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IServerCache type Control int diff --git a/utils/go.mod b/utils/go.mod index 0a47803..ca60513 100644 --- a/utils/go.mod +++ b/utils/go.mod @@ -3,14 +3,14 @@ module github.com/ARM-software/embedded-development-services-client-utils/utils go 1.24 require ( - github.com/ARM-software/embedded-development-services-client/client v1.53.1 - github.com/ARM-software/golang-utils/utils v1.91.0 + github.com/ARM-software/embedded-development-services-client/client v1.54.0 + github.com/ARM-software/golang-utils/utils v1.93.0 github.com/go-faker/faker/v4 v4.6.0 github.com/go-logr/logr v1.4.2 github.com/stretchr/testify v1.10.0 go.uber.org/atomic v1.11.0 go.uber.org/goleak v1.3.0 - go.uber.org/mock v0.5.0 + go.uber.org/mock v0.5.2 golang.org/x/sync v0.13.0 ) @@ -74,9 +74,13 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.37.0 // indirect golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect + golang.org/x/mod v0.24.0 // indirect golang.org/x/oauth2 v0.29.0 // indirect golang.org/x/sys v0.32.0 // indirect golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.30.0 // indirect gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +tool go.uber.org/mock/mockgen diff --git a/utils/go.sum b/utils/go.sum index ab3ab85..37d0d56 100644 --- a/utils/go.sum +++ b/utils/go.sum @@ -1,8 +1,8 @@ bitbucket.org/creachadair/stringset v0.0.9/go.mod h1:t+4WcQ4+PXTa8aQdNKe40ZP6iwesoMFWAxPGd3UGjyY= -github.com/ARM-software/embedded-development-services-client/client v1.53.1 h1:sGOCSgrwW/dwPpyFPOfmNhARqgOVhICoXAHZWGJ8odI= -github.com/ARM-software/embedded-development-services-client/client v1.53.1/go.mod h1:QZ0J+RQvfuD7JfEa2pZyIF+6GnivLLso9uh7HaNuXlc= -github.com/ARM-software/golang-utils/utils v1.91.0 h1:aVIeyPLPX4kEJEkse1JA4F2eXUO6n91WPJOYup2kZcQ= -github.com/ARM-software/golang-utils/utils v1.91.0/go.mod h1:plsOQHwkMemjNf874kEBJyWXtVldm9KNZHQ2M/i03pQ= +github.com/ARM-software/embedded-development-services-client/client v1.54.0 h1:1AfJ/eqVRcnNkxkRJmjTOJkAYc6xfxkJAmxjpxWpijw= +github.com/ARM-software/embedded-development-services-client/client v1.54.0/go.mod h1:g7uy8LXhEVH6aaQM7Ameb5zMsWlDYQqKtJGPpa7sCQg= +github.com/ARM-software/golang-utils/utils v1.93.0 h1:lrfhT8lFlNcR60gwIntGUcBXdSX2dUN/SR2MmJdvF6o= +github.com/ARM-software/golang-utils/utils v1.93.0/go.mod h1:bBeEZK/kqT2EP2Q8Z1FZk5a2QkaBxhdPQNA5VKTEFOY= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -200,8 +200,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= @@ -212,6 +212,8 @@ golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -258,6 +260,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/utils/job/interfaces.go b/utils/job/interfaces.go index 2658ff6..eeadf62 100644 --- a/utils/job/interfaces.go +++ b/utils/job/interfaces.go @@ -17,7 +17,7 @@ import ( // Mocks are generated using `go generate ./...` // Add interfaces to the following command for a mock to be generated -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IAsynchronousJob,IJobManager +//go:generate go tool mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IAsynchronousJob,IJobManager // IAsynchronousJob defines a typical asynchronous job. type IAsynchronousJob interface { diff --git a/utils/job/manager.go b/utils/job/manager.go index 084b063..53aed70 100644 --- a/utils/job/manager.go +++ b/utils/job/manager.go @@ -20,6 +20,7 @@ import ( "github.com/ARM-software/golang-utils/utils/commonerrors" "github.com/ARM-software/golang-utils/utils/logs" "github.com/ARM-software/golang-utils/utils/parallelisation" + "github.com/ARM-software/golang-utils/utils/reflection" "github.com/ARM-software/golang-utils/utils/retry" ) @@ -37,22 +38,20 @@ func (m *Manager) FetchJobMessagesFirstPage(ctx context.Context, job IAsynchrono return } if job == nil { - err = fmt.Errorf("%w: missing job", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("job") return } jobName, err := job.FetchName() if err != nil { return } - jobType := job.FetchType() - page, resp, apierr := m.fetchJobFirstMessagePageFunc(ctx, jobName) - if resp != nil { - _ = resp.Body.Close() - } - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("could not fetch %v [%v]'s messages first page", jobType, jobName), resp, apierr) - if err != nil { + if reflection.IsEmpty(jobName) { + err = commonerrors.UndefinedVariable("job identifier") return } + page, err = api.GenericCallAndCheckSuccess[pagination.IStaticPageStream](ctx, fmt.Sprintf("could not fetch %v [%v]'s messages first page", job.FetchType(), jobName), func(fCtx context.Context) (pagination.IStaticPageStream, *http.Response, error) { + return m.fetchJobFirstMessagePageFunc(fCtx, jobName) + }) return } @@ -71,7 +70,11 @@ func waitForJobState(ctx context.Context, logger logs.Loggers, job IAsynchronous if err != nil { return } - notStartedError := fmt.Errorf("%w: job [%v] has not reached the expected state [%v]", commonerrors.ErrCondition, jobName, jobState) + if reflection.IsEmpty(jobName) { + err = commonerrors.UndefinedVariable("job identifier") + return + } + notStartedError := commonerrors.Newf(commonerrors.ErrCondition, "job [%v] has not reached the expected state [%v]", jobName, jobState) err = retry.RetryOnError(subCtx, logs.NewPlainLogrLoggerFromLoggers(logger), retryCfg, func() error { inState, subErr := checkStateFunc(subCtx, job) if subErr != nil { @@ -230,7 +233,7 @@ func (m *Manager) areThereMessages(ctx context.Context, job IAsynchronousJob) (h return } if job == nil { - err = fmt.Errorf("%w: missing job", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("job") return } if job.HasMessages() { @@ -242,12 +245,14 @@ func (m *Manager) areThereMessages(ctx context.Context, job IAsynchronousJob) (h if err != nil { return } - jobType := job.FetchType() - jobStatus, resp, apierr := m.fetchJobStatusFunc(ctx, jobName) - if resp != nil { - _ = resp.Body.Close() + if reflection.IsEmpty(jobName) { + err = commonerrors.UndefinedVariable("job identifier") + return } - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("could not fetch %v [%v]'s status", jobType, jobName), resp, apierr) + jobType := job.FetchType() + jobStatus, err := api.GenericCallAndCheckSuccess[IAsynchronousJob](ctx, fmt.Sprintf("could not fetch %v [%v]'s status", jobType, jobName), func(fCtx context.Context) (IAsynchronousJob, *http.Response, error) { + return m.fetchJobStatusFunc(fCtx, jobName) + }) if err != nil { return } @@ -261,7 +266,7 @@ func (m *Manager) HasJobStarted(ctx context.Context, job IAsynchronousJob) (star return } if job == nil { - err = fmt.Errorf("%w: missing job", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("job") return } if job.GetDone() { @@ -277,12 +282,13 @@ func (m *Manager) HasJobStarted(ctx context.Context, job IAsynchronousJob) (star if err != nil { return } - jobType := job.FetchType() - jobStatus, resp, apierr := m.fetchJobStatusFunc(ctx, jobName) - if resp != nil { - _ = resp.Body.Close() + if reflection.IsEmpty(jobName) { + err = commonerrors.UndefinedVariable("job identifier") + return } - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("could not fetch %v [%v]'s status", jobType, jobName), resp, apierr) + jobStatus, err := api.GenericCallAndCheckSuccess[IAsynchronousJob](ctx, fmt.Sprintf("could not fetch %v [%v]'s status", job.FetchType(), jobName), func(fCtx context.Context) (IAsynchronousJob, *http.Response, error) { + return m.fetchJobStatusFunc(fCtx, jobName) + }) if err != nil { return } @@ -300,19 +306,21 @@ func (m *Manager) HasJobCompleted(ctx context.Context, job IAsynchronousJob) (co return } if job == nil { - err = fmt.Errorf("%w: missing job", commonerrors.ErrUndefined) + err = commonerrors.UndefinedVariable("job") return } jobName, err := job.FetchName() if err != nil { return } - jobType := job.FetchType() - jobStatus, resp, apierr := m.fetchJobStatusFunc(ctx, jobName) - if resp != nil { - _ = resp.Body.Close() + if reflection.IsEmpty(jobName) { + err = commonerrors.UndefinedVariable("job identifier") + return } - err = api.CheckAPICallSuccess(ctx, fmt.Sprintf("could not fetch %v [%v]'s status", jobType, jobName), resp, apierr) + jobType := job.FetchType() + jobStatus, err := api.GenericCallAndCheckSuccess[IAsynchronousJob](ctx, fmt.Sprintf("could not fetch %v [%v]'s status", jobType, jobName), func(fCtx context.Context) (IAsynchronousJob, *http.Response, error) { + return m.fetchJobStatusFunc(fCtx, jobName) + }) if err != nil { return } @@ -320,18 +328,18 @@ func (m *Manager) HasJobCompleted(ctx context.Context, job IAsynchronousJob) (co completed = true } if jobStatus.GetError() { - err = fmt.Errorf("%w: %v [%v] errored: %v", commonerrors.ErrUnexpected, jobType, jobName, jobStatus.GetStatus()) + err = commonerrors.Newf(commonerrors.ErrUnexpected, "%v [%v] errored: %v", jobType, jobName, jobStatus.GetStatus()) return } if jobStatus.GetFailure() { - err = fmt.Errorf("%w: %v [%v] failed: %v", commonerrors.ErrInvalid, jobType, jobName, jobStatus.GetStatus()) + err = commonerrors.Newf(commonerrors.ErrInvalid, "%v [%v] failed: %v", jobType, jobName, jobStatus.GetStatus()) return } if jobStatus.GetSuccess() { return } if completed { - err = fmt.Errorf("%w: %v [%v] completed but without success: %v", commonerrors.ErrUnexpected, jobType, jobName, jobStatus.GetStatus()) + err = commonerrors.Newf(commonerrors.ErrUnexpected, "%v [%v] completed but without success: %v", jobType, jobName, jobStatus.GetStatus()) return } return @@ -354,7 +362,7 @@ func newJobManagerFromMessageFactory(logger *messages.MessageLoggerFactory, back return nil, commonerrors.ErrNoLogger } if messagePaginator == nil { - return nil, fmt.Errorf("%w: missing paginator factory", commonerrors.ErrUndefined) + return nil, commonerrors.UndefinedVariable("paginator factory") } return &Manager{ messageLoggerFactory: *logger, diff --git a/utils/messages/format_test.go b/utils/messages/format_test.go index 1f8a9cb..8640f4c 100644 --- a/utils/messages/format_test.go +++ b/utils/messages/format_test.go @@ -15,12 +15,13 @@ import ( "github.com/ARM-software/embedded-development-services-client/client" "github.com/ARM-software/golang-utils/utils/commonerrors" + "github.com/ARM-software/golang-utils/utils/commonerrors/errortest" ) func TestFormatMessage(t *testing.T) { message, err := FormatMessage(nil) require.Error(t, err) - assert.True(t, commonerrors.Any(err, commonerrors.ErrUndefined)) + errortest.AssertError(t, err, commonerrors.ErrUndefined) assert.Empty(t, message) message, err = FormatMessage(client.NewMessageObject(faker.Sentence())) require.NoError(t, err) diff --git a/utils/messages/interfaces.go b/utils/messages/interfaces.go index a081f83..de7ecc4 100644 --- a/utils/messages/interfaces.go +++ b/utils/messages/interfaces.go @@ -16,7 +16,7 @@ import ( // Mocks are generated using `go generate ./...` // Add interfaces to the following command for a mock to be generated -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IMessage,IMessageLogger +//go:generate go tool mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IMessage,IMessageLogger const ( // DefaultMessagesPrintingFrequency describes the default frequency at which messages are printed diff --git a/utils/messages/logger_test.go b/utils/messages/logger_test.go index ddaf25a..a2f6ccf 100644 --- a/utils/messages/logger_test.go +++ b/utils/messages/logger_test.go @@ -11,13 +11,13 @@ import ( "time" "github.com/go-faker/faker/v4" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/goleak" "github.com/ARM-software/embedded-development-services-client-utils/utils/logging" "github.com/ARM-software/embedded-development-services-client/client" "github.com/ARM-software/golang-utils/utils/commonerrors" + "github.com/ARM-software/golang-utils/utils/commonerrors/errortest" "github.com/ARM-software/golang-utils/utils/field" ) @@ -118,7 +118,7 @@ func TestLogMessageCollectionCancel(t *testing.T) { cancel() err = logger.LogMessagesCollection(gtx, messages) require.Error(t, err) - assert.True(t, commonerrors.Any(err, commonerrors.ErrCancelled)) + errortest.AssertError(t, err, commonerrors.ErrCancelled) require.NoError(t, logger.Close()) }) } diff --git a/utils/mocks/mock_artefacts.go b/utils/mocks/mock_artefacts.go index 8ed0294..dc60823 100644 --- a/utils/mocks/mock_artefacts.go +++ b/utils/mocks/mock_artefacts.go @@ -18,37 +18,37 @@ import ( context "context" reflect "reflect" - client "github.com/ARM-software/embedded-development-services-client/client" + artefacts "github.com/ARM-software/embedded-development-services-client-utils/utils/artefacts" pagination "github.com/ARM-software/golang-utils/utils/collection/pagination" gomock "go.uber.org/mock/gomock" ) // MockIArtefactManager is a mock of IArtefactManager interface. -type MockIArtefactManager struct { +type MockIArtefactManager[M artefacts.IManager, D artefacts.ILinkData] struct { ctrl *gomock.Controller - recorder *MockIArtefactManagerMockRecorder + recorder *MockIArtefactManagerMockRecorder[M, D] isgomock struct{} } // MockIArtefactManagerMockRecorder is the mock recorder for MockIArtefactManager. -type MockIArtefactManagerMockRecorder struct { - mock *MockIArtefactManager +type MockIArtefactManagerMockRecorder[M artefacts.IManager, D artefacts.ILinkData] struct { + mock *MockIArtefactManager[M, D] } // NewMockIArtefactManager creates a new mock instance. -func NewMockIArtefactManager(ctrl *gomock.Controller) *MockIArtefactManager { - mock := &MockIArtefactManager{ctrl: ctrl} - mock.recorder = &MockIArtefactManagerMockRecorder{mock} +func NewMockIArtefactManager[M artefacts.IManager, D artefacts.ILinkData](ctrl *gomock.Controller) *MockIArtefactManager[M, D] { + mock := &MockIArtefactManager[M, D]{ctrl: ctrl} + mock.recorder = &MockIArtefactManagerMockRecorder[M, D]{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockIArtefactManager) EXPECT() *MockIArtefactManagerMockRecorder { +func (m *MockIArtefactManager[M, D]) EXPECT() *MockIArtefactManagerMockRecorder[M, D] { return m.recorder } // DownloadAllJobArtefacts mocks base method. -func (m *MockIArtefactManager) DownloadAllJobArtefacts(ctx context.Context, jobName, outputDirectory string) error { +func (m *MockIArtefactManager[M, D]) DownloadAllJobArtefacts(ctx context.Context, jobName, outputDirectory string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadAllJobArtefacts", ctx, jobName, outputDirectory) ret0, _ := ret[0].(error) @@ -56,13 +56,13 @@ func (m *MockIArtefactManager) DownloadAllJobArtefacts(ctx context.Context, jobN } // DownloadAllJobArtefacts indicates an expected call of DownloadAllJobArtefacts. -func (mr *MockIArtefactManagerMockRecorder) DownloadAllJobArtefacts(ctx, jobName, outputDirectory any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) DownloadAllJobArtefacts(ctx, jobName, outputDirectory any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadAllJobArtefacts", reflect.TypeOf((*MockIArtefactManager)(nil).DownloadAllJobArtefacts), ctx, jobName, outputDirectory) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadAllJobArtefacts", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).DownloadAllJobArtefacts), ctx, jobName, outputDirectory) } // DownloadAllJobArtefactsWithTree mocks base method. -func (m *MockIArtefactManager) DownloadAllJobArtefactsWithTree(ctx context.Context, jobName string, maintainTreeStructure bool, outputDirectory string) error { +func (m *MockIArtefactManager[M, D]) DownloadAllJobArtefactsWithTree(ctx context.Context, jobName string, maintainTreeStructure bool, outputDirectory string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadAllJobArtefactsWithTree", ctx, jobName, maintainTreeStructure, outputDirectory) ret0, _ := ret[0].(error) @@ -70,13 +70,13 @@ func (m *MockIArtefactManager) DownloadAllJobArtefactsWithTree(ctx context.Conte } // DownloadAllJobArtefactsWithTree indicates an expected call of DownloadAllJobArtefactsWithTree. -func (mr *MockIArtefactManagerMockRecorder) DownloadAllJobArtefactsWithTree(ctx, jobName, maintainTreeStructure, outputDirectory any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) DownloadAllJobArtefactsWithTree(ctx, jobName, maintainTreeStructure, outputDirectory any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadAllJobArtefactsWithTree", reflect.TypeOf((*MockIArtefactManager)(nil).DownloadAllJobArtefactsWithTree), ctx, jobName, maintainTreeStructure, outputDirectory) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadAllJobArtefactsWithTree", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).DownloadAllJobArtefactsWithTree), ctx, jobName, maintainTreeStructure, outputDirectory) } // DownloadJobArtefact mocks base method. -func (m *MockIArtefactManager) DownloadJobArtefact(ctx context.Context, jobName, outputDirectory string, artefactManager *client.ArtefactManagerItem) error { +func (m *MockIArtefactManager[M, D]) DownloadJobArtefact(ctx context.Context, jobName, outputDirectory string, artefactManager M) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadJobArtefact", ctx, jobName, outputDirectory, artefactManager) ret0, _ := ret[0].(error) @@ -84,13 +84,13 @@ func (m *MockIArtefactManager) DownloadJobArtefact(ctx context.Context, jobName, } // DownloadJobArtefact indicates an expected call of DownloadJobArtefact. -func (mr *MockIArtefactManagerMockRecorder) DownloadJobArtefact(ctx, jobName, outputDirectory, artefactManager any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) DownloadJobArtefact(ctx, jobName, outputDirectory, artefactManager any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefact", reflect.TypeOf((*MockIArtefactManager)(nil).DownloadJobArtefact), ctx, jobName, outputDirectory, artefactManager) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefact", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).DownloadJobArtefact), ctx, jobName, outputDirectory, artefactManager) } // DownloadJobArtefactFromLink mocks base method. -func (m *MockIArtefactManager) DownloadJobArtefactFromLink(ctx context.Context, jobName, outputDirectory string, artefactManagerItemLink *client.HalLinkData) error { +func (m *MockIArtefactManager[M, D]) DownloadJobArtefactFromLink(ctx context.Context, jobName, outputDirectory string, artefactManagerItemLink D) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadJobArtefactFromLink", ctx, jobName, outputDirectory, artefactManagerItemLink) ret0, _ := ret[0].(error) @@ -98,13 +98,13 @@ func (m *MockIArtefactManager) DownloadJobArtefactFromLink(ctx context.Context, } // DownloadJobArtefactFromLink indicates an expected call of DownloadJobArtefactFromLink. -func (mr *MockIArtefactManagerMockRecorder) DownloadJobArtefactFromLink(ctx, jobName, outputDirectory, artefactManagerItemLink any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) DownloadJobArtefactFromLink(ctx, jobName, outputDirectory, artefactManagerItemLink any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefactFromLink", reflect.TypeOf((*MockIArtefactManager)(nil).DownloadJobArtefactFromLink), ctx, jobName, outputDirectory, artefactManagerItemLink) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefactFromLink", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).DownloadJobArtefactFromLink), ctx, jobName, outputDirectory, artefactManagerItemLink) } // DownloadJobArtefactFromLinkWithTree mocks base method. -func (m *MockIArtefactManager) DownloadJobArtefactFromLinkWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManagerItemLink *client.HalLinkData) error { +func (m *MockIArtefactManager[M, D]) DownloadJobArtefactFromLinkWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManagerItemLink D) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadJobArtefactFromLinkWithTree", ctx, jobName, maintainTreeLocation, outputDirectory, artefactManagerItemLink) ret0, _ := ret[0].(error) @@ -112,13 +112,13 @@ func (m *MockIArtefactManager) DownloadJobArtefactFromLinkWithTree(ctx context.C } // DownloadJobArtefactFromLinkWithTree indicates an expected call of DownloadJobArtefactFromLinkWithTree. -func (mr *MockIArtefactManagerMockRecorder) DownloadJobArtefactFromLinkWithTree(ctx, jobName, maintainTreeLocation, outputDirectory, artefactManagerItemLink any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) DownloadJobArtefactFromLinkWithTree(ctx, jobName, maintainTreeLocation, outputDirectory, artefactManagerItemLink any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefactFromLinkWithTree", reflect.TypeOf((*MockIArtefactManager)(nil).DownloadJobArtefactFromLinkWithTree), ctx, jobName, maintainTreeLocation, outputDirectory, artefactManagerItemLink) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefactFromLinkWithTree", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).DownloadJobArtefactFromLinkWithTree), ctx, jobName, maintainTreeLocation, outputDirectory, artefactManagerItemLink) } // DownloadJobArtefactWithTree mocks base method. -func (m *MockIArtefactManager) DownloadJobArtefactWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManager *client.ArtefactManagerItem) error { +func (m *MockIArtefactManager[M, D]) DownloadJobArtefactWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManager M) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DownloadJobArtefactWithTree", ctx, jobName, maintainTreeLocation, outputDirectory, artefactManager) ret0, _ := ret[0].(error) @@ -126,13 +126,13 @@ func (m *MockIArtefactManager) DownloadJobArtefactWithTree(ctx context.Context, } // DownloadJobArtefactWithTree indicates an expected call of DownloadJobArtefactWithTree. -func (mr *MockIArtefactManagerMockRecorder) DownloadJobArtefactWithTree(ctx, jobName, maintainTreeLocation, outputDirectory, artefactManager any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) DownloadJobArtefactWithTree(ctx, jobName, maintainTreeLocation, outputDirectory, artefactManager any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefactWithTree", reflect.TypeOf((*MockIArtefactManager)(nil).DownloadJobArtefactWithTree), ctx, jobName, maintainTreeLocation, outputDirectory, artefactManager) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadJobArtefactWithTree", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).DownloadJobArtefactWithTree), ctx, jobName, maintainTreeLocation, outputDirectory, artefactManager) } // ListJobArtefacts mocks base method. -func (m *MockIArtefactManager) ListJobArtefacts(ctx context.Context, jobName string) (pagination.IPaginatorAndPageFetcher, error) { +func (m *MockIArtefactManager[M, D]) ListJobArtefacts(ctx context.Context, jobName string) (pagination.IPaginatorAndPageFetcher, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListJobArtefacts", ctx, jobName) ret0, _ := ret[0].(pagination.IPaginatorAndPageFetcher) @@ -141,7 +141,7 @@ func (m *MockIArtefactManager) ListJobArtefacts(ctx context.Context, jobName str } // ListJobArtefacts indicates an expected call of ListJobArtefacts. -func (mr *MockIArtefactManagerMockRecorder) ListJobArtefacts(ctx, jobName any) *gomock.Call { +func (mr *MockIArtefactManagerMockRecorder[M, D]) ListJobArtefacts(ctx, jobName any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListJobArtefacts", reflect.TypeOf((*MockIArtefactManager)(nil).ListJobArtefacts), ctx, jobName) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListJobArtefacts", reflect.TypeOf((*MockIArtefactManager[M, D])(nil).ListJobArtefacts), ctx, jobName) } diff --git a/utils/mocks/mock_job.go b/utils/mocks/mock_job.go index b5f2112..52b1815 100644 --- a/utils/mocks/mock_job.go +++ b/utils/mocks/mock_job.go @@ -245,88 +245,88 @@ func (m *MockIJobManager) EXPECT() *MockIJobManagerMockRecorder { } // GetMessagePaginator mocks base method. -func (m *MockIJobManager) GetMessagePaginator(ctx context.Context, logger logs.Loggers, job job.IAsynchronousJob, setupTimeout time.Duration) (pagination.IStreamPaginatorAndPageFetcher, error) { +func (m *MockIJobManager) GetMessagePaginator(ctx context.Context, logger logs.Loggers, arg2 job.IAsynchronousJob, setupTimeout time.Duration) (pagination.IStreamPaginatorAndPageFetcher, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMessagePaginator", ctx, logger, job, setupTimeout) + ret := m.ctrl.Call(m, "GetMessagePaginator", ctx, logger, arg2, setupTimeout) ret0, _ := ret[0].(pagination.IStreamPaginatorAndPageFetcher) ret1, _ := ret[1].(error) return ret0, ret1 } // GetMessagePaginator indicates an expected call of GetMessagePaginator. -func (mr *MockIJobManagerMockRecorder) GetMessagePaginator(ctx, logger, job, setupTimeout any) *gomock.Call { +func (mr *MockIJobManagerMockRecorder) GetMessagePaginator(ctx, logger, arg2, setupTimeout any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessagePaginator", reflect.TypeOf((*MockIJobManager)(nil).GetMessagePaginator), ctx, logger, job, setupTimeout) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessagePaginator", reflect.TypeOf((*MockIJobManager)(nil).GetMessagePaginator), ctx, logger, arg2, setupTimeout) } // HasJobCompleted mocks base method. -func (m *MockIJobManager) HasJobCompleted(ctx context.Context, job job.IAsynchronousJob) (bool, error) { +func (m *MockIJobManager) HasJobCompleted(ctx context.Context, arg1 job.IAsynchronousJob) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HasJobCompleted", ctx, job) + ret := m.ctrl.Call(m, "HasJobCompleted", ctx, arg1) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } // HasJobCompleted indicates an expected call of HasJobCompleted. -func (mr *MockIJobManagerMockRecorder) HasJobCompleted(ctx, job any) *gomock.Call { +func (mr *MockIJobManagerMockRecorder) HasJobCompleted(ctx, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasJobCompleted", reflect.TypeOf((*MockIJobManager)(nil).HasJobCompleted), ctx, job) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasJobCompleted", reflect.TypeOf((*MockIJobManager)(nil).HasJobCompleted), ctx, arg1) } // HasJobStarted mocks base method. -func (m *MockIJobManager) HasJobStarted(ctx context.Context, job job.IAsynchronousJob) (bool, error) { +func (m *MockIJobManager) HasJobStarted(ctx context.Context, arg1 job.IAsynchronousJob) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HasJobStarted", ctx, job) + ret := m.ctrl.Call(m, "HasJobStarted", ctx, arg1) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } // HasJobStarted indicates an expected call of HasJobStarted. -func (mr *MockIJobManagerMockRecorder) HasJobStarted(ctx, job any) *gomock.Call { +func (mr *MockIJobManagerMockRecorder) HasJobStarted(ctx, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasJobStarted", reflect.TypeOf((*MockIJobManager)(nil).HasJobStarted), ctx, job) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasJobStarted", reflect.TypeOf((*MockIJobManager)(nil).HasJobStarted), ctx, arg1) } // LogJobMessagesUntilNow mocks base method. -func (m *MockIJobManager) LogJobMessagesUntilNow(ctx context.Context, job job.IAsynchronousJob, loggingTimeout time.Duration) error { +func (m *MockIJobManager) LogJobMessagesUntilNow(ctx context.Context, arg1 job.IAsynchronousJob, loggingTimeout time.Duration) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LogJobMessagesUntilNow", ctx, job, loggingTimeout) + ret := m.ctrl.Call(m, "LogJobMessagesUntilNow", ctx, arg1, loggingTimeout) ret0, _ := ret[0].(error) return ret0 } // LogJobMessagesUntilNow indicates an expected call of LogJobMessagesUntilNow. -func (mr *MockIJobManagerMockRecorder) LogJobMessagesUntilNow(ctx, job, loggingTimeout any) *gomock.Call { +func (mr *MockIJobManagerMockRecorder) LogJobMessagesUntilNow(ctx, arg1, loggingTimeout any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogJobMessagesUntilNow", reflect.TypeOf((*MockIJobManager)(nil).LogJobMessagesUntilNow), ctx, job, loggingTimeout) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogJobMessagesUntilNow", reflect.TypeOf((*MockIJobManager)(nil).LogJobMessagesUntilNow), ctx, arg1, loggingTimeout) } // WaitForJobCompletion mocks base method. -func (m *MockIJobManager) WaitForJobCompletion(ctx context.Context, job job.IAsynchronousJob) error { +func (m *MockIJobManager) WaitForJobCompletion(ctx context.Context, arg1 job.IAsynchronousJob) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WaitForJobCompletion", ctx, job) + ret := m.ctrl.Call(m, "WaitForJobCompletion", ctx, arg1) ret0, _ := ret[0].(error) return ret0 } // WaitForJobCompletion indicates an expected call of WaitForJobCompletion. -func (mr *MockIJobManagerMockRecorder) WaitForJobCompletion(ctx, job any) *gomock.Call { +func (mr *MockIJobManagerMockRecorder) WaitForJobCompletion(ctx, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForJobCompletion", reflect.TypeOf((*MockIJobManager)(nil).WaitForJobCompletion), ctx, job) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForJobCompletion", reflect.TypeOf((*MockIJobManager)(nil).WaitForJobCompletion), ctx, arg1) } // WaitForJobCompletionWithTimeout mocks base method. -func (m *MockIJobManager) WaitForJobCompletionWithTimeout(ctx context.Context, job job.IAsynchronousJob, jobTimeout time.Duration) error { +func (m *MockIJobManager) WaitForJobCompletionWithTimeout(ctx context.Context, arg1 job.IAsynchronousJob, jobTimeout time.Duration) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WaitForJobCompletionWithTimeout", ctx, job, jobTimeout) + ret := m.ctrl.Call(m, "WaitForJobCompletionWithTimeout", ctx, arg1, jobTimeout) ret0, _ := ret[0].(error) return ret0 } // WaitForJobCompletionWithTimeout indicates an expected call of WaitForJobCompletionWithTimeout. -func (mr *MockIJobManagerMockRecorder) WaitForJobCompletionWithTimeout(ctx, job, jobTimeout any) *gomock.Call { +func (mr *MockIJobManagerMockRecorder) WaitForJobCompletionWithTimeout(ctx, arg1, jobTimeout any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForJobCompletionWithTimeout", reflect.TypeOf((*MockIJobManager)(nil).WaitForJobCompletionWithTimeout), ctx, job, jobTimeout) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForJobCompletionWithTimeout", reflect.TypeOf((*MockIJobManager)(nil).WaitForJobCompletionWithTimeout), ctx, arg1, jobTimeout) } diff --git a/utils/resource/interfaces.go b/utils/resource/interfaces.go index f9f0bb6..71dff05 100644 --- a/utils/resource/interfaces.go +++ b/utils/resource/interfaces.go @@ -10,7 +10,7 @@ import "github.com/ARM-software/embedded-development-services-client/client" // Mocks are generated using `go generate ./...` // Add interfaces to the following command for a mock to be generated -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IResource +//go:generate go tool mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IResource // IResource describe an API resource. type IResource interface { diff --git a/utils/store/interfaces.go b/utils/store/interfaces.go index a18070d..e238de6 100644 --- a/utils/store/interfaces.go +++ b/utils/store/interfaces.go @@ -15,7 +15,7 @@ import ( // Mocks are generated using `go generate ./...` // Add interfaces to the following command for a mock to be generated -//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IStore +//go:generate go tool mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IStore type IStore interface { io.Closer