From 7c97c25350413d83c515d40fc2b1765ebbbba43e Mon Sep 17 00:00:00 2001 From: Kian Parvin Date: Tue, 6 Aug 2024 11:14:17 +0200 Subject: [PATCH] feat: add mock client tests --- internal/juju/common_test.go | 8 +-- internal/juju/interfaces.go | 2 +- internal/juju/jaas.go | 10 ++-- internal/juju/jaas_test.go | 99 ++++++++++++++++++++++++++++++--- internal/juju/mock_test.go | 101 ++++++++++++++++++++++++++++------ internal/juju/offers.go | 3 +- internal/juju/secrets_test.go | 2 +- 7 files changed, 188 insertions(+), 37 deletions(-) diff --git a/internal/juju/common_test.go b/internal/juju/common_test.go index a02b54a4..c392ddb8 100644 --- a/internal/juju/common_test.go +++ b/internal/juju/common_test.go @@ -13,14 +13,14 @@ import ( type JujuSuite struct { suite.Suite - testModelName string + testModelName *string mockConnection *MockConnection mockSharedClient *MockSharedClient } -func (s *JujuSuite) setupMocks(t *testing.T) *gomock.Controller { - s.testModelName = "test-secret-model" +func (s *JujuSuite) setupMocks(t *testing.T, modelName *string) *gomock.Controller { + s.testModelName = modelName ctlr := gomock.NewController(t) @@ -35,7 +35,7 @@ func (s *JujuSuite) setupMocks(t *testing.T) *gomock.Controller { s.mockSharedClient.EXPECT().Errorf(gomock.Any(), gomock.Any()).Do(log).AnyTimes() s.mockSharedClient.EXPECT().Tracef(gomock.Any(), gomock.Any()).Do(log).AnyTimes() s.mockSharedClient.EXPECT().JujuLogger().Return(&jujuLoggerShim{}).AnyTimes() - s.mockSharedClient.EXPECT().GetConnection(&s.testModelName).Return(s.mockConnection, nil).AnyTimes() + s.mockSharedClient.EXPECT().GetConnection(s.testModelName).Return(s.mockConnection, nil).AnyTimes() return ctlr } diff --git a/internal/juju/interfaces.go b/internal/juju/interfaces.go index 7190bd87..be8460a4 100644 --- a/internal/juju/interfaces.go +++ b/internal/juju/interfaces.go @@ -78,7 +78,7 @@ type SecretAPIClient interface { RevokeSecret(uri *secrets.URI, name string, apps []string) ([]error, error) } -type JaasApiClient interface { +type JaasAPIClient interface { ListRelationshipTuples(req *jaasparams.ListRelationshipTuplesRequest) (*jaasparams.ListRelationshipTuplesResponse, error) AddRelation(req *jaasparams.AddRelationRequest) error RemoveRelation(req *jaasparams.RemoveRelationRequest) error diff --git a/internal/juju/jaas.go b/internal/juju/jaas.go index ded39798..020a16dc 100644 --- a/internal/juju/jaas.go +++ b/internal/juju/jaas.go @@ -10,19 +10,19 @@ import ( type jaasClient struct { SharedClient - getJaasApiClient func(jujuapi.Connection) JaasApiClient + getJaasApiClient func(jujuapi.Connection) JaasAPIClient } func newJaasClient(sc SharedClient) *jaasClient { return &jaasClient{ SharedClient: sc, - getJaasApiClient: func(conn jujuapi.Connection) JaasApiClient { + getJaasApiClient: func(conn jujuapi.Connection) JaasAPIClient { return api.NewClient(conn) }, } } -func (jc *jaasClient) AddTuples(tuples []params.RelationshipTuple) error { +func (jc *jaasClient) AddRelations(tuples []params.RelationshipTuple) error { conn, err := jc.GetConnection(nil) if err != nil { return err @@ -35,7 +35,7 @@ func (jc *jaasClient) AddTuples(tuples []params.RelationshipTuple) error { return cl.AddRelation(&req) } -func (jc *jaasClient) DeleteTuples(tuples []params.RelationshipTuple) error { +func (jc *jaasClient) DeleteRelations(tuples []params.RelationshipTuple) error { conn, err := jc.GetConnection(nil) if err != nil { return err @@ -48,7 +48,7 @@ func (jc *jaasClient) DeleteTuples(tuples []params.RelationshipTuple) error { return cl.RemoveRelation(&req) } -func (jc *jaasClient) ReadRelation(tuple *params.RelationshipTuple) ([]params.RelationshipTuple, error) { +func (jc *jaasClient) ReadRelations(tuple *params.RelationshipTuple) ([]params.RelationshipTuple, error) { if tuple == nil { return nil, errors.New("add relation request nil") } diff --git a/internal/juju/jaas_test.go b/internal/juju/jaas_test.go index da987c2b..e7fe5cd0 100644 --- a/internal/juju/jaas_test.go +++ b/internal/juju/jaas_test.go @@ -3,6 +3,8 @@ package juju import ( "testing" + "github.com/canonical/jimm-go-sdk/v3/api/params" + "github.com/juju/juju/api" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" ) @@ -11,18 +13,101 @@ type JaasSuite struct { suite.Suite JujuSuite - testModelName string - - mockJaasClient *MockSecretAPIClient + mockJaasClient *MockJaasAPIClient } func (s *JaasSuite) SetupTest() {} func (s *JaasSuite) setupMocks(t *testing.T) *gomock.Controller { - s.testModelName = "test-secret-model" - - ctlr := s.JujuSuite.setupMocks(t) - s.mockJaasClient = NewMockSecretAPIClient(ctlr) + ctlr := s.JujuSuite.setupMocks(t, nil) + s.mockJaasClient = NewMockJaasAPIClient(ctlr) return ctlr } + +func (s *JaasSuite) getJaasClient() jaasClient { + return jaasClient{ + SharedClient: s.JujuSuite.mockSharedClient, + getJaasApiClient: func(connection api.Connection) JaasAPIClient { + return s.mockJaasClient + }, + } +} + +func (s *JaasSuite) TestAddRelations() { + ctlr := s.setupMocks(s.T()) + defer ctlr.Finish() + + tuples := []params.RelationshipTuple{ + {Object: "object-1", Relation: "relation", TargetObject: "target-1"}, + {Object: "object-2", Relation: "relation", TargetObject: "target-2"}, + } + req := params.AddRelationRequest{ + Tuples: tuples, + } + + s.mockJaasClient.EXPECT().AddRelation( + &req, + ).Return(nil).Times(1) + + client := s.getJaasClient() + err := client.AddRelations(tuples) + s.Require().NoError(err) +} + +func (s *JaasSuite) TestDeleteRelations() { + ctlr := s.setupMocks(s.T()) + defer ctlr.Finish() + + tuples := []params.RelationshipTuple{ + {Object: "object-1", Relation: "relation", TargetObject: "target-1"}, + {Object: "object-2", Relation: "relation", TargetObject: "target-2"}, + } + req := params.RemoveRelationRequest{ + Tuples: tuples, + } + + s.mockJaasClient.EXPECT().RemoveRelation( + &req, + ).Return(nil).Times(1) + + client := s.getJaasClient() + err := client.DeleteRelations(tuples) + s.Require().NoError(err) +} + +func (s *JaasSuite) TestReadRelations() { + ctlr := s.setupMocks(s.T()) + defer ctlr.Finish() + + tuple := params.RelationshipTuple{Object: "object-1", Relation: "relation", TargetObject: "target-1"} + // 1st request/response has no token in the request and a token in the response indicating another page is available. + req := ¶ms.ListRelationshipTuplesRequest{Tuple: tuple} + respWithToken := ¶ms.ListRelationshipTuplesResponse{ + Tuples: []params.RelationshipTuple{tuple}, + ContinuationToken: "token", + } + s.mockJaasClient.EXPECT().ListRelationshipTuples( + req, + ).Return(respWithToken, nil).Times(1) + // 2nd request/response has the previous token in the request and no token in the response, indicating all pages have been consumed. + reqWithToken := ¶ms.ListRelationshipTuplesRequest{Tuple: tuple, ContinuationToken: "token"} + respWithoutToken := ¶ms.ListRelationshipTuplesResponse{ + Tuples: []params.RelationshipTuple{tuple}, + ContinuationToken: "", + } + s.mockJaasClient.EXPECT().ListRelationshipTuples( + reqWithToken, + ).Return(respWithoutToken, nil).Times(1) + + client := s.getJaasClient() + relations, err := client.ReadRelations(&tuple) + s.Require().NoError(err) + s.Require().Len(relations, 2) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestJaasSuite(t *testing.T) { + suite.Run(t, new(JaasSuite)) +} diff --git a/internal/juju/mock_test.go b/internal/juju/mock_test.go index 506c13ac..818b80e7 100644 --- a/internal/juju/mock_test.go +++ b/internal/juju/mock_test.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/juju/terraform-provider-juju/internal/juju (interfaces: SharedClient,ClientAPIClient,ApplicationAPIClient,ModelConfigAPIClient,ResourceAPIClient,SecretAPIClient) +// Source: github.com/juju/terraform-provider-juju/internal/juju (interfaces: SharedClient,ClientAPIClient,ApplicationAPIClient,ModelConfigAPIClient,ResourceAPIClient,SecretAPIClient,JaasAPIClient) // // Generated by this command: // -// mockgen -package juju -destination mock_test.go github.com/juju/terraform-provider-juju/internal/juju SharedClient,ClientAPIClient,ApplicationAPIClient,ModelConfigAPIClient,ResourceAPIClient,SecretAPIClient +// mockgen -package juju -destination mock_test.go github.com/juju/terraform-provider-juju/internal/juju SharedClient,ClientAPIClient,ApplicationAPIClient,ModelConfigAPIClient,ResourceAPIClient,SecretAPIClient,JaasAPIClient // // Package juju is a generated GoMock package. @@ -12,6 +12,7 @@ package juju import ( reflect "reflect" + params "github.com/canonical/jimm-go-sdk/v3/api/params" charm "github.com/juju/charm/v12" api "github.com/juju/juju/api" application "github.com/juju/juju/api/client/application" @@ -23,7 +24,7 @@ import ( model "github.com/juju/juju/core/model" resources0 "github.com/juju/juju/core/resources" secrets0 "github.com/juju/juju/core/secrets" - params "github.com/juju/juju/rpc/params" + params0 "github.com/juju/juju/rpc/params" names "github.com/juju/names/v5" gomock "go.uber.org/mock/gomock" ) @@ -221,10 +222,10 @@ func (m *MockClientAPIClient) EXPECT() *MockClientAPIClientMockRecorder { } // Status mocks base method. -func (m *MockClientAPIClient) Status(arg0 *client.StatusArgs) (*params.FullStatus, error) { +func (m *MockClientAPIClient) Status(arg0 *client.StatusArgs) (*params0.FullStatus, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Status", arg0) - ret0, _ := ret[0].(*params.FullStatus) + ret0, _ := ret[0].(*params0.FullStatus) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -274,10 +275,10 @@ func (mr *MockApplicationAPIClientMockRecorder) AddUnits(arg0 any) *gomock.Call } // ApplicationsInfo mocks base method. -func (m *MockApplicationAPIClient) ApplicationsInfo(arg0 []names.ApplicationTag) ([]params.ApplicationInfoResult, error) { +func (m *MockApplicationAPIClient) ApplicationsInfo(arg0 []names.ApplicationTag) ([]params0.ApplicationInfoResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ApplicationsInfo", arg0) - ret0, _ := ret[0].([]params.ApplicationInfoResult) + ret0, _ := ret[0].([]params0.ApplicationInfoResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -303,10 +304,10 @@ func (mr *MockApplicationAPIClientMockRecorder) Deploy(arg0 any) *gomock.Call { } // DestroyApplications mocks base method. -func (m *MockApplicationAPIClient) DestroyApplications(arg0 application.DestroyApplicationsParams) ([]params.DestroyApplicationResult, error) { +func (m *MockApplicationAPIClient) DestroyApplications(arg0 application.DestroyApplicationsParams) ([]params0.DestroyApplicationResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DestroyApplications", arg0) - ret0, _ := ret[0].([]params.DestroyApplicationResult) + ret0, _ := ret[0].([]params0.DestroyApplicationResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -318,10 +319,10 @@ func (mr *MockApplicationAPIClientMockRecorder) DestroyApplications(arg0 any) *g } // DestroyUnits mocks base method. -func (m *MockApplicationAPIClient) DestroyUnits(arg0 application.DestroyUnitsParams) ([]params.DestroyUnitResult, error) { +func (m *MockApplicationAPIClient) DestroyUnits(arg0 application.DestroyUnitsParams) ([]params0.DestroyUnitResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DestroyUnits", arg0) - ret0, _ := ret[0].([]params.DestroyUnitResult) + ret0, _ := ret[0].([]params0.DestroyUnitResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -333,7 +334,7 @@ func (mr *MockApplicationAPIClientMockRecorder) DestroyUnits(arg0 any) *gomock.C } // Expose mocks base method. -func (m *MockApplicationAPIClient) Expose(arg0 string, arg1 map[string]params.ExposedEndpoint) error { +func (m *MockApplicationAPIClient) Expose(arg0 string, arg1 map[string]params0.ExposedEndpoint) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Expose", arg0, arg1) ret0, _ := ret[0].(error) @@ -347,10 +348,10 @@ func (mr *MockApplicationAPIClientMockRecorder) Expose(arg0, arg1 any) *gomock.C } // Get mocks base method. -func (m *MockApplicationAPIClient) Get(arg0, arg1 string) (*params.ApplicationGetResults, error) { +func (m *MockApplicationAPIClient) Get(arg0, arg1 string) (*params0.ApplicationGetResults, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", arg0, arg1) - ret0, _ := ret[0].(*params.ApplicationGetResults) + ret0, _ := ret[0].(*params0.ApplicationGetResults) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -397,7 +398,7 @@ func (mr *MockApplicationAPIClientMockRecorder) GetConstraints(arg0 ...any) *gom } // MergeBindings mocks base method. -func (m *MockApplicationAPIClient) MergeBindings(arg0 params.ApplicationMergeBindingsArgs) error { +func (m *MockApplicationAPIClient) MergeBindings(arg0 params0.ApplicationMergeBindingsArgs) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MergeBindings", arg0) ret0, _ := ret[0].(error) @@ -411,10 +412,10 @@ func (mr *MockApplicationAPIClientMockRecorder) MergeBindings(arg0 any) *gomock. } // ScaleApplication mocks base method. -func (m *MockApplicationAPIClient) ScaleApplication(arg0 application.ScaleApplicationParams) (params.ScaleApplicationResult, error) { +func (m *MockApplicationAPIClient) ScaleApplication(arg0 application.ScaleApplicationParams) (params0.ScaleApplicationResult, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ScaleApplication", arg0) - ret0, _ := ret[0].(params.ScaleApplicationResult) + ret0, _ := ret[0].(params0.ScaleApplicationResult) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -682,3 +683,69 @@ func (mr *MockSecretAPIClientMockRecorder) UpdateSecret(arg0, arg1, arg2, arg3, mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSecret", reflect.TypeOf((*MockSecretAPIClient)(nil).UpdateSecret), arg0, arg1, arg2, arg3, arg4, arg5) } + +// MockJaasAPIClient is a mock of JaasAPIClient interface. +type MockJaasAPIClient struct { + ctrl *gomock.Controller + recorder *MockJaasAPIClientMockRecorder +} + +// MockJaasAPIClientMockRecorder is the mock recorder for MockJaasAPIClient. +type MockJaasAPIClientMockRecorder struct { + mock *MockJaasAPIClient +} + +// NewMockJaasAPIClient creates a new mock instance. +func NewMockJaasAPIClient(ctrl *gomock.Controller) *MockJaasAPIClient { + mock := &MockJaasAPIClient{ctrl: ctrl} + mock.recorder = &MockJaasAPIClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockJaasAPIClient) EXPECT() *MockJaasAPIClientMockRecorder { + return m.recorder +} + +// AddRelation mocks base method. +func (m *MockJaasAPIClient) AddRelation(arg0 *params.AddRelationRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddRelation", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddRelation indicates an expected call of AddRelation. +func (mr *MockJaasAPIClientMockRecorder) AddRelation(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRelation", reflect.TypeOf((*MockJaasAPIClient)(nil).AddRelation), arg0) +} + +// ListRelationshipTuples mocks base method. +func (m *MockJaasAPIClient) ListRelationshipTuples(arg0 *params.ListRelationshipTuplesRequest) (*params.ListRelationshipTuplesResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListRelationshipTuples", arg0) + ret0, _ := ret[0].(*params.ListRelationshipTuplesResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListRelationshipTuples indicates an expected call of ListRelationshipTuples. +func (mr *MockJaasAPIClientMockRecorder) ListRelationshipTuples(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRelationshipTuples", reflect.TypeOf((*MockJaasAPIClient)(nil).ListRelationshipTuples), arg0) +} + +// RemoveRelation mocks base method. +func (m *MockJaasAPIClient) RemoveRelation(arg0 *params.RemoveRelationRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveRelation", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveRelation indicates an expected call of RemoveRelation. +func (mr *MockJaasAPIClientMockRecorder) RemoveRelation(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveRelation", reflect.TypeOf((*MockJaasAPIClient)(nil).RemoveRelation), arg0) +} diff --git a/internal/juju/offers.go b/internal/juju/offers.go index 864d9a5a..b8428417 100644 --- a/internal/juju/offers.go +++ b/internal/juju/offers.go @@ -10,7 +10,6 @@ import ( "strings" "time" - "github.com/juju/juju/api/client/application" apiapplication "github.com/juju/juju/api/client/application" "github.com/juju/juju/api/client/applicationoffers" apiclient "github.com/juju/juju/api/client/client" @@ -103,7 +102,7 @@ func (c offersClient) CreateOffer(input *CreateOfferInput) (*CreateOfferResponse return nil, append(errs, err) } defer func() { _ = modelConn.Close() }() - applicationClient := application.NewClient(modelConn) + applicationClient := apiapplication.NewClient(modelConn) // wait for the app to be available ctx, cancel := context.WithTimeout(context.Background(), OfferAppAvailableTimeout) diff --git a/internal/juju/secrets_test.go b/internal/juju/secrets_test.go index f5bfd29f..e74be5b4 100644 --- a/internal/juju/secrets_test.go +++ b/internal/juju/secrets_test.go @@ -29,7 +29,7 @@ func (s *SecretSuite) SetupTest() {} func (s *SecretSuite) setupMocks(t *testing.T) *gomock.Controller { s.testModelName = "test-secret-model" - ctlr := s.JujuSuite.setupMocks(t) + ctlr := s.JujuSuite.setupMocks(t, &s.testModelName) s.mockSecretClient = NewMockSecretAPIClient(ctlr) return ctlr