Skip to content

Commit

Permalink
Add mockery test case to token reconciler (#446)
Browse files Browse the repository at this point in the history
Add mock nephio gitea client.
Add example test case fro deketeToken function.
Anti pattern arises in relation to the gitea client wrapper as it's also
being used by the repo reconciler.

---------

Signed-off-by: efiacor <[email protected]>
Co-authored-by: Liam Fallon <[email protected]>
  • Loading branch information
efiacor and liamfallon authored Feb 12, 2024
1 parent 3ddd4e2 commit 7d81bd2
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 2 deletions.
6 changes: 6 additions & 0 deletions controllers/pkg/.mockery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
packages:
github.com/nephio-project/nephio/controllers/pkg/giteaclient:
interfaces:
GiteaClient:
config:
dir: "{{.InterfaceDir}}"
5 changes: 5 additions & 0 deletions controllers/pkg/giteaclient/giteaclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type GiteaClient interface {
GetRepo(userName string, repoCRName string) (*gitea.Repository, *gitea.Response, error)
CreateRepo(createRepoOption gitea.CreateRepoOption) (*gitea.Repository, *gitea.Response, error)
EditRepo(userName string, repoCRName string, editRepoOption gitea.EditRepoOption) (*gitea.Repository, *gitea.Response, error)
DeleteAccessToken(value interface{}) (*gitea.Response, error)
}

var lock = &sync.Mutex{}
Expand Down Expand Up @@ -166,3 +167,7 @@ func (r *gc) CreateRepo(createRepoOption gitea.CreateRepoOption) (*gitea.Reposit
func (r *gc) EditRepo(userName string, repoCRName string, editRepoOption gitea.EditRepoOption) (*gitea.Repository, *gitea.Response, error) {
return r.giteaClient.EditRepo(userName, repoCRName, editRepoOption)
}

func (r *gc) DeleteAccessToken(value interface{}) (*gitea.Response, error) {
return r.giteaClient.DeleteAccessToken(value)
}
55 changes: 55 additions & 0 deletions controllers/pkg/giteaclient/mock_GiteaClient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions controllers/pkg/reconcilers/repository/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type repoTest struct {
wantErr bool
}


func TestUpsertRepo(t *testing.T) {
dummyString := "Dummy String"
dummyBool := true
Expand Down
4 changes: 2 additions & 2 deletions controllers/pkg/reconcilers/token/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
// Delete the token from the git server
// when successful remove the finalizer
if cr.Spec.Lifecycle.DeletionPolicy == commonv1alpha1.DeletionDelete {
if err := r.deleteToken(ctx, giteaClient, cr); err != nil {
if err := r.deleteToken(ctx, r.giteaClient, cr); err != nil {
return ctrl.Result{Requeue: true}, errors.Wrap(r.Status().Update(ctx, cr), errUpdateStatus)
}
}
Expand Down Expand Up @@ -219,7 +219,7 @@ func (r *reconciler) createToken(ctx context.Context, giteaClient *gitea.Client,
return nil
}

func (r *reconciler) deleteToken(ctx context.Context, giteaClient *gitea.Client, cr *infrav1alpha1.Token) error {
func (r *reconciler) deleteToken(ctx context.Context, giteaClient giteaclient.GiteaClient, cr *infrav1alpha1.Token) error {
_, err := giteaClient.DeleteAccessToken(cr.GetTokenName())
if err != nil {
log.FromContext(ctx).Error(err, "cannot delete token")
Expand Down
98 changes: 98 additions & 0 deletions controllers/pkg/reconcilers/token/reconciler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2023 The Nephio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package token

import (
"context"
"fmt"
"github.com/go-logr/logr"
"github.com/nephio-project/nephio/controllers/pkg/giteaclient"
"github.com/nephio-project/nephio/controllers/pkg/resource"
"github.com/stretchr/testify/mock"
"sigs.k8s.io/controller-runtime/pkg/log"
"testing"
infrav1alpha1 "github.com/nephio-project/api/infra/v1alpha1"
)

func TestDeleteToken(t *testing.T) {
type mockHelper struct {
methodName string
argType []string
retArgList []interface{}
}
type fields struct {
APIPatchingApplicator resource.APIPatchingApplicator
giteaClient giteaclient.GiteaClient
finalizer *resource.APIFinalizer
l logr.Logger
}
type args struct {
ctx context.Context
giteaClient giteaclient.GiteaClient
cr *infrav1alpha1.Token
}
tests := []struct {
name string
fields fields
args args
mocks []mockHelper
wantErr bool
}{
{
name: "Delete Access token reports error",
fields: fields{resource.NewAPIPatchingApplicator(nil), nil, nil, log.FromContext(nil)},
args: args{nil, nil, &infrav1alpha1.Token{}},
mocks: []mockHelper{
{"DeleteAccessToken", []string{"string"}, []interface{}{nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed")}},
},
wantErr: true,
},
{
name: "Delete Access token success",
fields: fields{resource.NewAPIPatchingApplicator(nil), nil, nil, log.FromContext(nil)},
args: args{nil, nil, &infrav1alpha1.Token{}},
mocks: []mockHelper{
{"DeleteAccessToken", []string{"string"}, []interface{}{nil, nil}},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &reconciler{
APIPatchingApplicator: tt.fields.APIPatchingApplicator,
giteaClient: tt.fields.giteaClient,
finalizer: tt.fields.finalizer,
}
// The below block being setup and processing of mocks before invoking the function to be tested
mockGClient := new(giteaclient.MockGiteaClient)
tt.args.giteaClient = mockGClient
tt.fields.giteaClient = mockGClient
for counter := range tt.mocks {
call := mockGClient.Mock.On(tt.mocks[counter].methodName)
for _, arg := range tt.mocks[counter].argType {
call.Arguments = append(call.Arguments, mock.AnythingOfType(arg))
}
for _, ret := range tt.mocks[counter].retArgList {
call.ReturnArguments = append(call.ReturnArguments, ret)
}
}

if err := r.deleteToken(tt.args.ctx, tt.args.giteaClient, tt.args.cr); (err != nil) != tt.wantErr {
t.Errorf("deleteToken() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
19 changes: 19 additions & 0 deletions default-go-test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@


GO_VERSION ?= 1.20.2
MOCKERY_VERSION=2.37.1
TEST_COVERAGE_FILE=lcov.info
TEST_COVERAGE_HTML_FILE=coverage_unit.html
TEST_COVERAGE_FUNC_FILE=func_coverage.out
GIT_ROOT_DIR ?= $(dir $(lastword $(MAKEFILE_LIST)))
OS_ARCH ?= $(shell uname -m)
OS ?= $(shell uname)
include $(GIT_ROOT_DIR)/detect-container-runtime.mk

.PHONY: unit
Expand All @@ -36,6 +39,22 @@ else
go tool cover -func=${TEST_COVERAGE_FILE} -o ${TEST_COVERAGE_FUNC_FILE}
endif

.PHONY: install-mockery
install-mockery: ## install mockery
ifeq ($(CONTAINER_RUNNABLE), 0)
$(CONTAINER_RUNTIME) pull docker.io/vektra/mockery:v${MOCKERY_VERSION}
else
wget -qO- https://github.com/vektra/mockery/releases/download/v${MOCKERY_VERSION}/mockery_${MOCKERY_VERSION}_${OS}_${OS_ARCH}.tar.gz | sudo tar -xvzf - -C /usr/local/bin
endif

.PHONY: generate-mocks
generate-mocks:
ifeq ($(CONTAINER_RUNNABLE), 0)
$(CONTAINER_RUNTIME) run --security-opt label=disable -v ${PWD}:/src -w /src docker.io/vektra/mockery:v${MOCKERY_VERSION}
else
mockery
endif

.PHONY: unit-clean
unit-clean: ## Clean up the artifacts created by the unit tests
ifeq ($(CONTAINER_RUNNABLE), 0)
Expand Down

0 comments on commit 7d81bd2

Please sign in to comment.