Provisioning: add most mocks to unit test provisioning jobs (#103446)

* Use interface for factories

* Add most mocks to unit test jobs

* Generate more mocks for main jobs package

* Interface for parser

* Use clients directly without parser

* Regenerate mock

* Eliminate resource clients from Parser

* Interface for folder tree
This commit is contained in:
Roberto Jiménez Sánchez
2025-04-04 15:42:20 +03:00
committed by GitHub
parent 5465abd5a1
commit 364247e26b
45 changed files with 3025 additions and 112 deletions
@@ -0,0 +1,96 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package legacy
import (
context "context"
resource "github.com/grafana/grafana/pkg/storage/unified/resource"
mock "github.com/stretchr/testify/mock"
)
// MockLegacyMigrator is an autogenerated mock type for the LegacyMigrator type
type MockLegacyMigrator struct {
mock.Mock
}
type MockLegacyMigrator_Expecter struct {
mock *mock.Mock
}
func (_m *MockLegacyMigrator) EXPECT() *MockLegacyMigrator_Expecter {
return &MockLegacyMigrator_Expecter{mock: &_m.Mock}
}
// Migrate provides a mock function with given fields: ctx, opts
func (_m *MockLegacyMigrator) Migrate(ctx context.Context, opts MigrateOptions) (*resource.BulkResponse, error) {
ret := _m.Called(ctx, opts)
if len(ret) == 0 {
panic("no return value specified for Migrate")
}
var r0 *resource.BulkResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, MigrateOptions) (*resource.BulkResponse, error)); ok {
return rf(ctx, opts)
}
if rf, ok := ret.Get(0).(func(context.Context, MigrateOptions) *resource.BulkResponse); ok {
r0 = rf(ctx, opts)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*resource.BulkResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, MigrateOptions) error); ok {
r1 = rf(ctx, opts)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockLegacyMigrator_Migrate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Migrate'
type MockLegacyMigrator_Migrate_Call struct {
*mock.Call
}
// Migrate is a helper method to define mock.On call
// - ctx context.Context
// - opts MigrateOptions
func (_e *MockLegacyMigrator_Expecter) Migrate(ctx interface{}, opts interface{}) *MockLegacyMigrator_Migrate_Call {
return &MockLegacyMigrator_Migrate_Call{Call: _e.mock.On("Migrate", ctx, opts)}
}
func (_c *MockLegacyMigrator_Migrate_Call) Run(run func(ctx context.Context, opts MigrateOptions)) *MockLegacyMigrator_Migrate_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(MigrateOptions))
})
return _c
}
func (_c *MockLegacyMigrator_Migrate_Call) Return(_a0 *resource.BulkResponse, _a1 error) *MockLegacyMigrator_Migrate_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockLegacyMigrator_Migrate_Call) RunAndReturn(run func(context.Context, MigrateOptions) (*resource.BulkResponse, error)) *MockLegacyMigrator_Migrate_Call {
_c.Call.Return(run)
return _c
}
// NewMockLegacyMigrator creates a new instance of MockLegacyMigrator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockLegacyMigrator(t interface {
mock.TestingT
Cleanup(func())
}) *MockLegacyMigrator {
mock := &MockLegacyMigrator{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -35,6 +35,8 @@ type MigrateOptions struct {
}
// Read from legacy and write into unified storage
//
//go:generate mockery --name LegacyMigrator --structname MockLegacyMigrator --inpackage --filename legacy_migrator_mock.go --with-expecter
type LegacyMigrator interface {
Migrate(ctx context.Context, opts MigrateOptions) (*resource.BulkResponse, error)
}
@@ -29,7 +29,7 @@ const CleanFinalizer = "cleanup"
type finalizer struct {
lister resources.ResourceLister
clientFactory *resources.ClientFactory
clientFactory resources.ClientFactory
}
func (f *finalizer) process(ctx context.Context,
@@ -58,7 +58,7 @@ type RepositoryController struct {
resourceLister resources.ResourceLister
repoLister listers.RepositoryLister
repoSynced cache.InformerSynced
parsers *resources.ParserFactory
parsers resources.ParserFactory
logger logging.Logger
secrets secrets.Service
dualwrite dualwrite.Service
@@ -83,7 +83,8 @@ func NewRepositoryController(
repoInformer informer.RepositoryInformer,
repoGetter RepoGetter,
resourceLister resources.ResourceLister,
parsers *resources.ParserFactory,
parsers resources.ParserFactory,
clients resources.ClientFactory,
tester RepositoryTester,
jobs jobs.Queue,
secrets secrets.Service,
@@ -104,7 +105,7 @@ func NewRepositoryController(
parsers: parsers,
finalizer: &finalizer{
lister: resourceLister,
clientFactory: parsers.ClientFactory,
clientFactory: clients,
},
tester: tester,
jobs: jobs,
+12 -2
View File
@@ -24,7 +24,12 @@ const (
type filesConnector struct {
getter RepoGetter
parsers *resources.ParserFactory
parsers resources.ParserFactory
clients resources.ClientFactory
}
func NewFilesConnector(getter RepoGetter, parsers resources.ParserFactory, clients resources.ClientFactory) *filesConnector {
return &filesConnector{getter: getter, parsers: parsers, clients: clients}
}
func (*filesConnector) New() runtime.Object {
@@ -70,7 +75,12 @@ func (s *filesConnector) Connect(ctx context.Context, name string, opts runtime.
return nil, fmt.Errorf("failed to get parser: %w", err)
}
folderClient, err := parser.Clients().Folder()
clients, err := s.clients.Clients(ctx, repo.Config().Namespace)
if err != nil {
return nil, fmt.Errorf("failed to get clients: %w", err)
}
folderClient, err := clients.Folder()
if err != nil {
return nil, fmt.Errorf("failed to get folder client: %w", err)
}
@@ -15,6 +15,8 @@ import (
// Store is an abstraction for the storage API.
// This exists to allow for unit testing.
//
//go:generate mockery --name Store --structname MockStore --inpackage --filename store_mock.go --with-expecter
type Store interface {
// Claim takes a job from storage, marks it as ours, and returns it.
//
@@ -19,17 +19,18 @@ import (
type ExportWorker struct {
// required to create clients
clientFactory *resources.ClientFactory
clientFactory resources.ClientFactory
// Check where values are currently saved
storageStatus dualwrite.Service
parsers *resources.ParserFactory
parsers resources.ParserFactory
}
func NewExportWorker(clientFactory *resources.ClientFactory,
func NewExportWorker(
clientFactory resources.ClientFactory,
storageStatus dualwrite.Service,
parsers *resources.ParserFactory,
parsers resources.ParserFactory,
) *ExportWorker {
return &ExportWorker{
clientFactory,
@@ -15,6 +15,8 @@ import (
)
// History keeps track of completed jobs
//
//go:generate mockery --name History --structname MockHistory --inpackage --filename history_mock.go --with-expecter
type History interface {
// Adds a job to the history
WriteJob(ctx context.Context, job *provisioning.Job) error
@@ -0,0 +1,205 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
mock "github.com/stretchr/testify/mock"
)
// MockHistory is an autogenerated mock type for the History type
type MockHistory struct {
mock.Mock
}
type MockHistory_Expecter struct {
mock *mock.Mock
}
func (_m *MockHistory) EXPECT() *MockHistory_Expecter {
return &MockHistory_Expecter{mock: &_m.Mock}
}
// GetJob provides a mock function with given fields: ctx, namespace, repo, uid
func (_m *MockHistory) GetJob(ctx context.Context, namespace string, repo string, uid string) (*v0alpha1.Job, error) {
ret := _m.Called(ctx, namespace, repo, uid)
if len(ret) == 0 {
panic("no return value specified for GetJob")
}
var r0 *v0alpha1.Job
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (*v0alpha1.Job, error)); ok {
return rf(ctx, namespace, repo, uid)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string, string) *v0alpha1.Job); ok {
r0 = rf(ctx, namespace, repo, uid)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.Job)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok {
r1 = rf(ctx, namespace, repo, uid)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockHistory_GetJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetJob'
type MockHistory_GetJob_Call struct {
*mock.Call
}
// GetJob is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
// - repo string
// - uid string
func (_e *MockHistory_Expecter) GetJob(ctx interface{}, namespace interface{}, repo interface{}, uid interface{}) *MockHistory_GetJob_Call {
return &MockHistory_GetJob_Call{Call: _e.mock.On("GetJob", ctx, namespace, repo, uid)}
}
func (_c *MockHistory_GetJob_Call) Run(run func(ctx context.Context, namespace string, repo string, uid string)) *MockHistory_GetJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string))
})
return _c
}
func (_c *MockHistory_GetJob_Call) Return(_a0 *v0alpha1.Job, _a1 error) *MockHistory_GetJob_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockHistory_GetJob_Call) RunAndReturn(run func(context.Context, string, string, string) (*v0alpha1.Job, error)) *MockHistory_GetJob_Call {
_c.Call.Return(run)
return _c
}
// RecentJobs provides a mock function with given fields: ctx, namespace, repo
func (_m *MockHistory) RecentJobs(ctx context.Context, namespace string, repo string) (*v0alpha1.JobList, error) {
ret := _m.Called(ctx, namespace, repo)
if len(ret) == 0 {
panic("no return value specified for RecentJobs")
}
var r0 *v0alpha1.JobList
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*v0alpha1.JobList, error)); ok {
return rf(ctx, namespace, repo)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *v0alpha1.JobList); ok {
r0 = rf(ctx, namespace, repo)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.JobList)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, namespace, repo)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockHistory_RecentJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RecentJobs'
type MockHistory_RecentJobs_Call struct {
*mock.Call
}
// RecentJobs is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
// - repo string
func (_e *MockHistory_Expecter) RecentJobs(ctx interface{}, namespace interface{}, repo interface{}) *MockHistory_RecentJobs_Call {
return &MockHistory_RecentJobs_Call{Call: _e.mock.On("RecentJobs", ctx, namespace, repo)}
}
func (_c *MockHistory_RecentJobs_Call) Run(run func(ctx context.Context, namespace string, repo string)) *MockHistory_RecentJobs_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockHistory_RecentJobs_Call) Return(_a0 *v0alpha1.JobList, _a1 error) *MockHistory_RecentJobs_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockHistory_RecentJobs_Call) RunAndReturn(run func(context.Context, string, string) (*v0alpha1.JobList, error)) *MockHistory_RecentJobs_Call {
_c.Call.Return(run)
return _c
}
// WriteJob provides a mock function with given fields: ctx, job
func (_m *MockHistory) WriteJob(ctx context.Context, job *v0alpha1.Job) error {
ret := _m.Called(ctx, job)
if len(ret) == 0 {
panic("no return value specified for WriteJob")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Job) error); ok {
r0 = rf(ctx, job)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockHistory_WriteJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteJob'
type MockHistory_WriteJob_Call struct {
*mock.Call
}
// WriteJob is a helper method to define mock.On call
// - ctx context.Context
// - job *v0alpha1.Job
func (_e *MockHistory_Expecter) WriteJob(ctx interface{}, job interface{}) *MockHistory_WriteJob_Call {
return &MockHistory_WriteJob_Call{Call: _e.mock.On("WriteJob", ctx, job)}
}
func (_c *MockHistory_WriteJob_Call) Run(run func(ctx context.Context, job *v0alpha1.Job)) *MockHistory_WriteJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*v0alpha1.Job))
})
return _c
}
func (_c *MockHistory_WriteJob_Call) Return(_a0 error) *MockHistory_WriteJob_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockHistory_WriteJob_Call) RunAndReturn(run func(context.Context, *v0alpha1.Job) error) *MockHistory_WriteJob_Call {
_c.Call.Return(run)
return _c
}
// NewMockHistory creates a new instance of MockHistory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockHistory(t interface {
mock.TestingT
Cleanup(func())
}) *MockHistory {
mock := &MockHistory{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -0,0 +1,375 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
mock "github.com/stretchr/testify/mock"
)
// MockJobProgressRecorder is an autogenerated mock type for the JobProgressRecorder type
type MockJobProgressRecorder struct {
mock.Mock
}
type MockJobProgressRecorder_Expecter struct {
mock *mock.Mock
}
func (_m *MockJobProgressRecorder) EXPECT() *MockJobProgressRecorder_Expecter {
return &MockJobProgressRecorder_Expecter{mock: &_m.Mock}
}
// Complete provides a mock function with given fields: ctx, err
func (_m *MockJobProgressRecorder) Complete(ctx context.Context, err error) v0alpha1.JobStatus {
ret := _m.Called(ctx, err)
if len(ret) == 0 {
panic("no return value specified for Complete")
}
var r0 v0alpha1.JobStatus
if rf, ok := ret.Get(0).(func(context.Context, error) v0alpha1.JobStatus); ok {
r0 = rf(ctx, err)
} else {
r0 = ret.Get(0).(v0alpha1.JobStatus)
}
return r0
}
// MockJobProgressRecorder_Complete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Complete'
type MockJobProgressRecorder_Complete_Call struct {
*mock.Call
}
// Complete is a helper method to define mock.On call
// - ctx context.Context
// - err error
func (_e *MockJobProgressRecorder_Expecter) Complete(ctx interface{}, err interface{}) *MockJobProgressRecorder_Complete_Call {
return &MockJobProgressRecorder_Complete_Call{Call: _e.mock.On("Complete", ctx, err)}
}
func (_c *MockJobProgressRecorder_Complete_Call) Run(run func(ctx context.Context, err error)) *MockJobProgressRecorder_Complete_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(error))
})
return _c
}
func (_c *MockJobProgressRecorder_Complete_Call) Return(_a0 v0alpha1.JobStatus) *MockJobProgressRecorder_Complete_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockJobProgressRecorder_Complete_Call) RunAndReturn(run func(context.Context, error) v0alpha1.JobStatus) *MockJobProgressRecorder_Complete_Call {
_c.Call.Return(run)
return _c
}
// GetRef provides a mock function with no fields
func (_m *MockJobProgressRecorder) GetRef() string {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetRef")
}
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockJobProgressRecorder_GetRef_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRef'
type MockJobProgressRecorder_GetRef_Call struct {
*mock.Call
}
// GetRef is a helper method to define mock.On call
func (_e *MockJobProgressRecorder_Expecter) GetRef() *MockJobProgressRecorder_GetRef_Call {
return &MockJobProgressRecorder_GetRef_Call{Call: _e.mock.On("GetRef")}
}
func (_c *MockJobProgressRecorder_GetRef_Call) Run(run func()) *MockJobProgressRecorder_GetRef_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockJobProgressRecorder_GetRef_Call) Return(_a0 string) *MockJobProgressRecorder_GetRef_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockJobProgressRecorder_GetRef_Call) RunAndReturn(run func() string) *MockJobProgressRecorder_GetRef_Call {
_c.Call.Return(run)
return _c
}
// Record provides a mock function with given fields: ctx, result
func (_m *MockJobProgressRecorder) Record(ctx context.Context, result JobResourceResult) {
_m.Called(ctx, result)
}
// MockJobProgressRecorder_Record_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Record'
type MockJobProgressRecorder_Record_Call struct {
*mock.Call
}
// Record is a helper method to define mock.On call
// - ctx context.Context
// - result JobResourceResult
func (_e *MockJobProgressRecorder_Expecter) Record(ctx interface{}, result interface{}) *MockJobProgressRecorder_Record_Call {
return &MockJobProgressRecorder_Record_Call{Call: _e.mock.On("Record", ctx, result)}
}
func (_c *MockJobProgressRecorder_Record_Call) Run(run func(ctx context.Context, result JobResourceResult)) *MockJobProgressRecorder_Record_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(JobResourceResult))
})
return _c
}
func (_c *MockJobProgressRecorder_Record_Call) Return() *MockJobProgressRecorder_Record_Call {
_c.Call.Return()
return _c
}
func (_c *MockJobProgressRecorder_Record_Call) RunAndReturn(run func(context.Context, JobResourceResult)) *MockJobProgressRecorder_Record_Call {
_c.Run(run)
return _c
}
// ResetResults provides a mock function with no fields
func (_m *MockJobProgressRecorder) ResetResults() {
_m.Called()
}
// MockJobProgressRecorder_ResetResults_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetResults'
type MockJobProgressRecorder_ResetResults_Call struct {
*mock.Call
}
// ResetResults is a helper method to define mock.On call
func (_e *MockJobProgressRecorder_Expecter) ResetResults() *MockJobProgressRecorder_ResetResults_Call {
return &MockJobProgressRecorder_ResetResults_Call{Call: _e.mock.On("ResetResults")}
}
func (_c *MockJobProgressRecorder_ResetResults_Call) Run(run func()) *MockJobProgressRecorder_ResetResults_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockJobProgressRecorder_ResetResults_Call) Return() *MockJobProgressRecorder_ResetResults_Call {
_c.Call.Return()
return _c
}
func (_c *MockJobProgressRecorder_ResetResults_Call) RunAndReturn(run func()) *MockJobProgressRecorder_ResetResults_Call {
_c.Run(run)
return _c
}
// SetFinalMessage provides a mock function with given fields: ctx, msg
func (_m *MockJobProgressRecorder) SetFinalMessage(ctx context.Context, msg string) {
_m.Called(ctx, msg)
}
// MockJobProgressRecorder_SetFinalMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetFinalMessage'
type MockJobProgressRecorder_SetFinalMessage_Call struct {
*mock.Call
}
// SetFinalMessage is a helper method to define mock.On call
// - ctx context.Context
// - msg string
func (_e *MockJobProgressRecorder_Expecter) SetFinalMessage(ctx interface{}, msg interface{}) *MockJobProgressRecorder_SetFinalMessage_Call {
return &MockJobProgressRecorder_SetFinalMessage_Call{Call: _e.mock.On("SetFinalMessage", ctx, msg)}
}
func (_c *MockJobProgressRecorder_SetFinalMessage_Call) Run(run func(ctx context.Context, msg string)) *MockJobProgressRecorder_SetFinalMessage_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockJobProgressRecorder_SetFinalMessage_Call) Return() *MockJobProgressRecorder_SetFinalMessage_Call {
_c.Call.Return()
return _c
}
func (_c *MockJobProgressRecorder_SetFinalMessage_Call) RunAndReturn(run func(context.Context, string)) *MockJobProgressRecorder_SetFinalMessage_Call {
_c.Run(run)
return _c
}
// SetMessage provides a mock function with given fields: ctx, msg
func (_m *MockJobProgressRecorder) SetMessage(ctx context.Context, msg string) {
_m.Called(ctx, msg)
}
// MockJobProgressRecorder_SetMessage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetMessage'
type MockJobProgressRecorder_SetMessage_Call struct {
*mock.Call
}
// SetMessage is a helper method to define mock.On call
// - ctx context.Context
// - msg string
func (_e *MockJobProgressRecorder_Expecter) SetMessage(ctx interface{}, msg interface{}) *MockJobProgressRecorder_SetMessage_Call {
return &MockJobProgressRecorder_SetMessage_Call{Call: _e.mock.On("SetMessage", ctx, msg)}
}
func (_c *MockJobProgressRecorder_SetMessage_Call) Run(run func(ctx context.Context, msg string)) *MockJobProgressRecorder_SetMessage_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockJobProgressRecorder_SetMessage_Call) Return() *MockJobProgressRecorder_SetMessage_Call {
_c.Call.Return()
return _c
}
func (_c *MockJobProgressRecorder_SetMessage_Call) RunAndReturn(run func(context.Context, string)) *MockJobProgressRecorder_SetMessage_Call {
_c.Run(run)
return _c
}
// SetRef provides a mock function with given fields: ref
func (_m *MockJobProgressRecorder) SetRef(ref string) {
_m.Called(ref)
}
// MockJobProgressRecorder_SetRef_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetRef'
type MockJobProgressRecorder_SetRef_Call struct {
*mock.Call
}
// SetRef is a helper method to define mock.On call
// - ref string
func (_e *MockJobProgressRecorder_Expecter) SetRef(ref interface{}) *MockJobProgressRecorder_SetRef_Call {
return &MockJobProgressRecorder_SetRef_Call{Call: _e.mock.On("SetRef", ref)}
}
func (_c *MockJobProgressRecorder_SetRef_Call) Run(run func(ref string)) *MockJobProgressRecorder_SetRef_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockJobProgressRecorder_SetRef_Call) Return() *MockJobProgressRecorder_SetRef_Call {
_c.Call.Return()
return _c
}
func (_c *MockJobProgressRecorder_SetRef_Call) RunAndReturn(run func(string)) *MockJobProgressRecorder_SetRef_Call {
_c.Run(run)
return _c
}
// SetTotal provides a mock function with given fields: ctx, total
func (_m *MockJobProgressRecorder) SetTotal(ctx context.Context, total int) {
_m.Called(ctx, total)
}
// MockJobProgressRecorder_SetTotal_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetTotal'
type MockJobProgressRecorder_SetTotal_Call struct {
*mock.Call
}
// SetTotal is a helper method to define mock.On call
// - ctx context.Context
// - total int
func (_e *MockJobProgressRecorder_Expecter) SetTotal(ctx interface{}, total interface{}) *MockJobProgressRecorder_SetTotal_Call {
return &MockJobProgressRecorder_SetTotal_Call{Call: _e.mock.On("SetTotal", ctx, total)}
}
func (_c *MockJobProgressRecorder_SetTotal_Call) Run(run func(ctx context.Context, total int)) *MockJobProgressRecorder_SetTotal_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(int))
})
return _c
}
func (_c *MockJobProgressRecorder_SetTotal_Call) Return() *MockJobProgressRecorder_SetTotal_Call {
_c.Call.Return()
return _c
}
func (_c *MockJobProgressRecorder_SetTotal_Call) RunAndReturn(run func(context.Context, int)) *MockJobProgressRecorder_SetTotal_Call {
_c.Run(run)
return _c
}
// TooManyErrors provides a mock function with no fields
func (_m *MockJobProgressRecorder) TooManyErrors() error {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for TooManyErrors")
}
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// MockJobProgressRecorder_TooManyErrors_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TooManyErrors'
type MockJobProgressRecorder_TooManyErrors_Call struct {
*mock.Call
}
// TooManyErrors is a helper method to define mock.On call
func (_e *MockJobProgressRecorder_Expecter) TooManyErrors() *MockJobProgressRecorder_TooManyErrors_Call {
return &MockJobProgressRecorder_TooManyErrors_Call{Call: _e.mock.On("TooManyErrors")}
}
func (_c *MockJobProgressRecorder_TooManyErrors_Call) Run(run func()) *MockJobProgressRecorder_TooManyErrors_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockJobProgressRecorder_TooManyErrors_Call) Return(_a0 error) *MockJobProgressRecorder_TooManyErrors_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockJobProgressRecorder_TooManyErrors_Call) RunAndReturn(run func() error) *MockJobProgressRecorder_TooManyErrors_Call {
_c.Call.Return(run)
return _c
}
// NewMockJobProgressRecorder creates a new instance of MockJobProgressRecorder. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockJobProgressRecorder(t interface {
mock.TestingT
Cleanup(func())
}) *MockJobProgressRecorder {
mock := &MockJobProgressRecorder{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -19,7 +19,7 @@ const maxFolders = 10000
var _ resource.BulkResourceWriter = (*legacyFolderReader)(nil)
type legacyFolderReader struct {
tree *resources.FolderTree
tree resources.FolderTree
repoName string
legacyMigrator legacy.LegacyMigrator
namespace string
@@ -68,6 +68,6 @@ func (f *legacyFolderReader) Read(ctx context.Context, legacyMigrator legacy.Leg
return err
}
func (f *legacyFolderReader) Tree() *resources.FolderTree {
func (f *legacyFolderReader) Tree() resources.FolderTree {
return f.tree
}
@@ -21,7 +21,7 @@ var _ resource.BulkResourceWriter = (*legacyResourceResourceMigrator)(nil)
// TODO: can we use the same migrator for folders?
type legacyResourceResourceMigrator struct {
legacy legacy.LegacyMigrator
parser *resources.Parser
parser resources.Parser
progress jobs.JobProgressRecorder
namespace string
kind schema.GroupResource
@@ -29,7 +29,7 @@ type legacyResourceResourceMigrator struct {
resources *resources.ResourcesManager
}
func NewLegacyResourceMigrator(legacy legacy.LegacyMigrator, parser *resources.Parser, resources *resources.ResourcesManager, progress jobs.JobProgressRecorder, options provisioning.MigrateJobOptions, namespace string, kind schema.GroupResource) *legacyResourceResourceMigrator {
func NewLegacyResourceMigrator(legacy legacy.LegacyMigrator, parser resources.Parser, resources *resources.ResourcesManager, progress jobs.JobProgressRecorder, options provisioning.MigrateJobOptions, namespace string, kind schema.GroupResource) *legacyResourceResourceMigrator {
return &legacyResourceResourceMigrator{
legacy: legacy,
parser: parser,
@@ -13,8 +13,8 @@ import (
const maxUsers = 10000
func loadUsers(ctx context.Context, parser *resources.Parser) (map[string]repository.CommitSignature, error) {
client, err := parser.Clients().User()
func loadUsers(ctx context.Context, clients resources.ResourceClients) (map[string]repository.CommitSignature, error) {
client, err := clients.User()
if err != nil {
return nil, err
}
@@ -15,8 +15,6 @@ import (
provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs/export"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs/sync"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
"github.com/grafana/grafana/pkg/storage/legacysql/dualwrite"
@@ -25,7 +23,9 @@ import (
type MigrationWorker struct {
// temporary... while we still do an import
parsers *resources.ParserFactory
parsers resources.ParserFactory
clients resources.ClientFactory
// Check where values are currently saved
storageStatus dualwrite.Service
@@ -37,22 +37,24 @@ type MigrationWorker struct {
bulk resource.BulkStoreClient
// Delegate the export to the export worker
exportWorker *export.ExportWorker
exportWorker jobs.Worker
// Delegate the import to sync worker
syncWorker *sync.SyncWorker
syncWorker jobs.Worker
}
func NewMigrationWorker(
legacyMigrator legacy.LegacyMigrator,
parsers *resources.ParserFactory, // should not be necessary!
parsers resources.ParserFactory, // should not be necessary!
clients resources.ClientFactory,
storageStatus dualwrite.Service,
batch resource.BulkStoreClient,
exportWorker *export.ExportWorker,
syncWorker *sync.SyncWorker,
exportWorker jobs.Worker,
syncWorker jobs.Worker,
) *MigrationWorker {
return &MigrationWorker{
parsers,
clients,
storageStatus,
legacyMigrator,
batch,
@@ -82,15 +84,20 @@ func (w *MigrationWorker) Process(ctx context.Context, repo repository.Repositor
return fmt.Errorf("error getting parser: %w", err)
}
if dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, w.storageStatus) {
return w.migrateFromLegacy(ctx, rw, parser, *options, progress)
clients, err := w.clients.Clients(ctx, rw.Config().Namespace)
if err != nil {
return fmt.Errorf("error getting clients: %w", err)
}
return w.migrateFromAPIServer(ctx, rw, parser, *options, progress)
if dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, w.storageStatus) {
return w.migrateFromLegacy(ctx, rw, parser, clients, *options, progress)
}
return w.migrateFromAPIServer(ctx, rw, clients, *options, progress)
}
// migrateFromLegacy will export the resources from legacy storage and import them into the target repository
func (w *MigrationWorker) migrateFromLegacy(ctx context.Context, rw repository.ReaderWriter, parser *resources.Parser, options provisioning.MigrateJobOptions, progress jobs.JobProgressRecorder) error {
func (w *MigrationWorker) migrateFromLegacy(ctx context.Context, rw repository.ReaderWriter, parser resources.Parser, clients resources.ResourceClients, options provisioning.MigrateJobOptions, progress jobs.JobProgressRecorder) error {
var (
err error
clone repository.ClonedRepository
@@ -128,7 +135,7 @@ func (w *MigrationWorker) migrateFromLegacy(ctx context.Context, rw repository.R
var userInfo map[string]repository.CommitSignature
if options.History {
progress.SetMessage(ctx, "loading users")
userInfo, err = loadUsers(ctx, parser)
userInfo, err = loadUsers(ctx, clients)
if err != nil {
return fmt.Errorf("error loading users: %w", err)
}
@@ -141,7 +148,7 @@ func (w *MigrationWorker) migrateFromLegacy(ctx context.Context, rw repository.R
return fmt.Errorf("error loading folder tree: %w", err)
}
folderClient, err := parser.Clients().Folder()
folderClient, err := clients.Folder()
if err != nil {
return fmt.Errorf("error getting folder client: %w", err)
}
@@ -170,7 +177,7 @@ func (w *MigrationWorker) migrateFromLegacy(ctx context.Context, rw repository.R
}
progress.SetMessage(ctx, "exporting legacy resources")
resourceManager := resources.NewResourcesManager(rw, folders, parser, parser.Clients(), userInfo)
resourceManager := resources.NewResourcesManager(rw, folders, parser, clients, userInfo)
for _, kind := range resources.SupportedProvisioningResources {
if kind == resources.FolderResource {
continue
@@ -230,7 +237,7 @@ func (w *MigrationWorker) migrateFromLegacy(ctx context.Context, rw repository.R
}
// migrateFromAPIServer will export the resources from unified storage and import them into the target repository
func (w *MigrationWorker) migrateFromAPIServer(ctx context.Context, repo repository.ReaderWriter, parser *resources.Parser, options provisioning.MigrateJobOptions, progress jobs.JobProgressRecorder) error {
func (w *MigrationWorker) migrateFromAPIServer(ctx context.Context, repo repository.ReaderWriter, clients resources.ResourceClients, options provisioning.MigrateJobOptions, progress jobs.JobProgressRecorder) error {
progress.SetMessage(ctx, "exporting unified storage resources")
exportJob := provisioning.Job{
Spec: provisioning.JobSpec{
@@ -259,7 +266,7 @@ func (w *MigrationWorker) migrateFromAPIServer(ctx context.Context, repo reposit
for _, kind := range resources.SupportedProvisioningResources {
progress.SetMessage(ctx, fmt.Sprintf("removing unprovisioned %s", kind.Resource))
client, _, err := parser.Clients().ForResource(kind)
client, _, err := clients.ForResource(kind)
if err != nil {
return err
}
@@ -55,6 +55,9 @@ var (
}
)
// Queue is a job queue abstraction.
//
//go:generate mockery --name Queue --structname MockQueue --inpackage --filename queue_mock.go --with-expecter
type Queue interface {
// Insert adds a new job to the queue.
//
@@ -0,0 +1,84 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
mock "github.com/stretchr/testify/mock"
)
// MockProgressFn is an autogenerated mock type for the ProgressFn type
type MockProgressFn struct {
mock.Mock
}
type MockProgressFn_Expecter struct {
mock *mock.Mock
}
func (_m *MockProgressFn) EXPECT() *MockProgressFn_Expecter {
return &MockProgressFn_Expecter{mock: &_m.Mock}
}
// Execute provides a mock function with given fields: ctx, status
func (_m *MockProgressFn) Execute(ctx context.Context, status v0alpha1.JobStatus) error {
ret := _m.Called(ctx, status)
if len(ret) == 0 {
panic("no return value specified for Execute")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, v0alpha1.JobStatus) error); ok {
r0 = rf(ctx, status)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockProgressFn_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute'
type MockProgressFn_Execute_Call struct {
*mock.Call
}
// Execute is a helper method to define mock.On call
// - ctx context.Context
// - status v0alpha1.JobStatus
func (_e *MockProgressFn_Expecter) Execute(ctx interface{}, status interface{}) *MockProgressFn_Execute_Call {
return &MockProgressFn_Execute_Call{Call: _e.mock.On("Execute", ctx, status)}
}
func (_c *MockProgressFn_Execute_Call) Run(run func(ctx context.Context, status v0alpha1.JobStatus)) *MockProgressFn_Execute_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(v0alpha1.JobStatus))
})
return _c
}
func (_c *MockProgressFn_Execute_Call) Return(_a0 error) *MockProgressFn_Execute_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockProgressFn_Execute_Call) RunAndReturn(run func(context.Context, v0alpha1.JobStatus) error) *MockProgressFn_Execute_Call {
_c.Call.Return(run)
return _c
}
// NewMockProgressFn creates a new instance of MockProgressFn. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockProgressFn(t interface {
mock.TestingT
Cleanup(func())
}) *MockProgressFn {
mock := &MockProgressFn{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -50,19 +50,29 @@ See the [preview]({{.PreviewURL}}) of {{.Filename}}.
{{- end}}`
// PreviewRenderer is an interface for rendering a preview of a file
//
//go:generate mockery --name PreviewRenderer --structname MockPreviewRenderer --inpackage --filename preview_renderer_mock.go --with-expecter
type PreviewRenderer interface {
IsAvailable(ctx context.Context) bool
RenderDashboardPreview(ctx context.Context, namespace, repoName, path, ref string) (string, error)
}
type Previewer struct {
// Previewer is a service for previewing dashboard changes in a pull request
//
//go:generate mockery --name Previewer --structname MockPreviewer --inpackage --filename previewer_mock.go --with-expecter
type Previewer interface {
Preview(ctx context.Context, f repository.VersionedFileChange, namespace, repoName, base, ref, pullRequestURL string, generatePreview bool) (resourcePreview, error)
GenerateComment(preview resourcePreview) (string, error)
}
type previewer struct {
template *template.Template
urlProvider func(namespace string) string
renderer PreviewRenderer
}
func NewPreviewer(renderer PreviewRenderer, urlProvider func(namespace string) string) *Previewer {
return &Previewer{
func NewPreviewer(renderer PreviewRenderer, urlProvider func(namespace string) string) *previewer {
return &previewer{
template: template.Must(template.New("comment").Parse(previewsCommentTemplate)),
urlProvider: urlProvider,
renderer: renderer,
@@ -70,7 +80,7 @@ func NewPreviewer(renderer PreviewRenderer, urlProvider func(namespace string) s
}
// GenerateComment creates a formatted comment for dashboard previews
func (p *Previewer) GenerateComment(preview resourcePreview) (string, error) {
func (p *previewer) GenerateComment(preview resourcePreview) (string, error) {
var buf bytes.Buffer
if err := p.template.Execute(&buf, preview); err != nil {
return "", fmt.Errorf("execute previews comment template: %w", err)
@@ -79,7 +89,7 @@ func (p *Previewer) GenerateComment(preview resourcePreview) (string, error) {
}
// getOriginalURL returns the URL for the original version of the file based on the action
func (p *Previewer) getOriginalURL(ctx context.Context, f repository.VersionedFileChange, baseURL *url.URL, repoName, base, pullRequestURL string) string {
func (p *previewer) getOriginalURL(ctx context.Context, f repository.VersionedFileChange, baseURL *url.URL, repoName, base, pullRequestURL string) string {
switch f.Action {
case repository.FileActionCreated:
return "" // No original URL for new files
@@ -96,7 +106,7 @@ func (p *Previewer) getOriginalURL(ctx context.Context, f repository.VersionedFi
}
// getPreviewURL returns the URL for the preview version of the file based on the action
func (p *Previewer) getPreviewURL(ctx context.Context, f repository.VersionedFileChange, baseURL *url.URL, repoName, ref, pullRequestURL string) string {
func (p *previewer) getPreviewURL(ctx context.Context, f repository.VersionedFileChange, baseURL *url.URL, repoName, ref, pullRequestURL string) string {
switch f.Action {
case repository.FileActionCreated, repository.FileActionUpdated, repository.FileActionRenamed:
return p.previewURL(baseURL, repoName, ref, f.Path, pullRequestURL)
@@ -109,7 +119,7 @@ func (p *Previewer) getPreviewURL(ctx context.Context, f repository.VersionedFil
}
// previewURL returns the URL to preview the file in Grafana
func (p *Previewer) previewURL(u *url.URL, repoName, ref, filePath, pullRequestURL string) string {
func (p *previewer) previewURL(u *url.URL, repoName, ref, filePath, pullRequestURL string) string {
baseURL := *u
baseURL = *baseURL.JoinPath("/admin/provisioning", repoName, "dashboard/preview", filePath)
@@ -126,7 +136,7 @@ func (p *Previewer) previewURL(u *url.URL, repoName, ref, filePath, pullRequestU
}
// Preview creates a preview for a single file change
func (p *Previewer) Preview(
func (p *previewer) Preview(
ctx context.Context,
f repository.VersionedFileChange,
namespace string,
@@ -0,0 +1,142 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package pullrequest
import (
context "context"
mock "github.com/stretchr/testify/mock"
)
// MockPreviewRenderer is an autogenerated mock type for the PreviewRenderer type
type MockPreviewRenderer struct {
mock.Mock
}
type MockPreviewRenderer_Expecter struct {
mock *mock.Mock
}
func (_m *MockPreviewRenderer) EXPECT() *MockPreviewRenderer_Expecter {
return &MockPreviewRenderer_Expecter{mock: &_m.Mock}
}
// IsAvailable provides a mock function with given fields: ctx
func (_m *MockPreviewRenderer) IsAvailable(ctx context.Context) bool {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for IsAvailable")
}
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context) bool); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockPreviewRenderer_IsAvailable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsAvailable'
type MockPreviewRenderer_IsAvailable_Call struct {
*mock.Call
}
// IsAvailable is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockPreviewRenderer_Expecter) IsAvailable(ctx interface{}) *MockPreviewRenderer_IsAvailable_Call {
return &MockPreviewRenderer_IsAvailable_Call{Call: _e.mock.On("IsAvailable", ctx)}
}
func (_c *MockPreviewRenderer_IsAvailable_Call) Run(run func(ctx context.Context)) *MockPreviewRenderer_IsAvailable_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *MockPreviewRenderer_IsAvailable_Call) Return(_a0 bool) *MockPreviewRenderer_IsAvailable_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockPreviewRenderer_IsAvailable_Call) RunAndReturn(run func(context.Context) bool) *MockPreviewRenderer_IsAvailable_Call {
_c.Call.Return(run)
return _c
}
// RenderDashboardPreview provides a mock function with given fields: ctx, namespace, repoName, path, ref
func (_m *MockPreviewRenderer) RenderDashboardPreview(ctx context.Context, namespace string, repoName string, path string, ref string) (string, error) {
ret := _m.Called(ctx, namespace, repoName, path, ref)
if len(ret) == 0 {
panic("no return value specified for RenderDashboardPreview")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) (string, error)); ok {
return rf(ctx, namespace, repoName, path, ref)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) string); ok {
r0 = rf(ctx, namespace, repoName, path, ref)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string) error); ok {
r1 = rf(ctx, namespace, repoName, path, ref)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockPreviewRenderer_RenderDashboardPreview_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RenderDashboardPreview'
type MockPreviewRenderer_RenderDashboardPreview_Call struct {
*mock.Call
}
// RenderDashboardPreview is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
// - repoName string
// - path string
// - ref string
func (_e *MockPreviewRenderer_Expecter) RenderDashboardPreview(ctx interface{}, namespace interface{}, repoName interface{}, path interface{}, ref interface{}) *MockPreviewRenderer_RenderDashboardPreview_Call {
return &MockPreviewRenderer_RenderDashboardPreview_Call{Call: _e.mock.On("RenderDashboardPreview", ctx, namespace, repoName, path, ref)}
}
func (_c *MockPreviewRenderer_RenderDashboardPreview_Call) Run(run func(ctx context.Context, namespace string, repoName string, path string, ref string)) *MockPreviewRenderer_RenderDashboardPreview_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string), args[4].(string))
})
return _c
}
func (_c *MockPreviewRenderer_RenderDashboardPreview_Call) Return(_a0 string, _a1 error) *MockPreviewRenderer_RenderDashboardPreview_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockPreviewRenderer_RenderDashboardPreview_Call) RunAndReturn(run func(context.Context, string, string, string, string) (string, error)) *MockPreviewRenderer_RenderDashboardPreview_Call {
_c.Call.Return(run)
return _c
}
// NewMockPreviewRenderer creates a new instance of MockPreviewRenderer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockPreviewRenderer(t interface {
mock.TestingT
Cleanup(func())
}) *MockPreviewRenderer {
mock := &MockPreviewRenderer{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -0,0 +1,156 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package pullrequest
import (
context "context"
repository "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
mock "github.com/stretchr/testify/mock"
)
// MockPreviewer is an autogenerated mock type for the Previewer type
type MockPreviewer struct {
mock.Mock
}
type MockPreviewer_Expecter struct {
mock *mock.Mock
}
func (_m *MockPreviewer) EXPECT() *MockPreviewer_Expecter {
return &MockPreviewer_Expecter{mock: &_m.Mock}
}
// GenerateComment provides a mock function with given fields: preview
func (_m *MockPreviewer) GenerateComment(preview resourcePreview) (string, error) {
ret := _m.Called(preview)
if len(ret) == 0 {
panic("no return value specified for GenerateComment")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(resourcePreview) (string, error)); ok {
return rf(preview)
}
if rf, ok := ret.Get(0).(func(resourcePreview) string); ok {
r0 = rf(preview)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(resourcePreview) error); ok {
r1 = rf(preview)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockPreviewer_GenerateComment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenerateComment'
type MockPreviewer_GenerateComment_Call struct {
*mock.Call
}
// GenerateComment is a helper method to define mock.On call
// - preview resourcePreview
func (_e *MockPreviewer_Expecter) GenerateComment(preview interface{}) *MockPreviewer_GenerateComment_Call {
return &MockPreviewer_GenerateComment_Call{Call: _e.mock.On("GenerateComment", preview)}
}
func (_c *MockPreviewer_GenerateComment_Call) Run(run func(preview resourcePreview)) *MockPreviewer_GenerateComment_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(resourcePreview))
})
return _c
}
func (_c *MockPreviewer_GenerateComment_Call) Return(_a0 string, _a1 error) *MockPreviewer_GenerateComment_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockPreviewer_GenerateComment_Call) RunAndReturn(run func(resourcePreview) (string, error)) *MockPreviewer_GenerateComment_Call {
_c.Call.Return(run)
return _c
}
// Preview provides a mock function with given fields: ctx, f, namespace, repoName, base, ref, pullRequestURL, generatePreview
func (_m *MockPreviewer) Preview(ctx context.Context, f repository.VersionedFileChange, namespace string, repoName string, base string, ref string, pullRequestURL string, generatePreview bool) (resourcePreview, error) {
ret := _m.Called(ctx, f, namespace, repoName, base, ref, pullRequestURL, generatePreview)
if len(ret) == 0 {
panic("no return value specified for Preview")
}
var r0 resourcePreview
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, repository.VersionedFileChange, string, string, string, string, string, bool) (resourcePreview, error)); ok {
return rf(ctx, f, namespace, repoName, base, ref, pullRequestURL, generatePreview)
}
if rf, ok := ret.Get(0).(func(context.Context, repository.VersionedFileChange, string, string, string, string, string, bool) resourcePreview); ok {
r0 = rf(ctx, f, namespace, repoName, base, ref, pullRequestURL, generatePreview)
} else {
r0 = ret.Get(0).(resourcePreview)
}
if rf, ok := ret.Get(1).(func(context.Context, repository.VersionedFileChange, string, string, string, string, string, bool) error); ok {
r1 = rf(ctx, f, namespace, repoName, base, ref, pullRequestURL, generatePreview)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockPreviewer_Preview_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Preview'
type MockPreviewer_Preview_Call struct {
*mock.Call
}
// Preview is a helper method to define mock.On call
// - ctx context.Context
// - f repository.VersionedFileChange
// - namespace string
// - repoName string
// - base string
// - ref string
// - pullRequestURL string
// - generatePreview bool
func (_e *MockPreviewer_Expecter) Preview(ctx interface{}, f interface{}, namespace interface{}, repoName interface{}, base interface{}, ref interface{}, pullRequestURL interface{}, generatePreview interface{}) *MockPreviewer_Preview_Call {
return &MockPreviewer_Preview_Call{Call: _e.mock.On("Preview", ctx, f, namespace, repoName, base, ref, pullRequestURL, generatePreview)}
}
func (_c *MockPreviewer_Preview_Call) Run(run func(ctx context.Context, f repository.VersionedFileChange, namespace string, repoName string, base string, ref string, pullRequestURL string, generatePreview bool)) *MockPreviewer_Preview_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(repository.VersionedFileChange), args[2].(string), args[3].(string), args[4].(string), args[5].(string), args[6].(string), args[7].(bool))
})
return _c
}
func (_c *MockPreviewer_Preview_Call) Return(_a0 resourcePreview, _a1 error) *MockPreviewer_Preview_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockPreviewer_Preview_Call) RunAndReturn(run func(context.Context, repository.VersionedFileChange, string, string, string, string, string, bool) (resourcePreview, error)) *MockPreviewer_Preview_Call {
_c.Call.Return(run)
return _c
}
// NewMockPreviewer creates a new instance of MockPreviewer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockPreviewer(t interface {
mock.TestingT
Cleanup(func())
}) *MockPreviewer {
mock := &MockPreviewer{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -24,18 +24,18 @@ type PullRequestRepo interface {
}
type PullRequestWorker struct {
parsers *resources.ParserFactory
previewer *Previewer
parsers resources.ParserFactory
previewer Previewer
}
func NewPullRequestWorker(
parsers *resources.ParserFactory,
previewer *Previewer,
) (*PullRequestWorker, error) {
parsers resources.ParserFactory,
previewer Previewer,
) *PullRequestWorker {
return &PullRequestWorker{
parsers: parsers,
previewer: previewer,
}, nil
}
}
func (c *PullRequestWorker) IsSupported(ctx context.Context, job provisioning.Job) bool {
@@ -7,10 +7,16 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
)
// RepoGetter is a function that can be called to get a repository by name
//
//go:generate mockery --name RepoGetter --structname MockRepoGetter --inpackage --filename repo_getter_mock.go --with-expecter
type RepoGetter interface {
GetRepository(ctx context.Context, name string) (repository.Repository, error)
}
// JobProgressRecorder is a function that can be called to record the progress of a job
//
//go:generate mockery --name JobProgressRecorder --structname MockJobProgressRecorder --inpackage --filename job_progress_recorder_mock.go --with-expecter
type JobProgressRecorder interface {
Record(ctx context.Context, result JobResourceResult)
ResetResults()
@@ -23,6 +29,9 @@ type JobProgressRecorder interface {
Complete(ctx context.Context, err error) provisioning.JobStatus
}
// Worker is a worker that can process a job
//
//go:generate mockery --name Worker --structname MockWorker --inpackage --filename worker_mock.go --with-expecter
type Worker interface {
IsSupported(ctx context.Context, job provisioning.Job) bool
// Process the job. The job status should be updated as the job progresses.
@@ -32,4 +41,6 @@ type Worker interface {
}
// ProgressFn is a function that can be called to update the progress of a job
//
//go:generate mockery --name ProgressFn --structname MockProgressFn --inpackage --filename progress_fn_mock.go --with-expecter
type ProgressFn func(ctx context.Context, status provisioning.JobStatus) error
@@ -0,0 +1,97 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
mock "github.com/stretchr/testify/mock"
)
// MockQueue is an autogenerated mock type for the Queue type
type MockQueue struct {
mock.Mock
}
type MockQueue_Expecter struct {
mock *mock.Mock
}
func (_m *MockQueue) EXPECT() *MockQueue_Expecter {
return &MockQueue_Expecter{mock: &_m.Mock}
}
// Insert provides a mock function with given fields: ctx, namespace, spec
func (_m *MockQueue) Insert(ctx context.Context, namespace string, spec v0alpha1.JobSpec) (*v0alpha1.Job, error) {
ret := _m.Called(ctx, namespace, spec)
if len(ret) == 0 {
panic("no return value specified for Insert")
}
var r0 *v0alpha1.Job
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, v0alpha1.JobSpec) (*v0alpha1.Job, error)); ok {
return rf(ctx, namespace, spec)
}
if rf, ok := ret.Get(0).(func(context.Context, string, v0alpha1.JobSpec) *v0alpha1.Job); ok {
r0 = rf(ctx, namespace, spec)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.Job)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, v0alpha1.JobSpec) error); ok {
r1 = rf(ctx, namespace, spec)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockQueue_Insert_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Insert'
type MockQueue_Insert_Call struct {
*mock.Call
}
// Insert is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
// - spec v0alpha1.JobSpec
func (_e *MockQueue_Expecter) Insert(ctx interface{}, namespace interface{}, spec interface{}) *MockQueue_Insert_Call {
return &MockQueue_Insert_Call{Call: _e.mock.On("Insert", ctx, namespace, spec)}
}
func (_c *MockQueue_Insert_Call) Run(run func(ctx context.Context, namespace string, spec v0alpha1.JobSpec)) *MockQueue_Insert_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(v0alpha1.JobSpec))
})
return _c
}
func (_c *MockQueue_Insert_Call) Return(_a0 *v0alpha1.Job, _a1 error) *MockQueue_Insert_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockQueue_Insert_Call) RunAndReturn(run func(context.Context, string, v0alpha1.JobSpec) (*v0alpha1.Job, error)) *MockQueue_Insert_Call {
_c.Call.Return(run)
return _c
}
// NewMockQueue creates a new instance of MockQueue. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockQueue(t interface {
mock.TestingT
Cleanup(func())
}) *MockQueue {
mock := &MockQueue{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -0,0 +1,96 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
repository "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
mock "github.com/stretchr/testify/mock"
)
// MockRepoGetter is an autogenerated mock type for the RepoGetter type
type MockRepoGetter struct {
mock.Mock
}
type MockRepoGetter_Expecter struct {
mock *mock.Mock
}
func (_m *MockRepoGetter) EXPECT() *MockRepoGetter_Expecter {
return &MockRepoGetter_Expecter{mock: &_m.Mock}
}
// GetRepository provides a mock function with given fields: ctx, name
func (_m *MockRepoGetter) GetRepository(ctx context.Context, name string) (repository.Repository, error) {
ret := _m.Called(ctx, name)
if len(ret) == 0 {
panic("no return value specified for GetRepository")
}
var r0 repository.Repository
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (repository.Repository, error)); ok {
return rf(ctx, name)
}
if rf, ok := ret.Get(0).(func(context.Context, string) repository.Repository); ok {
r0 = rf(ctx, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(repository.Repository)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockRepoGetter_GetRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepository'
type MockRepoGetter_GetRepository_Call struct {
*mock.Call
}
// GetRepository is a helper method to define mock.On call
// - ctx context.Context
// - name string
func (_e *MockRepoGetter_Expecter) GetRepository(ctx interface{}, name interface{}) *MockRepoGetter_GetRepository_Call {
return &MockRepoGetter_GetRepository_Call{Call: _e.mock.On("GetRepository", ctx, name)}
}
func (_c *MockRepoGetter_GetRepository_Call) Run(run func(ctx context.Context, name string)) *MockRepoGetter_GetRepository_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockRepoGetter_GetRepository_Call) Return(_a0 repository.Repository, _a1 error) *MockRepoGetter_GetRepository_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockRepoGetter_GetRepository_Call) RunAndReturn(run func(context.Context, string) (repository.Repository, error)) *MockRepoGetter_GetRepository_Call {
_c.Call.Return(run)
return _c
}
// NewMockRepoGetter creates a new instance of MockRepoGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockRepoGetter(t interface {
mock.TestingT
Cleanup(func())
}) *MockRepoGetter {
mock := &MockRepoGetter{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -0,0 +1,303 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
mock "github.com/stretchr/testify/mock"
)
// MockStore is an autogenerated mock type for the Store type
type MockStore struct {
mock.Mock
}
type MockStore_Expecter struct {
mock *mock.Mock
}
func (_m *MockStore) EXPECT() *MockStore_Expecter {
return &MockStore_Expecter{mock: &_m.Mock}
}
// Claim provides a mock function with given fields: ctx
func (_m *MockStore) Claim(ctx context.Context) (*v0alpha1.Job, func(), error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for Claim")
}
var r0 *v0alpha1.Job
var r1 func()
var r2 error
if rf, ok := ret.Get(0).(func(context.Context) (*v0alpha1.Job, func(), error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) *v0alpha1.Job); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.Job)
}
}
if rf, ok := ret.Get(1).(func(context.Context) func()); ok {
r1 = rf(ctx)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(func())
}
}
if rf, ok := ret.Get(2).(func(context.Context) error); ok {
r2 = rf(ctx)
} else {
r2 = ret.Error(2)
}
return r0, r1, r2
}
// MockStore_Claim_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Claim'
type MockStore_Claim_Call struct {
*mock.Call
}
// Claim is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockStore_Expecter) Claim(ctx interface{}) *MockStore_Claim_Call {
return &MockStore_Claim_Call{Call: _e.mock.On("Claim", ctx)}
}
func (_c *MockStore_Claim_Call) Run(run func(ctx context.Context)) *MockStore_Claim_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *MockStore_Claim_Call) Return(job *v0alpha1.Job, rollback func(), err error) *MockStore_Claim_Call {
_c.Call.Return(job, rollback, err)
return _c
}
func (_c *MockStore_Claim_Call) RunAndReturn(run func(context.Context) (*v0alpha1.Job, func(), error)) *MockStore_Claim_Call {
_c.Call.Return(run)
return _c
}
// Cleanup provides a mock function with given fields: ctx
func (_m *MockStore) Cleanup(ctx context.Context) error {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for Cleanup")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context) error); ok {
r0 = rf(ctx)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockStore_Cleanup_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Cleanup'
type MockStore_Cleanup_Call struct {
*mock.Call
}
// Cleanup is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockStore_Expecter) Cleanup(ctx interface{}) *MockStore_Cleanup_Call {
return &MockStore_Cleanup_Call{Call: _e.mock.On("Cleanup", ctx)}
}
func (_c *MockStore_Cleanup_Call) Run(run func(ctx context.Context)) *MockStore_Cleanup_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *MockStore_Cleanup_Call) Return(_a0 error) *MockStore_Cleanup_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockStore_Cleanup_Call) RunAndReturn(run func(context.Context) error) *MockStore_Cleanup_Call {
_c.Call.Return(run)
return _c
}
// Complete provides a mock function with given fields: ctx, job
func (_m *MockStore) Complete(ctx context.Context, job *v0alpha1.Job) error {
ret := _m.Called(ctx, job)
if len(ret) == 0 {
panic("no return value specified for Complete")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Job) error); ok {
r0 = rf(ctx, job)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockStore_Complete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Complete'
type MockStore_Complete_Call struct {
*mock.Call
}
// Complete is a helper method to define mock.On call
// - ctx context.Context
// - job *v0alpha1.Job
func (_e *MockStore_Expecter) Complete(ctx interface{}, job interface{}) *MockStore_Complete_Call {
return &MockStore_Complete_Call{Call: _e.mock.On("Complete", ctx, job)}
}
func (_c *MockStore_Complete_Call) Run(run func(ctx context.Context, job *v0alpha1.Job)) *MockStore_Complete_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*v0alpha1.Job))
})
return _c
}
func (_c *MockStore_Complete_Call) Return(_a0 error) *MockStore_Complete_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockStore_Complete_Call) RunAndReturn(run func(context.Context, *v0alpha1.Job) error) *MockStore_Complete_Call {
_c.Call.Return(run)
return _c
}
// InsertNotifications provides a mock function with no fields
func (_m *MockStore) InsertNotifications() chan struct{} {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for InsertNotifications")
}
var r0 chan struct{}
if rf, ok := ret.Get(0).(func() chan struct{}); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(chan struct{})
}
}
return r0
}
// MockStore_InsertNotifications_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InsertNotifications'
type MockStore_InsertNotifications_Call struct {
*mock.Call
}
// InsertNotifications is a helper method to define mock.On call
func (_e *MockStore_Expecter) InsertNotifications() *MockStore_InsertNotifications_Call {
return &MockStore_InsertNotifications_Call{Call: _e.mock.On("InsertNotifications")}
}
func (_c *MockStore_InsertNotifications_Call) Run(run func()) *MockStore_InsertNotifications_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockStore_InsertNotifications_Call) Return(_a0 chan struct{}) *MockStore_InsertNotifications_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockStore_InsertNotifications_Call) RunAndReturn(run func() chan struct{}) *MockStore_InsertNotifications_Call {
_c.Call.Return(run)
return _c
}
// Update provides a mock function with given fields: ctx, job
func (_m *MockStore) Update(ctx context.Context, job *v0alpha1.Job) (*v0alpha1.Job, error) {
ret := _m.Called(ctx, job)
if len(ret) == 0 {
panic("no return value specified for Update")
}
var r0 *v0alpha1.Job
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Job) (*v0alpha1.Job, error)); ok {
return rf(ctx, job)
}
if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Job) *v0alpha1.Job); ok {
r0 = rf(ctx, job)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.Job)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *v0alpha1.Job) error); ok {
r1 = rf(ctx, job)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStore_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update'
type MockStore_Update_Call struct {
*mock.Call
}
// Update is a helper method to define mock.On call
// - ctx context.Context
// - job *v0alpha1.Job
func (_e *MockStore_Expecter) Update(ctx interface{}, job interface{}) *MockStore_Update_Call {
return &MockStore_Update_Call{Call: _e.mock.On("Update", ctx, job)}
}
func (_c *MockStore_Update_Call) Run(run func(ctx context.Context, job *v0alpha1.Job)) *MockStore_Update_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*v0alpha1.Job))
})
return _c
}
func (_c *MockStore_Update_Call) Return(_a0 *v0alpha1.Job, _a1 error) *MockStore_Update_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockStore_Update_Call) RunAndReturn(run func(context.Context, *v0alpha1.Job) (*v0alpha1.Job, error)) *MockStore_Update_Call {
_c.Call.Return(run)
return _c
}
// NewMockStore creates a new instance of MockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStore(t interface {
mock.TestingT
Cleanup(func())
}) *MockStore {
mock := &MockStore{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -30,7 +30,10 @@ type SyncWorker struct {
lister resources.ResourceLister
// Parses fields saved in remore repository
parsers *resources.ParserFactory
parsers resources.ParserFactory
// Clients for the repository
clients resources.ClientFactory
// Check if the system is using unified storage
storageStatus dualwrite.Service
@@ -38,13 +41,15 @@ type SyncWorker struct {
func NewSyncWorker(
client client.ProvisioningV0alpha1Interface,
parsers *resources.ParserFactory,
parsers resources.ParserFactory,
clients resources.ClientFactory,
lister resources.ResourceLister,
storageStatus dualwrite.Service,
) *SyncWorker {
return &SyncWorker{
client: client,
parsers: parsers,
clients: clients,
lister: lister,
storageStatus: storageStatus,
}
@@ -137,7 +142,12 @@ func (r *SyncWorker) createJob(ctx context.Context, repo repository.ReaderWriter
return nil, fmt.Errorf("failed to get parser for %s: %w", cfg.Name, err)
}
folderClient, err := parser.Clients().Folder()
clients, err := r.clients.Clients(ctx, cfg.Namespace)
if err != nil {
return nil, fmt.Errorf("failed to get clients for %s: %w", cfg.Name, err)
}
folderClient, err := clients.Folder()
if err != nil {
return nil, fmt.Errorf("unable to get folder client: %w", err)
}
@@ -148,8 +158,8 @@ func (r *SyncWorker) createJob(ctx context.Context, repo repository.ReaderWriter
progress: progress,
lister: r.lister,
folders: folders,
clients: parser.Clients(),
resourceManager: resources.NewResourcesManager(repo, folders, parser, parser.Clients(), nil),
clients: clients,
resourceManager: resources.NewResourcesManager(repo, folders, parser, clients, nil),
}
return job, nil
@@ -0,0 +1,135 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package jobs
import (
context "context"
repository "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
mock "github.com/stretchr/testify/mock"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
)
// MockWorker is an autogenerated mock type for the Worker type
type MockWorker struct {
mock.Mock
}
type MockWorker_Expecter struct {
mock *mock.Mock
}
func (_m *MockWorker) EXPECT() *MockWorker_Expecter {
return &MockWorker_Expecter{mock: &_m.Mock}
}
// IsSupported provides a mock function with given fields: ctx, job
func (_m *MockWorker) IsSupported(ctx context.Context, job v0alpha1.Job) bool {
ret := _m.Called(ctx, job)
if len(ret) == 0 {
panic("no return value specified for IsSupported")
}
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, v0alpha1.Job) bool); ok {
r0 = rf(ctx, job)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockWorker_IsSupported_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsSupported'
type MockWorker_IsSupported_Call struct {
*mock.Call
}
// IsSupported is a helper method to define mock.On call
// - ctx context.Context
// - job v0alpha1.Job
func (_e *MockWorker_Expecter) IsSupported(ctx interface{}, job interface{}) *MockWorker_IsSupported_Call {
return &MockWorker_IsSupported_Call{Call: _e.mock.On("IsSupported", ctx, job)}
}
func (_c *MockWorker_IsSupported_Call) Run(run func(ctx context.Context, job v0alpha1.Job)) *MockWorker_IsSupported_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(v0alpha1.Job))
})
return _c
}
func (_c *MockWorker_IsSupported_Call) Return(_a0 bool) *MockWorker_IsSupported_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockWorker_IsSupported_Call) RunAndReturn(run func(context.Context, v0alpha1.Job) bool) *MockWorker_IsSupported_Call {
_c.Call.Return(run)
return _c
}
// Process provides a mock function with given fields: ctx, repo, job, progress
func (_m *MockWorker) Process(ctx context.Context, repo repository.Repository, job v0alpha1.Job, progress JobProgressRecorder) error {
ret := _m.Called(ctx, repo, job, progress)
if len(ret) == 0 {
panic("no return value specified for Process")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, repository.Repository, v0alpha1.Job, JobProgressRecorder) error); ok {
r0 = rf(ctx, repo, job, progress)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockWorker_Process_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Process'
type MockWorker_Process_Call struct {
*mock.Call
}
// Process is a helper method to define mock.On call
// - ctx context.Context
// - repo repository.Repository
// - job v0alpha1.Job
// - progress JobProgressRecorder
func (_e *MockWorker_Expecter) Process(ctx interface{}, repo interface{}, job interface{}, progress interface{}) *MockWorker_Process_Call {
return &MockWorker_Process_Call{Call: _e.mock.On("Process", ctx, repo, job, progress)}
}
func (_c *MockWorker_Process_Call) Run(run func(ctx context.Context, repo repository.Repository, job v0alpha1.Job, progress JobProgressRecorder)) *MockWorker_Process_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(repository.Repository), args[2].(v0alpha1.Job), args[3].(JobProgressRecorder))
})
return _c
}
func (_c *MockWorker_Process_Call) Return(_a0 error) *MockWorker_Process_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockWorker_Process_Call) RunAndReturn(run func(context.Context, repository.Repository, v0alpha1.Job, JobProgressRecorder) error) *MockWorker_Process_Call {
_c.Call.Return(run)
return _c
}
// NewMockWorker creates a new instance of MockWorker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockWorker(t interface {
mock.TestingT
Cleanup(func())
}) *MockWorker {
mock := &MockWorker{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+18 -20
View File
@@ -80,7 +80,8 @@ type APIBuilder struct {
getter rest.Getter
localFileResolver *repository.LocalFolderResolver
render rendering.Service
parsers *resources.ParserFactory
parsers resources.ParserFactory
clients resources.ClientFactory
ghFactory *github.Factory
clonedir string // where repo clones are managed
jobs interface {
@@ -117,6 +118,7 @@ func NewAPIBuilder(
) *APIBuilder {
// HACK: Assume is only public if it is HTTPS
isPublic := strings.HasPrefix(urlProvider(""), "https://")
clients := resources.NewClientFactory(configProvider)
return &APIBuilder{
urlProvider: urlProvider,
@@ -125,16 +127,15 @@ func NewAPIBuilder(
isPublic: isPublic,
features: features,
ghFactory: ghFactory,
parsers: &resources.ParserFactory{
ClientFactory: resources.NewClientFactory(configProvider),
},
render: render,
clonedir: clonedir,
resourceLister: resources.NewResourceLister(unified, unified, legacyMigrator, storageStatus),
legacyMigrator: legacyMigrator,
storageStatus: storageStatus,
unified: unified,
secrets: secrets,
clients: clients,
parsers: resources.NewParserFactory(clients),
render: render,
clonedir: clonedir,
resourceLister: resources.NewResourceLister(unified, unified, legacyMigrator, storageStatus),
legacyMigrator: legacyMigrator,
storageStatus: storageStatus,
unified: unified,
secrets: secrets,
}
}
@@ -367,10 +368,7 @@ func (b *APIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupI
storage[provisioning.RepositoryResourceInfo.StoragePath("test")] = &testConnector{
getter: b,
}
storage[provisioning.RepositoryResourceInfo.StoragePath("files")] = &filesConnector{
getter: b,
parsers: b.parsers,
}
storage[provisioning.RepositoryResourceInfo.StoragePath("files")] = NewFilesConnector(b, b.parsers, b.clients)
storage[provisioning.RepositoryResourceInfo.StoragePath("resources")] = &listConnector{
getter: b,
lister: b.resourceLister,
@@ -562,19 +560,21 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH
b.repositoryLister = repoInformer.Lister()
exportWorker := export.NewExportWorker(
b.parsers.ClientFactory,
b.clients,
b.storageStatus,
b.parsers,
)
syncWorker := sync.NewSyncWorker(
b.GetClient(),
b.parsers,
b.clients,
b.resourceLister,
b.storageStatus,
)
migrationWorker := migrate.NewMigrationWorker(
b.legacyMigrator,
b.parsers,
b.clients,
b.storageStatus,
b.unified,
exportWorker,
@@ -584,10 +584,7 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH
// Pull request worker
renderer := pullrequest.NewScreenshotRenderer(b.render, b.unified, b.isPublic, b.urlProvider)
previewer := pullrequest.NewPreviewer(renderer, b.urlProvider)
pullRequestWorker, err := pullrequest.NewPullRequestWorker(b.parsers, previewer)
if err != nil {
return fmt.Errorf("create pull request worker: %w", err)
}
pullRequestWorker := pullrequest.NewPullRequestWorker(b.parsers, previewer)
driver := jobs.NewJobDriver(time.Second*28, time.Second*30, time.Second*30, b.jobs, b, b.jobHistory,
exportWorker, syncWorker, migrationWorker, pullRequestWorker)
@@ -599,6 +596,7 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH
b, // repoGetter
b.resourceLister,
b.parsers,
b.clients,
&repository.Tester{},
b.jobs,
b.secrets,
@@ -26,7 +26,14 @@ var (
SupportedProvisioningResources = []schema.GroupVersionResource{FolderResource, DashboardResource}
)
type ClientFactory struct {
// ClientFactory is a factory for creating clients for a given namespace
//
//go:generate mockery --name ClientFactory --structname MockClientFactory --inpackage --filename client_factory_mock.go --with-expecter
type ClientFactory interface {
Clients(ctx context.Context, namespace string) (ResourceClients, error)
}
type clientFactory struct {
configProvider apiserver.RestConfigProvider
}
@@ -41,11 +48,11 @@ type ResourceClients interface {
User() (dynamic.ResourceInterface, error)
}
func NewClientFactory(configProvider apiserver.RestConfigProvider) *ClientFactory {
return &ClientFactory{configProvider}
func NewClientFactory(configProvider apiserver.RestConfigProvider) ClientFactory {
return &clientFactory{configProvider}
}
func (f *ClientFactory) Clients(ctx context.Context, namespace string) (ResourceClients, error) {
func (f *clientFactory) Clients(ctx context.Context, namespace string) (ResourceClients, error) {
restConfig, err := f.configProvider.GetRestConfig(ctx)
if err != nil {
return nil, err
@@ -0,0 +1,95 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package resources
import (
context "context"
mock "github.com/stretchr/testify/mock"
)
// MockClientFactory is an autogenerated mock type for the ClientFactory type
type MockClientFactory struct {
mock.Mock
}
type MockClientFactory_Expecter struct {
mock *mock.Mock
}
func (_m *MockClientFactory) EXPECT() *MockClientFactory_Expecter {
return &MockClientFactory_Expecter{mock: &_m.Mock}
}
// Clients provides a mock function with given fields: ctx, namespace
func (_m *MockClientFactory) Clients(ctx context.Context, namespace string) (ResourceClients, error) {
ret := _m.Called(ctx, namespace)
if len(ret) == 0 {
panic("no return value specified for Clients")
}
var r0 ResourceClients
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (ResourceClients, error)); ok {
return rf(ctx, namespace)
}
if rf, ok := ret.Get(0).(func(context.Context, string) ResourceClients); ok {
r0 = rf(ctx, namespace)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(ResourceClients)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, namespace)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockClientFactory_Clients_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Clients'
type MockClientFactory_Clients_Call struct {
*mock.Call
}
// Clients is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
func (_e *MockClientFactory_Expecter) Clients(ctx interface{}, namespace interface{}) *MockClientFactory_Clients_Call {
return &MockClientFactory_Clients_Call{Call: _e.mock.On("Clients", ctx, namespace)}
}
func (_c *MockClientFactory_Clients_Call) Run(run func(ctx context.Context, namespace string)) *MockClientFactory_Clients_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockClientFactory_Clients_Call) Return(_a0 ResourceClients, _a1 error) *MockClientFactory_Clients_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockClientFactory_Clients_Call) RunAndReturn(run func(context.Context, string) (ResourceClients, error)) *MockClientFactory_Clients_Call {
_c.Call.Return(run)
return _c
}
// NewMockClientFactory creates a new instance of MockClientFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockClientFactory(t interface {
mock.TestingT
Cleanup(func())
}) *MockClientFactory {
mock := &MockClientFactory{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.3. DO NOT EDIT.
// Code generated by mockery v2.52.4. DO NOT EDIT.
package resources
@@ -18,11 +18,11 @@ import (
// TODO: it does not support folders yet
type DualReadWriter struct {
repo repository.ReaderWriter
parser *Parser
parser Parser
folders *FolderManager
}
func NewDualReadWriter(repo repository.ReaderWriter, parser *Parser, folders *FolderManager) *DualReadWriter {
func NewDualReadWriter(repo repository.ReaderWriter, parser Parser, folders *FolderManager) *DualReadWriter {
return &DualReadWriter{repo: repo, parser: parser, folders: folders}
}
@@ -95,7 +95,7 @@ spec:
info.Data, err = os.ReadFile(path.Join("../../../../..", info.Path))
require.NoError(t, err)
parser := &Parser{
parser := &parser{
repo: provisioning.ResourceRepositoryInfo{
Name: "test",
},
@@ -20,11 +20,11 @@ const maxFolders = 10000
type FolderManager struct {
repo repository.ReaderWriter
tree *FolderTree
tree FolderTree
client dynamic.ResourceInterface
}
func NewFolderManager(repo repository.ReaderWriter, client dynamic.ResourceInterface, lookup *FolderTree) *FolderManager {
func NewFolderManager(repo repository.ReaderWriter, client dynamic.ResourceInterface, lookup FolderTree) *FolderManager {
return &FolderManager{
repo: repo,
tree: lookup,
@@ -36,11 +36,11 @@ func (fm *FolderManager) Client() dynamic.ResourceInterface {
return fm.client
}
func (fm *FolderManager) Tree() *FolderTree {
func (fm *FolderManager) Tree() FolderTree {
return fm.tree
}
func (fm *FolderManager) SetTree(tree *FolderTree) {
func (fm *FolderManager) SetTree(tree FolderTree) {
fm.tree = tree
}
@@ -16,6 +16,8 @@ import (
)
// Get repository stats
//
//go:generate mockery --name ResourceLister --structname MockResourceLister --inpackage --filename resource_lister_mock.go --with-expecter
type ResourceLister interface {
List(ctx context.Context, namespace, repository string) (*provisioning.ResourceList, error)
Stats(ctx context.Context, namespace, repository string) (*provisioning.ResourceStats, error)
@@ -23,11 +23,29 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/provisioning/safepath"
)
type ParserFactory struct {
ClientFactory *ClientFactory
// ParserFactory is a factory for creating parsers for a given repository
//
//go:generate mockery --name ParserFactory --structname MockParserFactory --inpackage --filename parser_factory_mock.go --with-expecter
type ParserFactory interface {
GetParser(ctx context.Context, repo repository.Reader) (Parser, error)
}
func (f *ParserFactory) GetParser(ctx context.Context, repo repository.Reader) (*Parser, error) {
// Parser is a parser for a given repository
//
//go:generate mockery --name Parser --structname MockParser --inpackage --filename parser_mock.go --with-expecter
type Parser interface {
Parse(ctx context.Context, info *repository.FileInfo) (parsed *ParsedResource, err error)
}
type parserFactory struct {
ClientFactory ClientFactory
}
func NewParserFactory(clientFactory ClientFactory) ParserFactory {
return &parserFactory{clientFactory}
}
func (f *parserFactory) GetParser(ctx context.Context, repo repository.Reader) (Parser, error) {
config := repo.Config()
clients, err := f.ClientFactory.Clients(ctx, config.GetNamespace())
@@ -36,7 +54,7 @@ func (f *ParserFactory) GetParser(ctx context.Context, repo repository.Reader) (
}
urls, _ := repo.(repository.RepositoryWithURLs)
return &Parser{
return &parser{
repo: provisioning.ResourceRepositoryInfo{
Type: config.Spec.Type,
Title: config.Spec.Title,
@@ -48,7 +66,7 @@ func (f *ParserFactory) GetParser(ctx context.Context, repo repository.Reader) (
}, nil
}
type Parser struct {
type parser struct {
// The target repository
repo provisioning.ResourceRepositoryInfo
@@ -101,12 +119,7 @@ type ParsedResource struct {
Errors []string
}
// FIXME: eliminate clients from parser (but be careful that we can use the same cache/resolved GVK+GVR)
func (r *Parser) Clients() ResourceClients {
return r.clients
}
func (r *Parser) Parse(ctx context.Context, info *repository.FileInfo) (parsed *ParsedResource, err error) {
func (r *parser) Parse(ctx context.Context, info *repository.FileInfo) (parsed *ParsedResource, err error) {
logger := logging.FromContext(ctx).With("path", info.Path)
parsed = &ParsedResource{
Info: info,
@@ -0,0 +1,96 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package resources
import (
context "context"
repository "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
mock "github.com/stretchr/testify/mock"
)
// MockParserFactory is an autogenerated mock type for the ParserFactory type
type MockParserFactory struct {
mock.Mock
}
type MockParserFactory_Expecter struct {
mock *mock.Mock
}
func (_m *MockParserFactory) EXPECT() *MockParserFactory_Expecter {
return &MockParserFactory_Expecter{mock: &_m.Mock}
}
// GetParser provides a mock function with given fields: ctx, repo
func (_m *MockParserFactory) GetParser(ctx context.Context, repo repository.Reader) (Parser, error) {
ret := _m.Called(ctx, repo)
if len(ret) == 0 {
panic("no return value specified for GetParser")
}
var r0 Parser
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, repository.Reader) (Parser, error)); ok {
return rf(ctx, repo)
}
if rf, ok := ret.Get(0).(func(context.Context, repository.Reader) Parser); ok {
r0 = rf(ctx, repo)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(Parser)
}
}
if rf, ok := ret.Get(1).(func(context.Context, repository.Reader) error); ok {
r1 = rf(ctx, repo)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockParserFactory_GetParser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetParser'
type MockParserFactory_GetParser_Call struct {
*mock.Call
}
// GetParser is a helper method to define mock.On call
// - ctx context.Context
// - repo repository.Reader
func (_e *MockParserFactory_Expecter) GetParser(ctx interface{}, repo interface{}) *MockParserFactory_GetParser_Call {
return &MockParserFactory_GetParser_Call{Call: _e.mock.On("GetParser", ctx, repo)}
}
func (_c *MockParserFactory_GetParser_Call) Run(run func(ctx context.Context, repo repository.Reader)) *MockParserFactory_GetParser_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(repository.Reader))
})
return _c
}
func (_c *MockParserFactory_GetParser_Call) Return(_a0 Parser, _a1 error) *MockParserFactory_GetParser_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockParserFactory_GetParser_Call) RunAndReturn(run func(context.Context, repository.Reader) (Parser, error)) *MockParserFactory_GetParser_Call {
_c.Call.Return(run)
return _c
}
// NewMockParserFactory creates a new instance of MockParserFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockParserFactory(t interface {
mock.TestingT
Cleanup(func())
}) *MockParserFactory {
mock := &MockParserFactory{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -0,0 +1,96 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package resources
import (
context "context"
repository "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
mock "github.com/stretchr/testify/mock"
)
// MockParser is an autogenerated mock type for the Parser type
type MockParser struct {
mock.Mock
}
type MockParser_Expecter struct {
mock *mock.Mock
}
func (_m *MockParser) EXPECT() *MockParser_Expecter {
return &MockParser_Expecter{mock: &_m.Mock}
}
// Parse provides a mock function with given fields: ctx, info
func (_m *MockParser) Parse(ctx context.Context, info *repository.FileInfo) (*ParsedResource, error) {
ret := _m.Called(ctx, info)
if len(ret) == 0 {
panic("no return value specified for Parse")
}
var r0 *ParsedResource
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *repository.FileInfo) (*ParsedResource, error)); ok {
return rf(ctx, info)
}
if rf, ok := ret.Get(0).(func(context.Context, *repository.FileInfo) *ParsedResource); ok {
r0 = rf(ctx, info)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*ParsedResource)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *repository.FileInfo) error); ok {
r1 = rf(ctx, info)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockParser_Parse_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Parse'
type MockParser_Parse_Call struct {
*mock.Call
}
// Parse is a helper method to define mock.On call
// - ctx context.Context
// - info *repository.FileInfo
func (_e *MockParser_Expecter) Parse(ctx interface{}, info interface{}) *MockParser_Parse_Call {
return &MockParser_Parse_Call{Call: _e.mock.On("Parse", ctx, info)}
}
func (_c *MockParser_Parse_Call) Run(run func(ctx context.Context, info *repository.FileInfo)) *MockParser_Parse_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*repository.FileInfo))
})
return _c
}
func (_c *MockParser_Parse_Call) Return(parsed *ParsedResource, err error) *MockParser_Parse_Call {
_c.Call.Return(parsed, err)
return _c
}
func (_c *MockParser_Parse_Call) RunAndReturn(run func(context.Context, *repository.FileInfo) (*ParsedResource, error)) *MockParser_Parse_Call {
_c.Call.Return(run)
return _c
}
// NewMockParser creates a new instance of MockParser. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockParser(t interface {
mock.TestingT
Cleanup(func())
}) *MockParser {
mock := &MockParser{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -20,7 +20,7 @@ func TestParser(t *testing.T) {
clients.On("ForKind", dashboardV1.DashboardResourceInfo.GroupVersionKind()).
Return(nil, dashboardV1.DashboardResourceInfo.GroupVersionResource(), nil).Maybe()
parser := &Parser{
parser := &parser{
repo: v0alpha1.ResourceRepositoryInfo{
Type: v0alpha1.LocalRepositoryType,
Namespace: "xxx",
@@ -0,0 +1,157 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package resources
import (
context "context"
v0alpha1 "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
mock "github.com/stretchr/testify/mock"
)
// MockResourceLister is an autogenerated mock type for the ResourceLister type
type MockResourceLister struct {
mock.Mock
}
type MockResourceLister_Expecter struct {
mock *mock.Mock
}
func (_m *MockResourceLister) EXPECT() *MockResourceLister_Expecter {
return &MockResourceLister_Expecter{mock: &_m.Mock}
}
// List provides a mock function with given fields: ctx, namespace, repository
func (_m *MockResourceLister) List(ctx context.Context, namespace string, repository string) (*v0alpha1.ResourceList, error) {
ret := _m.Called(ctx, namespace, repository)
if len(ret) == 0 {
panic("no return value specified for List")
}
var r0 *v0alpha1.ResourceList
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*v0alpha1.ResourceList, error)); ok {
return rf(ctx, namespace, repository)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *v0alpha1.ResourceList); ok {
r0 = rf(ctx, namespace, repository)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.ResourceList)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, namespace, repository)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockResourceLister_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List'
type MockResourceLister_List_Call struct {
*mock.Call
}
// List is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
// - repository string
func (_e *MockResourceLister_Expecter) List(ctx interface{}, namespace interface{}, repository interface{}) *MockResourceLister_List_Call {
return &MockResourceLister_List_Call{Call: _e.mock.On("List", ctx, namespace, repository)}
}
func (_c *MockResourceLister_List_Call) Run(run func(ctx context.Context, namespace string, repository string)) *MockResourceLister_List_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockResourceLister_List_Call) Return(_a0 *v0alpha1.ResourceList, _a1 error) *MockResourceLister_List_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockResourceLister_List_Call) RunAndReturn(run func(context.Context, string, string) (*v0alpha1.ResourceList, error)) *MockResourceLister_List_Call {
_c.Call.Return(run)
return _c
}
// Stats provides a mock function with given fields: ctx, namespace, repository
func (_m *MockResourceLister) Stats(ctx context.Context, namespace string, repository string) (*v0alpha1.ResourceStats, error) {
ret := _m.Called(ctx, namespace, repository)
if len(ret) == 0 {
panic("no return value specified for Stats")
}
var r0 *v0alpha1.ResourceStats
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*v0alpha1.ResourceStats, error)); ok {
return rf(ctx, namespace, repository)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *v0alpha1.ResourceStats); ok {
r0 = rf(ctx, namespace, repository)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0alpha1.ResourceStats)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, namespace, repository)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockResourceLister_Stats_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stats'
type MockResourceLister_Stats_Call struct {
*mock.Call
}
// Stats is a helper method to define mock.On call
// - ctx context.Context
// - namespace string
// - repository string
func (_e *MockResourceLister_Expecter) Stats(ctx interface{}, namespace interface{}, repository interface{}) *MockResourceLister_Stats_Call {
return &MockResourceLister_Stats_Call{Call: _e.mock.On("Stats", ctx, namespace, repository)}
}
func (_c *MockResourceLister_Stats_Call) Run(run func(ctx context.Context, namespace string, repository string)) *MockResourceLister_Stats_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockResourceLister_Stats_Call) Return(_a0 *v0alpha1.ResourceStats, _a1 error) *MockResourceLister_Stats_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockResourceLister_Stats_Call) RunAndReturn(run func(context.Context, string, string) (*v0alpha1.ResourceStats, error)) *MockResourceLister_Stats_Call {
_c.Call.Return(run)
return _c
}
// NewMockResourceLister creates a new instance of MockResourceLister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockResourceLister(t interface {
mock.TestingT
Cleanup(func())
}) *MockResourceLister {
mock := &MockResourceLister{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -37,13 +37,13 @@ type resourceID struct {
type ResourcesManager struct {
repo repository.ReaderWriter
folders *FolderManager
parser *Parser
parser Parser
clients ResourceClients
userInfo map[string]repository.CommitSignature
resourcesLookup map[resourceID]string // the path with this k8s name
}
func NewResourcesManager(repo repository.ReaderWriter, folders *FolderManager, parser *Parser, clients ResourceClients, userInfo map[string]repository.CommitSignature) *ResourcesManager {
func NewResourcesManager(repo repository.ReaderWriter, folders *FolderManager, parser Parser, clients ResourceClients, userInfo map[string]repository.CommitSignature) *ResourcesManager {
return &ResourcesManager{
repo: repo,
folders: folders,
@@ -16,7 +16,18 @@ import (
// FolderTree contains the entire set of folders (at a given snapshot in time) of the Grafana instance.
// The folders are portrayed as a tree, where a folder has a parent, up until the root folder.
// The root folder is special-cased as a folder that exists, but is not itself stored. It has no ID, no title, and no data, but will return `true` for OK bools.
type FolderTree struct {
//
//go:generate mockery --name FolderTree --structname MockFolderTree --inpackage --filename tree_mock.go --with-expecter
type FolderTree interface {
In(folder string) bool
DirPath(folder, baseFolder string) (Folder, bool)
Add(folder Folder, parent string)
AddUnstructured(item *unstructured.Unstructured, skipRepo string) error
Count() int
Walk(ctx context.Context, fn WalkFunc) error
}
type folderTree struct {
tree map[string]string
folders map[string]Folder
count int
@@ -24,7 +35,7 @@ type FolderTree struct {
// In determines if the given folder is in the tree at all. That is, it answers "does the folder even exist in the Grafana instance?"
// An empty folder string means the root folder, and is special-cased to always return true.
func (t *FolderTree) In(folder string) bool {
func (t *folderTree) In(folder string) bool {
_, ok := t.tree[folder]
return ok || folder == ""
}
@@ -36,7 +47,7 @@ func (t *FolderTree) In(folder string) bool {
//
// If In(folder) or In(baseFolder) is false, this will return ok=false, because it would be undefined behaviour.
// If baseFolder is not a parent of folder, ok=false is returned.
func (t *FolderTree) DirPath(folder, baseFolder string) (fid Folder, ok bool) {
func (t *folderTree) DirPath(folder, baseFolder string) (fid Folder, ok bool) {
if !t.In(folder) || !t.In(baseFolder) {
return Folder{}, false
}
@@ -64,19 +75,19 @@ func (t *FolderTree) DirPath(folder, baseFolder string) (fid Folder, ok bool) {
return fid, ok
}
func (t *FolderTree) Add(folder Folder, parent string) {
func (t *folderTree) Add(folder Folder, parent string) {
t.tree[folder.ID] = parent
t.folders[folder.ID] = folder
t.count++
}
func (t *FolderTree) Count() int {
func (t *folderTree) Count() int {
return t.count
}
type WalkFunc func(ctx context.Context, folder Folder) error
func (t *FolderTree) Walk(ctx context.Context, fn WalkFunc) error {
func (t *folderTree) Walk(ctx context.Context, fn WalkFunc) error {
toWalk := make([]Folder, 0, len(t.folders))
for _, folder := range t.folders {
folder, _ := t.DirPath(folder.ID, "")
@@ -97,14 +108,14 @@ func (t *FolderTree) Walk(ctx context.Context, fn WalkFunc) error {
return nil
}
func NewEmptyFolderTree() *FolderTree {
return &FolderTree{
func NewEmptyFolderTree() FolderTree {
return &folderTree{
tree: make(map[string]string, 0),
folders: make(map[string]Folder, 0),
}
}
func (t *FolderTree) AddUnstructured(item *unstructured.Unstructured, skipRepo string) error {
func (t *folderTree) AddUnstructured(item *unstructured.Unstructured, skipRepo string) error {
meta, err := utils.MetaAccessor(item)
if err != nil {
return fmt.Errorf("extract meta accessor: %w", err)
@@ -123,7 +134,7 @@ func (t *FolderTree) AddUnstructured(item *unstructured.Unstructured, skipRepo s
return nil
}
func NewFolderTreeFromResourceList(resources *provisioning.ResourceList) *FolderTree {
func NewFolderTreeFromResourceList(resources *provisioning.ResourceList) FolderTree {
tree := make(map[string]string, len(resources.Items))
folderIDs := make(map[string]Folder, len(resources.Items))
for _, rf := range resources.Items {
@@ -139,7 +150,7 @@ func NewFolderTreeFromResourceList(resources *provisioning.ResourceList) *Folder
}
}
return &FolderTree{
return &folderTree{
tree: tree,
folders: folderIDs,
count: len(resources.Items),
@@ -0,0 +1,313 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package resources
import (
context "context"
mock "github.com/stretchr/testify/mock"
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// MockFolderTree is an autogenerated mock type for the FolderTree type
type MockFolderTree struct {
mock.Mock
}
type MockFolderTree_Expecter struct {
mock *mock.Mock
}
func (_m *MockFolderTree) EXPECT() *MockFolderTree_Expecter {
return &MockFolderTree_Expecter{mock: &_m.Mock}
}
// Add provides a mock function with given fields: folder, parent
func (_m *MockFolderTree) Add(folder Folder, parent string) {
_m.Called(folder, parent)
}
// MockFolderTree_Add_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Add'
type MockFolderTree_Add_Call struct {
*mock.Call
}
// Add is a helper method to define mock.On call
// - folder Folder
// - parent string
func (_e *MockFolderTree_Expecter) Add(folder interface{}, parent interface{}) *MockFolderTree_Add_Call {
return &MockFolderTree_Add_Call{Call: _e.mock.On("Add", folder, parent)}
}
func (_c *MockFolderTree_Add_Call) Run(run func(folder Folder, parent string)) *MockFolderTree_Add_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(Folder), args[1].(string))
})
return _c
}
func (_c *MockFolderTree_Add_Call) Return() *MockFolderTree_Add_Call {
_c.Call.Return()
return _c
}
func (_c *MockFolderTree_Add_Call) RunAndReturn(run func(Folder, string)) *MockFolderTree_Add_Call {
_c.Run(run)
return _c
}
// AddUnstructured provides a mock function with given fields: item, skipRepo
func (_m *MockFolderTree) AddUnstructured(item *unstructured.Unstructured, skipRepo string) error {
ret := _m.Called(item, skipRepo)
if len(ret) == 0 {
panic("no return value specified for AddUnstructured")
}
var r0 error
if rf, ok := ret.Get(0).(func(*unstructured.Unstructured, string) error); ok {
r0 = rf(item, skipRepo)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockFolderTree_AddUnstructured_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddUnstructured'
type MockFolderTree_AddUnstructured_Call struct {
*mock.Call
}
// AddUnstructured is a helper method to define mock.On call
// - item *unstructured.Unstructured
// - skipRepo string
func (_e *MockFolderTree_Expecter) AddUnstructured(item interface{}, skipRepo interface{}) *MockFolderTree_AddUnstructured_Call {
return &MockFolderTree_AddUnstructured_Call{Call: _e.mock.On("AddUnstructured", item, skipRepo)}
}
func (_c *MockFolderTree_AddUnstructured_Call) Run(run func(item *unstructured.Unstructured, skipRepo string)) *MockFolderTree_AddUnstructured_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*unstructured.Unstructured), args[1].(string))
})
return _c
}
func (_c *MockFolderTree_AddUnstructured_Call) Return(_a0 error) *MockFolderTree_AddUnstructured_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockFolderTree_AddUnstructured_Call) RunAndReturn(run func(*unstructured.Unstructured, string) error) *MockFolderTree_AddUnstructured_Call {
_c.Call.Return(run)
return _c
}
// Count provides a mock function with no fields
func (_m *MockFolderTree) Count() int {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Count")
}
var r0 int
if rf, ok := ret.Get(0).(func() int); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(int)
}
return r0
}
// MockFolderTree_Count_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Count'
type MockFolderTree_Count_Call struct {
*mock.Call
}
// Count is a helper method to define mock.On call
func (_e *MockFolderTree_Expecter) Count() *MockFolderTree_Count_Call {
return &MockFolderTree_Count_Call{Call: _e.mock.On("Count")}
}
func (_c *MockFolderTree_Count_Call) Run(run func()) *MockFolderTree_Count_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockFolderTree_Count_Call) Return(_a0 int) *MockFolderTree_Count_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockFolderTree_Count_Call) RunAndReturn(run func() int) *MockFolderTree_Count_Call {
_c.Call.Return(run)
return _c
}
// DirPath provides a mock function with given fields: folder, baseFolder
func (_m *MockFolderTree) DirPath(folder string, baseFolder string) (Folder, bool) {
ret := _m.Called(folder, baseFolder)
if len(ret) == 0 {
panic("no return value specified for DirPath")
}
var r0 Folder
var r1 bool
if rf, ok := ret.Get(0).(func(string, string) (Folder, bool)); ok {
return rf(folder, baseFolder)
}
if rf, ok := ret.Get(0).(func(string, string) Folder); ok {
r0 = rf(folder, baseFolder)
} else {
r0 = ret.Get(0).(Folder)
}
if rf, ok := ret.Get(1).(func(string, string) bool); ok {
r1 = rf(folder, baseFolder)
} else {
r1 = ret.Get(1).(bool)
}
return r0, r1
}
// MockFolderTree_DirPath_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DirPath'
type MockFolderTree_DirPath_Call struct {
*mock.Call
}
// DirPath is a helper method to define mock.On call
// - folder string
// - baseFolder string
func (_e *MockFolderTree_Expecter) DirPath(folder interface{}, baseFolder interface{}) *MockFolderTree_DirPath_Call {
return &MockFolderTree_DirPath_Call{Call: _e.mock.On("DirPath", folder, baseFolder)}
}
func (_c *MockFolderTree_DirPath_Call) Run(run func(folder string, baseFolder string)) *MockFolderTree_DirPath_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(string))
})
return _c
}
func (_c *MockFolderTree_DirPath_Call) Return(_a0 Folder, _a1 bool) *MockFolderTree_DirPath_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockFolderTree_DirPath_Call) RunAndReturn(run func(string, string) (Folder, bool)) *MockFolderTree_DirPath_Call {
_c.Call.Return(run)
return _c
}
// In provides a mock function with given fields: folder
func (_m *MockFolderTree) In(folder string) bool {
ret := _m.Called(folder)
if len(ret) == 0 {
panic("no return value specified for In")
}
var r0 bool
if rf, ok := ret.Get(0).(func(string) bool); ok {
r0 = rf(folder)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockFolderTree_In_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'In'
type MockFolderTree_In_Call struct {
*mock.Call
}
// In is a helper method to define mock.On call
// - folder string
func (_e *MockFolderTree_Expecter) In(folder interface{}) *MockFolderTree_In_Call {
return &MockFolderTree_In_Call{Call: _e.mock.On("In", folder)}
}
func (_c *MockFolderTree_In_Call) Run(run func(folder string)) *MockFolderTree_In_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockFolderTree_In_Call) Return(_a0 bool) *MockFolderTree_In_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockFolderTree_In_Call) RunAndReturn(run func(string) bool) *MockFolderTree_In_Call {
_c.Call.Return(run)
return _c
}
// Walk provides a mock function with given fields: ctx, fn
func (_m *MockFolderTree) Walk(ctx context.Context, fn WalkFunc) error {
ret := _m.Called(ctx, fn)
if len(ret) == 0 {
panic("no return value specified for Walk")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, WalkFunc) error); ok {
r0 = rf(ctx, fn)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockFolderTree_Walk_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Walk'
type MockFolderTree_Walk_Call struct {
*mock.Call
}
// Walk is a helper method to define mock.On call
// - ctx context.Context
// - fn WalkFunc
func (_e *MockFolderTree_Expecter) Walk(ctx interface{}, fn interface{}) *MockFolderTree_Walk_Call {
return &MockFolderTree_Walk_Call{Call: _e.mock.On("Walk", ctx, fn)}
}
func (_c *MockFolderTree_Walk_Call) Run(run func(ctx context.Context, fn WalkFunc)) *MockFolderTree_Walk_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(WalkFunc))
})
return _c
}
func (_c *MockFolderTree_Walk_Call) Return(_a0 error) *MockFolderTree_Walk_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockFolderTree_Walk_Call) RunAndReturn(run func(context.Context, WalkFunc) error) *MockFolderTree_Walk_Call {
_c.Call.Return(run)
return _c
}
// NewMockFolderTree creates a new instance of MockFolderTree. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockFolderTree(t interface {
mock.TestingT
Cleanup(func())
}) *MockFolderTree {
mock := &MockFolderTree{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -12,7 +12,7 @@ func TestFolderTree(t *testing.T) {
}
t.Run("empty tree", func(t *testing.T) {
tree := &FolderTree{
tree := &folderTree{
tree: make(map[string]string),
folders: make(map[string]Folder),
}
@@ -24,7 +24,7 @@ func TestFolderTree(t *testing.T) {
})
t.Run("single directory in tree", func(t *testing.T) {
tree := &FolderTree{
tree := &folderTree{
tree: map[string]string{"x": ""},
folders: map[string]Folder{"x": newFid("x", "X!")},
}
@@ -45,7 +45,7 @@ func TestFolderTree(t *testing.T) {
})
t.Run("simple nesting tree", func(t *testing.T) {
tree := &FolderTree{
tree := &folderTree{
tree: map[string]string{"a": "b", "b": "c", "c": "x", "x": ""},
folders: map[string]Folder{
"x": newFid("x", "X!"),
@@ -0,0 +1,374 @@
// Code generated by mockery v2.52.4. DO NOT EDIT.
package dualwrite
import (
context "context"
rest "github.com/grafana/grafana/pkg/apiserver/rest"
mock "github.com/stretchr/testify/mock"
schema "k8s.io/apimachinery/pkg/runtime/schema"
)
// MockService is an autogenerated mock type for the Service type
type MockService struct {
mock.Mock
}
type MockService_Expecter struct {
mock *mock.Mock
}
func (_m *MockService) EXPECT() *MockService_Expecter {
return &MockService_Expecter{mock: &_m.Mock}
}
// NewStorage provides a mock function with given fields: gr, legacy, storage
func (_m *MockService) NewStorage(gr schema.GroupResource, legacy rest.Storage, storage rest.Storage) (rest.Storage, error) {
ret := _m.Called(gr, legacy, storage)
if len(ret) == 0 {
panic("no return value specified for NewStorage")
}
var r0 rest.Storage
var r1 error
if rf, ok := ret.Get(0).(func(schema.GroupResource, rest.Storage, rest.Storage) (rest.Storage, error)); ok {
return rf(gr, legacy, storage)
}
if rf, ok := ret.Get(0).(func(schema.GroupResource, rest.Storage, rest.Storage) rest.Storage); ok {
r0 = rf(gr, legacy, storage)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(rest.Storage)
}
}
if rf, ok := ret.Get(1).(func(schema.GroupResource, rest.Storage, rest.Storage) error); ok {
r1 = rf(gr, legacy, storage)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_NewStorage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewStorage'
type MockService_NewStorage_Call struct {
*mock.Call
}
// NewStorage is a helper method to define mock.On call
// - gr schema.GroupResource
// - legacy rest.Storage
// - storage rest.Storage
func (_e *MockService_Expecter) NewStorage(gr interface{}, legacy interface{}, storage interface{}) *MockService_NewStorage_Call {
return &MockService_NewStorage_Call{Call: _e.mock.On("NewStorage", gr, legacy, storage)}
}
func (_c *MockService_NewStorage_Call) Run(run func(gr schema.GroupResource, legacy rest.Storage, storage rest.Storage)) *MockService_NewStorage_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(schema.GroupResource), args[1].(rest.Storage), args[2].(rest.Storage))
})
return _c
}
func (_c *MockService_NewStorage_Call) Return(_a0 rest.Storage, _a1 error) *MockService_NewStorage_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_NewStorage_Call) RunAndReturn(run func(schema.GroupResource, rest.Storage, rest.Storage) (rest.Storage, error)) *MockService_NewStorage_Call {
_c.Call.Return(run)
return _c
}
// ReadFromUnified provides a mock function with given fields: ctx, gr
func (_m *MockService) ReadFromUnified(ctx context.Context, gr schema.GroupResource) (bool, error) {
ret := _m.Called(ctx, gr)
if len(ret) == 0 {
panic("no return value specified for ReadFromUnified")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, schema.GroupResource) (bool, error)); ok {
return rf(ctx, gr)
}
if rf, ok := ret.Get(0).(func(context.Context, schema.GroupResource) bool); ok {
r0 = rf(ctx, gr)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, schema.GroupResource) error); ok {
r1 = rf(ctx, gr)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_ReadFromUnified_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadFromUnified'
type MockService_ReadFromUnified_Call struct {
*mock.Call
}
// ReadFromUnified is a helper method to define mock.On call
// - ctx context.Context
// - gr schema.GroupResource
func (_e *MockService_Expecter) ReadFromUnified(ctx interface{}, gr interface{}) *MockService_ReadFromUnified_Call {
return &MockService_ReadFromUnified_Call{Call: _e.mock.On("ReadFromUnified", ctx, gr)}
}
func (_c *MockService_ReadFromUnified_Call) Run(run func(ctx context.Context, gr schema.GroupResource)) *MockService_ReadFromUnified_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(schema.GroupResource))
})
return _c
}
func (_c *MockService_ReadFromUnified_Call) Return(_a0 bool, _a1 error) *MockService_ReadFromUnified_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_ReadFromUnified_Call) RunAndReturn(run func(context.Context, schema.GroupResource) (bool, error)) *MockService_ReadFromUnified_Call {
_c.Call.Return(run)
return _c
}
// ShouldManage provides a mock function with given fields: gr
func (_m *MockService) ShouldManage(gr schema.GroupResource) bool {
ret := _m.Called(gr)
if len(ret) == 0 {
panic("no return value specified for ShouldManage")
}
var r0 bool
if rf, ok := ret.Get(0).(func(schema.GroupResource) bool); ok {
r0 = rf(gr)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockService_ShouldManage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ShouldManage'
type MockService_ShouldManage_Call struct {
*mock.Call
}
// ShouldManage is a helper method to define mock.On call
// - gr schema.GroupResource
func (_e *MockService_Expecter) ShouldManage(gr interface{}) *MockService_ShouldManage_Call {
return &MockService_ShouldManage_Call{Call: _e.mock.On("ShouldManage", gr)}
}
func (_c *MockService_ShouldManage_Call) Run(run func(gr schema.GroupResource)) *MockService_ShouldManage_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(schema.GroupResource))
})
return _c
}
func (_c *MockService_ShouldManage_Call) Return(_a0 bool) *MockService_ShouldManage_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_ShouldManage_Call) RunAndReturn(run func(schema.GroupResource) bool) *MockService_ShouldManage_Call {
_c.Call.Return(run)
return _c
}
// StartMigration provides a mock function with given fields: ctx, gr, key
func (_m *MockService) StartMigration(ctx context.Context, gr schema.GroupResource, key int64) (StorageStatus, error) {
ret := _m.Called(ctx, gr, key)
if len(ret) == 0 {
panic("no return value specified for StartMigration")
}
var r0 StorageStatus
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, schema.GroupResource, int64) (StorageStatus, error)); ok {
return rf(ctx, gr, key)
}
if rf, ok := ret.Get(0).(func(context.Context, schema.GroupResource, int64) StorageStatus); ok {
r0 = rf(ctx, gr, key)
} else {
r0 = ret.Get(0).(StorageStatus)
}
if rf, ok := ret.Get(1).(func(context.Context, schema.GroupResource, int64) error); ok {
r1 = rf(ctx, gr, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_StartMigration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartMigration'
type MockService_StartMigration_Call struct {
*mock.Call
}
// StartMigration is a helper method to define mock.On call
// - ctx context.Context
// - gr schema.GroupResource
// - key int64
func (_e *MockService_Expecter) StartMigration(ctx interface{}, gr interface{}, key interface{}) *MockService_StartMigration_Call {
return &MockService_StartMigration_Call{Call: _e.mock.On("StartMigration", ctx, gr, key)}
}
func (_c *MockService_StartMigration_Call) Run(run func(ctx context.Context, gr schema.GroupResource, key int64)) *MockService_StartMigration_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(schema.GroupResource), args[2].(int64))
})
return _c
}
func (_c *MockService_StartMigration_Call) Return(_a0 StorageStatus, _a1 error) *MockService_StartMigration_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_StartMigration_Call) RunAndReturn(run func(context.Context, schema.GroupResource, int64) (StorageStatus, error)) *MockService_StartMigration_Call {
_c.Call.Return(run)
return _c
}
// Status provides a mock function with given fields: ctx, gr
func (_m *MockService) Status(ctx context.Context, gr schema.GroupResource) (StorageStatus, error) {
ret := _m.Called(ctx, gr)
if len(ret) == 0 {
panic("no return value specified for Status")
}
var r0 StorageStatus
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, schema.GroupResource) (StorageStatus, error)); ok {
return rf(ctx, gr)
}
if rf, ok := ret.Get(0).(func(context.Context, schema.GroupResource) StorageStatus); ok {
r0 = rf(ctx, gr)
} else {
r0 = ret.Get(0).(StorageStatus)
}
if rf, ok := ret.Get(1).(func(context.Context, schema.GroupResource) error); ok {
r1 = rf(ctx, gr)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Status_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Status'
type MockService_Status_Call struct {
*mock.Call
}
// Status is a helper method to define mock.On call
// - ctx context.Context
// - gr schema.GroupResource
func (_e *MockService_Expecter) Status(ctx interface{}, gr interface{}) *MockService_Status_Call {
return &MockService_Status_Call{Call: _e.mock.On("Status", ctx, gr)}
}
func (_c *MockService_Status_Call) Run(run func(ctx context.Context, gr schema.GroupResource)) *MockService_Status_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(schema.GroupResource))
})
return _c
}
func (_c *MockService_Status_Call) Return(_a0 StorageStatus, _a1 error) *MockService_Status_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_Status_Call) RunAndReturn(run func(context.Context, schema.GroupResource) (StorageStatus, error)) *MockService_Status_Call {
_c.Call.Return(run)
return _c
}
// Update provides a mock function with given fields: ctx, status
func (_m *MockService) Update(ctx context.Context, status StorageStatus) (StorageStatus, error) {
ret := _m.Called(ctx, status)
if len(ret) == 0 {
panic("no return value specified for Update")
}
var r0 StorageStatus
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, StorageStatus) (StorageStatus, error)); ok {
return rf(ctx, status)
}
if rf, ok := ret.Get(0).(func(context.Context, StorageStatus) StorageStatus); ok {
r0 = rf(ctx, status)
} else {
r0 = ret.Get(0).(StorageStatus)
}
if rf, ok := ret.Get(1).(func(context.Context, StorageStatus) error); ok {
r1 = rf(ctx, status)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update'
type MockService_Update_Call struct {
*mock.Call
}
// Update is a helper method to define mock.On call
// - ctx context.Context
// - status StorageStatus
func (_e *MockService_Expecter) Update(ctx interface{}, status interface{}) *MockService_Update_Call {
return &MockService_Update_Call{Call: _e.mock.On("Update", ctx, status)}
}
func (_c *MockService_Update_Call) Run(run func(ctx context.Context, status StorageStatus)) *MockService_Update_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(StorageStatus))
})
return _c
}
func (_c *MockService_Update_Call) Return(_a0 StorageStatus, _a1 error) *MockService_Update_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_Update_Call) RunAndReturn(run func(context.Context, StorageStatus) (StorageStatus, error)) *MockService_Update_Call {
_c.Call.Return(run)
return _c
}
// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockService(t interface {
mock.TestingT
Cleanup(func())
}) *MockService {
mock := &MockService{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
+3
View File
@@ -32,6 +32,9 @@ type StorageStatus struct {
UpdateKey int64 `json:"update_key" xorm:"update_key"`
}
// Service is a service for managing the dual write storage
//
//go:generate mockery --name Service --structname MockService --inpackage --filename service_mock.go --with-expecter
type Service interface {
ShouldManage(gr schema.GroupResource) bool