mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
This commit is contained in:
@@ -76,4 +76,7 @@ packages:
|
||||
SessionServiceClient:
|
||||
github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster:
|
||||
interfaces:
|
||||
ClusterServiceServer:
|
||||
ClusterServiceServer:
|
||||
github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1:
|
||||
interfaces:
|
||||
AppProjectInterface:
|
||||
|
||||
258
pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go
generated
Normal file
258
pkg/client/clientset/versioned/typed/application/v1alpha1/mocks/AppProjectInterface.go
generated
Normal file
@@ -0,0 +1,258 @@
|
||||
// Code generated by mockery v2.52.4. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
v1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
)
|
||||
|
||||
// AppProjectInterface is an autogenerated mock type for the AppProjectInterface type
|
||||
type AppProjectInterface struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Create provides a mock function with given fields: ctx, appProject, opts
|
||||
func (_m *AppProjectInterface) Create(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.CreateOptions) (*v1alpha1.AppProject, error) {
|
||||
ret := _m.Called(ctx, appProject, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Create")
|
||||
}
|
||||
|
||||
var r0 *v1alpha1.AppProject
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) (*v1alpha1.AppProject, error)); ok {
|
||||
return rf(ctx, appProject, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) *v1alpha1.AppProject); ok {
|
||||
r0 = rf(ctx, appProject, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.AppProject)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.AppProject, v1.CreateOptions) error); ok {
|
||||
r1 = rf(ctx, appProject, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: ctx, name, opts
|
||||
func (_m *AppProjectInterface) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
ret := _m.Called(ctx, name, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, v1.DeleteOptions) error); ok {
|
||||
r0 = rf(ctx, name, opts)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteCollection provides a mock function with given fields: ctx, opts, listOpts
|
||||
func (_m *AppProjectInterface) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
ret := _m.Called(ctx, opts, listOpts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteCollection")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, v1.DeleteOptions, v1.ListOptions) error); ok {
|
||||
r0 = rf(ctx, opts, listOpts)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: ctx, name, opts
|
||||
func (_m *AppProjectInterface) Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.AppProject, error) {
|
||||
ret := _m.Called(ctx, name, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Get")
|
||||
}
|
||||
|
||||
var r0 *v1alpha1.AppProject
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, v1.GetOptions) (*v1alpha1.AppProject, error)); ok {
|
||||
return rf(ctx, name, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, v1.GetOptions) *v1alpha1.AppProject); ok {
|
||||
r0 = rf(ctx, name, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.AppProject)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, v1.GetOptions) error); ok {
|
||||
r1 = rf(ctx, name, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: ctx, opts
|
||||
func (_m *AppProjectInterface) List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.AppProjectList, error) {
|
||||
ret := _m.Called(ctx, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for List")
|
||||
}
|
||||
|
||||
var r0 *v1alpha1.AppProjectList
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) (*v1alpha1.AppProjectList, error)); ok {
|
||||
return rf(ctx, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) *v1alpha1.AppProjectList); ok {
|
||||
r0 = rf(ctx, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.AppProjectList)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, v1.ListOptions) error); ok {
|
||||
r1 = rf(ctx, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Patch provides a mock function with given fields: ctx, name, pt, data, opts, subresources
|
||||
func (_m *AppProjectInterface) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (*v1alpha1.AppProject, error) {
|
||||
_va := make([]interface{}, len(subresources))
|
||||
for _i := range subresources {
|
||||
_va[_i] = subresources[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, name, pt, data, opts)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Patch")
|
||||
}
|
||||
|
||||
var r0 *v1alpha1.AppProject
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) (*v1alpha1.AppProject, error)); ok {
|
||||
return rf(ctx, name, pt, data, opts, subresources...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) *v1alpha1.AppProject); ok {
|
||||
r0 = rf(ctx, name, pt, data, opts, subresources...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.AppProject)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, types.PatchType, []byte, v1.PatchOptions, ...string) error); ok {
|
||||
r1 = rf(ctx, name, pt, data, opts, subresources...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Update provides a mock function with given fields: ctx, appProject, opts
|
||||
func (_m *AppProjectInterface) Update(ctx context.Context, appProject *v1alpha1.AppProject, opts v1.UpdateOptions) (*v1alpha1.AppProject, error) {
|
||||
ret := _m.Called(ctx, appProject, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Update")
|
||||
}
|
||||
|
||||
var r0 *v1alpha1.AppProject
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) (*v1alpha1.AppProject, error)); ok {
|
||||
return rf(ctx, appProject, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) *v1alpha1.AppProject); ok {
|
||||
r0 = rf(ctx, appProject, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v1alpha1.AppProject)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v1alpha1.AppProject, v1.UpdateOptions) error); ok {
|
||||
r1 = rf(ctx, appProject, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Watch provides a mock function with given fields: ctx, opts
|
||||
func (_m *AppProjectInterface) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
ret := _m.Called(ctx, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Watch")
|
||||
}
|
||||
|
||||
var r0 watch.Interface
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) (watch.Interface, error)); ok {
|
||||
return rf(ctx, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, v1.ListOptions) watch.Interface); ok {
|
||||
r0 = rf(ctx, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(watch.Interface)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, v1.ListOptions) error); ok {
|
||||
r1 = rf(ctx, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// NewAppProjectInterface creates a new instance of AppProjectInterface. 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 NewAppProjectInterface(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *AppProjectInterface {
|
||||
mock := &AppProjectInterface{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@@ -48,7 +48,6 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
servercache "github.com/argoproj/argo-cd/v3/server/cache"
|
||||
"github.com/argoproj/argo-cd/v3/server/deeplinks"
|
||||
"github.com/argoproj/argo-cd/v3/util"
|
||||
"github.com/argoproj/argo-cd/v3/util/argo"
|
||||
"github.com/argoproj/argo-cd/v3/util/collections"
|
||||
"github.com/argoproj/argo-cd/v3/util/db"
|
||||
@@ -127,8 +126,8 @@ func NewServer(
|
||||
}
|
||||
s := &Server{
|
||||
ns: namespace,
|
||||
appclientset: appclientset,
|
||||
appLister: appLister,
|
||||
appclientset: &deepCopyAppClientset{appclientset},
|
||||
appLister: &deepCopyApplicationLister{appLister},
|
||||
appInformer: appInformer,
|
||||
appBroadcaster: appBroadcaster,
|
||||
kubeclientset: kubeclientset,
|
||||
@@ -261,9 +260,7 @@ func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, pr
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Objects returned by the lister must be treated as read-only.
|
||||
// To allow us to modify the app later, make a copy
|
||||
return app.DeepCopy(), nil
|
||||
return app, nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -380,9 +377,6 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "unable to check existing application details (%s): %v", appNs, err)
|
||||
}
|
||||
// Objects returned from listers have to be treated as read-only
|
||||
// Take a deep copy so we can edit it below
|
||||
existing = existing.DeepCopy()
|
||||
|
||||
if _, err := argo.GetDestinationCluster(ctx, existing.Spec.Destination, s.db); err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "application destination spec for %s is invalid: %s", existing.Name, err.Error())
|
||||
@@ -491,7 +485,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
|
||||
}
|
||||
|
||||
sources := make([]v1alpha1.ApplicationSource, 0)
|
||||
appSpec := a.Spec.DeepCopy()
|
||||
appSpec := a.Spec
|
||||
if a.Spec.HasMultipleSources() {
|
||||
numOfSources := int64(len(a.Spec.GetSources()))
|
||||
for i, pos := range q.SourcePositions {
|
||||
@@ -888,7 +882,7 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *application.Applicat
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing resource events: %w", err)
|
||||
}
|
||||
return list, nil
|
||||
return list.DeepCopy(), nil
|
||||
}
|
||||
|
||||
// validateAndUpdateApp validates and updates the application. currentProject is the name of the project the app
|
||||
@@ -1226,7 +1220,6 @@ func (s *Server) Watch(q *application.ApplicationQuery, ws application.Applicati
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing apps with selector: %w", err)
|
||||
}
|
||||
apps = util.SliceCopy(apps)
|
||||
sort.Slice(apps, func(i, j int) bool {
|
||||
return apps[i].QualifiedName() < apps[j].QualifiedName()
|
||||
})
|
||||
@@ -2330,7 +2323,7 @@ func (s *Server) TerminateOperation(ctx context.Context, termOpReq *application.
|
||||
}
|
||||
log.Warnf("failed to set operation for app %q due to update conflict. retrying again...", *termOpReq.Name)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
a, err = s.appclientset.ArgoprojV1alpha1().Applications(appNs).Get(ctx, appName, metav1.GetOptions{})
|
||||
_, err = s.appclientset.ArgoprojV1alpha1().Applications(appNs).Get(ctx, appName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting application by name: %w", err)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -1547,7 +1549,7 @@ func TestDeleteApp(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, app)
|
||||
|
||||
fakeAppCs := appServer.appclientset.(*apps.Clientset)
|
||||
fakeAppCs := appServer.appclientset.(*deepCopyAppClientset).GetUnderlyingClientSet().(*apps.Clientset)
|
||||
// this removes the default */* reactor so we can set our own patch/delete reactor
|
||||
fakeAppCs.ReactionChain = nil
|
||||
patched := false
|
||||
@@ -2069,7 +2071,7 @@ func TestGetCachedAppState(t *testing.T) {
|
||||
},
|
||||
}
|
||||
appServer := newTestAppServer(t, testApp, testProj)
|
||||
fakeClientSet := appServer.appclientset.(*apps.Clientset)
|
||||
fakeClientSet := appServer.appclientset.(*deepCopyAppClientset).GetUnderlyingClientSet().(*apps.Clientset)
|
||||
fakeClientSet.AddReactor("get", "applications", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, &v1alpha1.Application{Spec: v1alpha1.ApplicationSpec{Source: &v1alpha1.ApplicationSource{}}}, nil
|
||||
})
|
||||
@@ -2330,7 +2332,6 @@ func refreshAnnotationRemover(t *testing.T, ctx context.Context, patched *int32,
|
||||
aName, appNs := argo.ParseFromQualifiedName(appName, appServer.ns)
|
||||
a, err := appServer.appLister.Applications(appNs).Get(aName)
|
||||
require.NoError(t, err)
|
||||
a = a.DeepCopy()
|
||||
if a.GetAnnotations() != nil && a.GetAnnotations()[v1alpha1.AnnotationKeyRefresh] != "" {
|
||||
a.SetAnnotations(map[string]string{})
|
||||
a.SetResourceVersion("999")
|
||||
@@ -3350,3 +3351,106 @@ func Test_RevisionMetadata(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_DeepCopyInformers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
namespace := "test-namespace"
|
||||
var ro []runtime.Object
|
||||
appOne := newTestApp(func(app *v1alpha1.Application) {
|
||||
app.Name = "appOne"
|
||||
app.ObjectMeta.Namespace = namespace
|
||||
app.Spec = v1alpha1.ApplicationSpec{}
|
||||
})
|
||||
appTwo := newTestApp(func(app *v1alpha1.Application) {
|
||||
app.Name = "appTwo"
|
||||
app.ObjectMeta.Namespace = namespace
|
||||
app.Spec = v1alpha1.ApplicationSpec{}
|
||||
})
|
||||
appThree := newTestApp(func(app *v1alpha1.Application) {
|
||||
app.Name = "appThree"
|
||||
app.ObjectMeta.Namespace = namespace
|
||||
app.Spec = v1alpha1.ApplicationSpec{}
|
||||
})
|
||||
ro = append(ro, appOne, appTwo, appThree)
|
||||
appls := []v1alpha1.Application{*appOne, *appTwo, *appThree}
|
||||
|
||||
appSetOne := &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "appSetOne", Namespace: namespace},
|
||||
Spec: v1alpha1.ApplicationSetSpec{},
|
||||
}
|
||||
appSetTwo := &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "appSetTwo", Namespace: namespace},
|
||||
Spec: v1alpha1.ApplicationSetSpec{},
|
||||
}
|
||||
appSetThree := &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "appSetThree", Namespace: namespace},
|
||||
Spec: v1alpha1.ApplicationSetSpec{},
|
||||
}
|
||||
ro = append(ro, appSetOne, appSetTwo, appSetThree)
|
||||
appSets := []v1alpha1.ApplicationSet{*appSetOne, *appSetTwo, *appSetThree}
|
||||
|
||||
appProjects := createAppProject("projOne", "projTwo", "projThree")
|
||||
for i := range appProjects {
|
||||
ro = append(ro, &appProjects[i])
|
||||
}
|
||||
|
||||
s := newTestAppServer(t, ro...)
|
||||
|
||||
appList, err := s.appclientset.ArgoprojV1alpha1().Applications(namespace).List(context.Background(), metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, appls, appList.Items)
|
||||
sAppList := appList.Items
|
||||
slices.SortFunc(sAppList, func(a, b v1alpha1.Application) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
slices.SortFunc(appls, func(a, b v1alpha1.Application) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
// ensure there is a deep copy
|
||||
for i := range appls {
|
||||
assert.NotSame(t, &appls[i], &sAppList[i])
|
||||
assert.NotSame(t, &appls[i].Spec, &sAppList[i].Spec)
|
||||
a, err := s.appclientset.ArgoprojV1alpha1().Applications(namespace).Get(context.Background(), sAppList[i].Name, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.NotSame(t, a, &sAppList[i])
|
||||
}
|
||||
|
||||
appSetList, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).List(context.Background(), metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, appSets, appSetList.Items)
|
||||
sAppSetList := appSetList.Items
|
||||
slices.SortFunc(sAppSetList, func(a, b v1alpha1.ApplicationSet) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
slices.SortFunc(appSets, func(a, b v1alpha1.ApplicationSet) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
for i := range appSets {
|
||||
assert.NotSame(t, &appSets[i], &sAppSetList[i])
|
||||
assert.NotSame(t, &appSets[i].Spec, &sAppSetList[i].Spec)
|
||||
a, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).Get(context.Background(),
|
||||
sAppSetList[i].Name, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.NotSame(t, a, &sAppSetList[i])
|
||||
}
|
||||
|
||||
projList, err := s.appclientset.ArgoprojV1alpha1().AppProjects("deep-copy-ns").List(context.Background(), metav1.ListOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.ElementsMatch(t, appProjects, projList.Items)
|
||||
spList := projList.Items
|
||||
slices.SortFunc(spList, func(a, b v1alpha1.AppProject) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
slices.SortFunc(appProjects, func(a, b v1alpha1.AppProject) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
})
|
||||
for i := range appProjects {
|
||||
assert.NotSame(t, &appProjects[i], &spList[i])
|
||||
assert.NotSame(t, &appProjects[i].Spec, &spList[i].Spec)
|
||||
p, err := s.appclientset.ArgoprojV1alpha1().AppProjects("deep-copy-ns").Get(context.Background(),
|
||||
spList[i].Name, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.NotSame(t, p, &spList[i])
|
||||
}
|
||||
}
|
||||
|
||||
164
server/application/deepinformer.go
Normal file
164
server/application/deepinformer.go
Normal file
@@ -0,0 +1,164 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
appclientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned"
|
||||
argoprojv1alpha1 "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1"
|
||||
applisters "github.com/argoproj/argo-cd/v3/pkg/client/listers/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
// deepCopyApplicationLister wraps an ApplicationLister and returns deep copies of the applications.
|
||||
type deepCopyApplicationLister struct {
|
||||
applisters.ApplicationLister
|
||||
}
|
||||
|
||||
// List lists all Applications in the indexer and returns deep copies.
|
||||
func (d *deepCopyApplicationLister) List(selector labels.Selector) ([]*v1alpha1.Application, error) {
|
||||
apps, err := d.ApplicationLister.List(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deepCopiedApps := util.SliceCopy(apps)
|
||||
return deepCopiedApps, nil
|
||||
}
|
||||
|
||||
// Applications return an object that can list and get Applications and returns deep copies.
|
||||
func (d *deepCopyApplicationLister) Applications(namespace string) applisters.ApplicationNamespaceLister {
|
||||
return &deepCopyApplicationNamespaceLister{
|
||||
ApplicationNamespaceLister: d.ApplicationLister.Applications(namespace),
|
||||
}
|
||||
}
|
||||
|
||||
// deepCopyApplicationNamespaceLister wraps an ApplicationNamespaceLister and returns deep copies of the applications.
|
||||
type deepCopyApplicationNamespaceLister struct {
|
||||
applisters.ApplicationNamespaceLister
|
||||
}
|
||||
|
||||
// List lists all Applications in the indexer for a given namespace and returns deep copies.
|
||||
func (d *deepCopyApplicationNamespaceLister) List(selector labels.Selector) ([]*v1alpha1.Application, error) {
|
||||
apps, err := d.ApplicationNamespaceLister.List(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deepCopiedApps := util.SliceCopy(apps)
|
||||
return deepCopiedApps, nil
|
||||
}
|
||||
|
||||
// Get retrieves the Application from the indexer for a given namespace and name and returns a deep copy.
|
||||
func (d *deepCopyApplicationNamespaceLister) Get(name string) (*v1alpha1.Application, error) {
|
||||
app, err := d.ApplicationNamespaceLister.Get(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return app.DeepCopy(), nil
|
||||
}
|
||||
|
||||
type deepCopyAppClientset struct {
|
||||
appclientset.Interface
|
||||
}
|
||||
|
||||
func (d *deepCopyAppClientset) ArgoprojV1alpha1() argoprojv1alpha1.ArgoprojV1alpha1Interface {
|
||||
return &deepCopyArgoprojV1alpha1Client{
|
||||
ArgoprojV1alpha1Interface: d.Interface.ArgoprojV1alpha1(),
|
||||
}
|
||||
}
|
||||
|
||||
// GetUnderlyingClientSet returns the underlying clientset.Interface.
|
||||
// Unit tests should only call this
|
||||
func (d *deepCopyAppClientset) GetUnderlyingClientSet() appclientset.Interface {
|
||||
return d.Interface
|
||||
}
|
||||
|
||||
type deepCopyArgoprojV1alpha1Client struct {
|
||||
argoprojv1alpha1.ArgoprojV1alpha1Interface
|
||||
}
|
||||
|
||||
func (d *deepCopyArgoprojV1alpha1Client) RESTClient() rest.Interface {
|
||||
return d.ArgoprojV1alpha1Interface.RESTClient()
|
||||
}
|
||||
|
||||
func (d *deepCopyArgoprojV1alpha1Client) AppProjects(namespace string) argoprojv1alpha1.AppProjectInterface {
|
||||
return &deepCopyAppProjectClient{
|
||||
AppProjectInterface: d.ArgoprojV1alpha1Interface.AppProjects(namespace),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *deepCopyArgoprojV1alpha1Client) ApplicationSets(namespace string) argoprojv1alpha1.ApplicationSetInterface {
|
||||
return &deepCopyApplicationSetClient{
|
||||
ApplicationSetInterface: d.ArgoprojV1alpha1Interface.ApplicationSets(namespace),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *deepCopyArgoprojV1alpha1Client) Applications(namespace string) argoprojv1alpha1.ApplicationInterface {
|
||||
return &deepCopyApplicationClient{
|
||||
ApplicationInterface: d.ArgoprojV1alpha1Interface.Applications(namespace),
|
||||
}
|
||||
}
|
||||
|
||||
type deepCopyApplicationClient struct {
|
||||
argoprojv1alpha1.ApplicationInterface
|
||||
}
|
||||
|
||||
func (d *deepCopyApplicationClient) Get(ctx context.Context, name string, options metav1.GetOptions) (*v1alpha1.Application, error) {
|
||||
app, err := d.ApplicationInterface.Get(ctx, name, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return app.DeepCopy(), nil
|
||||
}
|
||||
|
||||
func (d *deepCopyApplicationClient) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha1.ApplicationList, error) {
|
||||
appList, err := d.ApplicationInterface.List(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appList.DeepCopy(), nil
|
||||
}
|
||||
|
||||
type deepCopyAppProjectClient struct {
|
||||
argoprojv1alpha1.AppProjectInterface
|
||||
}
|
||||
|
||||
func (d *deepCopyAppProjectClient) Get(ctx context.Context, name string, options metav1.GetOptions) (*v1alpha1.AppProject, error) {
|
||||
appProject, err := d.AppProjectInterface.Get(ctx, name, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appProject.DeepCopy(), nil
|
||||
}
|
||||
|
||||
func (d *deepCopyAppProjectClient) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha1.AppProjectList, error) {
|
||||
appProjectList, err := d.AppProjectInterface.List(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appProjectList.DeepCopy(), nil
|
||||
}
|
||||
|
||||
type deepCopyApplicationSetClient struct {
|
||||
argoprojv1alpha1.ApplicationSetInterface
|
||||
}
|
||||
|
||||
func (d *deepCopyApplicationSetClient) Get(ctx context.Context, name string, options metav1.GetOptions) (*v1alpha1.ApplicationSet, error) {
|
||||
appSet, err := d.ApplicationSetInterface.Get(ctx, name, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appSet.DeepCopy(), nil
|
||||
}
|
||||
|
||||
func (d *deepCopyApplicationSetClient) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha1.ApplicationSetList, error) {
|
||||
appSetList, err := d.ApplicationSetInterface.List(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return appSetList.DeepCopy(), nil
|
||||
}
|
||||
150
server/application/deepinformer_test.go
Normal file
150
server/application/deepinformer_test.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/fake"
|
||||
clientset "github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/client/clientset/versioned/typed/application/v1alpha1/mocks"
|
||||
)
|
||||
|
||||
func Test_deepCopyAppProjectClient_Get(t *testing.T) {
|
||||
type fields struct {
|
||||
AppProjectInterface clientset.AppProjectInterface
|
||||
}
|
||||
type args struct {
|
||||
name string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want *v1alpha1.AppProject
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{name: "Get an app project", fields: fields{AppProjectInterface: setupAppProjects("appproject")}, args: args{
|
||||
name: "appproject",
|
||||
}, want: &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "appproject", Namespace: "deep-copy-ns"},
|
||||
}, wantErr: assert.NoError},
|
||||
{
|
||||
name: "Error getting an app project",
|
||||
fields: fields{
|
||||
AppProjectInterface: func() clientset.AppProjectInterface {
|
||||
appProject := mocks.AppProjectInterface{}
|
||||
appProject.On("Get", context.Background(), "appproject2", metav1.GetOptions{}).Return(nil, errors.New("error"))
|
||||
return &appProject
|
||||
}(),
|
||||
},
|
||||
args: args{
|
||||
name: "appproject2",
|
||||
},
|
||||
want: nil,
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
d := &deepCopyAppProjectClient{
|
||||
AppProjectInterface: tt.fields.AppProjectInterface,
|
||||
}
|
||||
got, err := d.Get(context.Background(), tt.args.name, metav1.GetOptions{})
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("Get(%v)", tt.args.name)) {
|
||||
return
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "Get(%v)", tt.args.name)
|
||||
if tt.want != nil {
|
||||
assert.NotSamef(t, tt.want, got, "%v and %v are the same ptr", tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deepCopyAppProjectClient_List(t *testing.T) {
|
||||
type fields struct {
|
||||
AppProjectInterface clientset.AppProjectInterface
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want []v1alpha1.AppProject
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "List app projects", fields: fields{AppProjectInterface: setupAppProjects("proj1", "proj2")},
|
||||
want: createAppProject("proj1", "proj2"), wantErr: assert.NoError,
|
||||
},
|
||||
{name: "Error listing app project", fields: fields{
|
||||
AppProjectInterface: func() clientset.AppProjectInterface {
|
||||
appProject := mocks.AppProjectInterface{}
|
||||
appProject.On("List", context.Background(), metav1.ListOptions{}).Return(nil, errors.New("error"))
|
||||
return &appProject
|
||||
}(),
|
||||
}, want: nil, wantErr: assert.Error},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
d := &deepCopyAppProjectClient{
|
||||
AppProjectInterface: tt.fields.AppProjectInterface,
|
||||
}
|
||||
got, err := d.List(context.Background(), metav1.ListOptions{})
|
||||
if !tt.wantErr(t, err, "List") {
|
||||
return
|
||||
}
|
||||
if tt.want != nil {
|
||||
assert.Equalf(t, tt.want, got.Items, "List")
|
||||
for i := range tt.want {
|
||||
assert.NotSamef(t, &tt.want[i], &got.Items[i], "%v and %v are the same ptr", tt.want, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createAppProject(projects ...string) []v1alpha1.AppProject {
|
||||
appProjects := make([]v1alpha1.AppProject, len(projects))
|
||||
for i, p := range projects {
|
||||
appProjects[i] = v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: p, Namespace: "deep-copy-ns"}}
|
||||
}
|
||||
return appProjects
|
||||
}
|
||||
|
||||
func setupAppProjects(projects ...string) clientset.AppProjectInterface {
|
||||
appProjects := createAppProject(projects...)
|
||||
ro := make([]runtime.Object, len(appProjects))
|
||||
for i := range appProjects {
|
||||
ro[i] = &appProjects[i]
|
||||
}
|
||||
return fake.NewSimpleClientset(ro...).ArgoprojV1alpha1().AppProjects("deep-copy-ns")
|
||||
}
|
||||
|
||||
func Test_deepCopyArgoprojV1alpha1Client_RESTClient(t *testing.T) {
|
||||
fclientset := fake.NewSimpleClientset().ArgoprojV1alpha1()
|
||||
type fields struct {
|
||||
ArgoprojV1alpha1Interface clientset.ArgoprojV1alpha1Interface
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want rest.Interface
|
||||
}{
|
||||
{name: "RestClientGetter", fields: fields{ArgoprojV1alpha1Interface: fclientset}, want: fclientset.RESTClient()},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
d := &deepCopyArgoprojV1alpha1Client{
|
||||
ArgoprojV1alpha1Interface: tt.fields.ArgoprojV1alpha1Interface,
|
||||
}
|
||||
assert.Equalf(t, tt.want, d.RESTClient(), "RESTClient()")
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user