This is an automated email from the ASF dual-hosted git repository. squakez pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 514e775aa83a85611830dd11ed31215f4cb263e4 Author: chaojixinren <[email protected]> AuthorDate: Thu Apr 16 10:13:26 2026 +0800 chore(controller): move action declarations from reconcile to init Closes #6567 Made-with: Cursor --- pkg/controller/catalog/catalog_controller.go | 27 ++- pkg/controller/catalog/catalog_controller_test.go | 44 +++++ .../integration/integration_controller.go | 56 ++++-- .../integration/integration_controller_test.go | 202 ++++----------------- .../integrationkit/integrationkit_controller.go | 31 +++- .../integrationkit_controller_test.go | 50 +++++ .../integrationplatform_controller.go | 29 ++- .../integrationplatform_controller_test.go | 47 +++++ pkg/controller/pipe/pipe_controller.go | 27 ++- pkg/controller/pipe/pipe_controller_test.go | 44 +++++ 10 files changed, 342 insertions(+), 215 deletions(-) diff --git a/pkg/controller/catalog/catalog_controller.go b/pkg/controller/catalog/catalog_controller.go index 58aa4eacb..1294c82ed 100644 --- a/pkg/controller/catalog/catalog_controller.go +++ b/pkg/controller/catalog/catalog_controller.go @@ -45,6 +45,8 @@ const ( requeueAfterDuration = 5 * time.Second ) +type actionFactory func() Action + // Add creates a new Catalog Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -57,6 +59,10 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-catalog-controller"), + actionFactories: []actionFactory{ + NewInitializeAction, + NewMonitorAction, + }, }, schema.GroupVersionKind{ Group: v1.SchemeGroupVersion.Group, @@ -104,9 +110,19 @@ var _ reconcile.Reconciler = &reconcileCatalog{} type reconcileCatalog struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + actionFactories []actionFactory +} + +func (r *reconcileCatalog) newActions() []Action { + actions := make([]Action, 0, len(r.actionFactories)) + for _, newAction := range r.actionFactories { + actions = append(actions, newAction()) + } + + return actions } // Reconcile reads that state of the cluster for a catalog object and makes changes based @@ -150,10 +166,7 @@ func (r *reconcileCatalog) Reconcile(ctx context.Context, request reconcile.Requ return reconcile.Result{}, nil } - actions := []Action{ - NewInitializeAction(), - NewMonitorAction(), - } + actions := r.newActions() var targetPhase v1.CamelCatalogPhase var err error diff --git a/pkg/controller/catalog/catalog_controller_test.go b/pkg/controller/catalog/catalog_controller_test.go new file mode 100644 index 000000000..7ed735228 --- /dev/null +++ b/pkg/controller/catalog/catalog_controller_test.go @@ -0,0 +1,44 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package catalog + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewActions(t *testing.T) { + reconciler := reconcileCatalog{ + actionFactories: []actionFactory{ + NewInitializeAction, + NewMonitorAction, + }, + } + + actions := reconciler.newActions() + require.Len(t, actions, 2) + + assert.IsType(t, &initializeAction{}, actions[0]) + assert.IsType(t, &monitorAction{}, actions[1]) + + nextActions := reconciler.newActions() + assert.NotSame(t, actions[0], nextActions[0]) + assert.NotSame(t, actions[1], nextActions[1]) +} diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go index e9de81d93..9c8e084d4 100644 --- a/pkg/controller/integration/integration_controller.go +++ b/pkg/controller/integration/integration_controller.go @@ -58,6 +58,8 @@ import ( const retryMonitoring = 5 +type actionFactory func() Action + func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { err := mgr.GetFieldIndexer().IndexField(ctx, &corev1.Pod{}, "status.phase", func(obj ctrl.Object) []string { @@ -79,6 +81,20 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-integration-controller"), + baseActionFactories: []actionFactory{ + NewPlatformSetupAction, + NewInitializeAction, + NewBuildAction, + newBuildKitAction, + NewBuildCompleteAction, + }, + syntheticActionFactories: []actionFactory{ + NewMonitorSyntheticAction, + }, + nonSyntheticActionFactories: []actionFactory{ + NewMonitorAction, + NewMonitorUnknownAction, + }, }, schema.GroupVersionKind{ Group: v1.SchemeGroupVersion.Group, @@ -453,9 +469,29 @@ var _ reconcile.Reconciler = &reconcileIntegration{} type reconcileIntegration struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + baseActionFactories []actionFactory + syntheticActionFactories []actionFactory + nonSyntheticActionFactories []actionFactory +} + +func (r *reconcileIntegration) newActions(synthetic bool) []Action { + factories := make([]actionFactory, 0, len(r.baseActionFactories)+len(r.syntheticActionFactories)) + factories = append(factories, r.baseActionFactories...) + if synthetic { + factories = append(factories, r.syntheticActionFactories...) + } else { + factories = append(factories, r.nonSyntheticActionFactories...) + } + + actions := make([]Action, 0, len(factories)) + for _, newAction := range factories { + actions = append(actions, newAction()) + } + + return actions } // Reconcile reads that state of the cluster for an Integration object and makes changes based on the state read @@ -500,19 +536,7 @@ func (r *reconcileIntegration) Reconcile(ctx context.Context, request reconcile. target := instance.DeepCopy() targetLog := rlog.ForIntegration(target) - actions := []Action{ - NewPlatformSetupAction(), - NewInitializeAction(), - NewBuildAction(), - newBuildKitAction(), - NewBuildCompleteAction(), - } - - if instance.IsSynthetic() { - actions = append(actions, NewMonitorSyntheticAction()) - } else { - actions = append(actions, NewMonitorAction(), NewMonitorUnknownAction()) - } + actions := r.newActions(instance.IsSynthetic()) for _, a := range actions { a.InjectClient(r.client) diff --git a/pkg/controller/integration/integration_controller_test.go b/pkg/controller/integration/integration_controller_test.go index 31403528b..f019cac14 100644 --- a/pkg/controller/integration/integration_controller_test.go +++ b/pkg/controller/integration/integration_controller_test.go @@ -19,186 +19,52 @@ package integration import ( "testing" - "time" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/stretchr/testify/require" ) -func TestIsIntegrationUpdated(t *testing.T) { - now := metav1.Now() - - tests := []struct { - name string - it *v1.Integration - previous *v1.IntegrationCondition - next *v1.IntegrationCondition - expected bool - }{ - { - name: "should return true when transitioning to ready", - it: &v1.Integration{ - Status: v1.IntegrationStatus{ - InitializationTimestamp: &now, - }, - }, - previous: nil, - next: &v1.IntegrationCondition{ - Status: corev1.ConditionTrue, - FirstTruthyTime: &now, - }, - expected: true, - }, - { - name: "should return false when no InitializationTimestamp", - it: &v1.Integration{ - Status: v1.IntegrationStatus{}, - }, - previous: nil, - next: &v1.IntegrationCondition{ - Status: corev1.ConditionTrue, - FirstTruthyTime: &now, - }, - expected: false, - }, - { - name: "should return false when already ready", - it: &v1.Integration{ - Status: v1.IntegrationStatus{ - InitializationTimestamp: &now, - }, - }, - previous: &v1.IntegrationCondition{ - Status: corev1.ConditionTrue, - FirstTruthyTime: &now, - }, - next: &v1.IntegrationCondition{ - Status: corev1.ConditionTrue, - FirstTruthyTime: &now, - }, - expected: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := isIntegrationUpdated(tt.it, tt.previous, tt.next) - assert.Equal(t, tt.expected, result) - }) - } -} - -func TestReadinessTimestampCalculation(t *testing.T) { - initTime := metav1.NewTime(time.Date(2025, 1, 1, 10, 0, 0, 0, time.UTC)) - deployTime := metav1.NewTime(time.Date(2025, 1, 1, 12, 0, 0, 0, time.UTC)) - readyTime := metav1.NewTime(time.Date(2025, 1, 1, 12, 5, 0, 0, time.UTC)) - zeroTime := metav1.Time{} - - tests := []struct { - name string - initializationTimestamp *metav1.Time - deploymentTimestamp *metav1.Time - firstTruthyTime *metav1.Time - expectedDuration time.Duration - description string - }{ - { - name: "normal build - uses InitializationTimestamp", - initializationTimestamp: &initTime, - deploymentTimestamp: nil, - firstTruthyTime: &readyTime, - expectedDuration: 2*time.Hour + 5*time.Minute, - description: "Without DeploymentTimestamp, should use InitializationTimestamp", +func TestNewActions(t *testing.T) { + reconciler := reconcileIntegration{ + baseActionFactories: []actionFactory{ + NewPlatformSetupAction, + NewInitializeAction, + NewBuildAction, + newBuildKitAction, + NewBuildCompleteAction, }, - { - name: "dry build - uses DeploymentTimestamp", - initializationTimestamp: &initTime, - deploymentTimestamp: &deployTime, - firstTruthyTime: &readyTime, - expectedDuration: 5 * time.Minute, - description: "With DeploymentTimestamp, should use it instead of InitializationTimestamp", + syntheticActionFactories: []actionFactory{ + NewMonitorSyntheticAction, }, - { - name: "DeploymentTimestamp is zero - falls back to InitializationTimestamp", - initializationTimestamp: &initTime, - deploymentTimestamp: &zeroTime, - firstTruthyTime: &readyTime, - expectedDuration: 2*time.Hour + 5*time.Minute, - description: "Zero DeploymentTimestamp should fall back to InitializationTimestamp", + nonSyntheticActionFactories: []actionFactory{ + NewMonitorAction, + NewMonitorUnknownAction, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - it := &v1.Integration{ - Status: v1.IntegrationStatus{ - InitializationTimestamp: tt.initializationTimestamp, - DeploymentTimestamp: tt.deploymentTimestamp, - }, - } + t.Run("non-synthetic", func(t *testing.T) { + actions := reconciler.newActions(false) + require.Len(t, actions, 7) - startTime := it.Status.InitializationTimestamp.Time - if it.Status.DeploymentTimestamp != nil && !it.Status.DeploymentTimestamp.IsZero() { - startTime = it.Status.DeploymentTimestamp.Time - } - duration := tt.firstTruthyTime.Sub(startTime) - assert.Equal(t, tt.expectedDuration, duration, tt.description) - }) - } -} + assert.IsType(t, &platformSetupAction{}, actions[0]) + assert.IsType(t, &initializeAction{}, actions[1]) + assert.IsType(t, &buildAction{}, actions[2]) + assert.IsType(t, &buildKitAction{}, actions[3]) + assert.IsType(t, &buildCompleteAction{}, actions[4]) + assert.IsType(t, &monitorAction{}, actions[5]) + assert.IsType(t, &monitorUnknownAction{}, actions[6]) -func TestDeploymentTimestampIsSet(t *testing.T) { - tests := []struct { - name string - hasDontRunAnnotation bool - expectedPhase v1.IntegrationPhase - expectDeploymentTimestamp bool - }{ - { - name: "normal build sets DeploymentTimestamp", - hasDontRunAnnotation: false, - expectedPhase: v1.IntegrationPhaseDeploying, - expectDeploymentTimestamp: true, - }, - { - name: "dry build does not set DeploymentTimestamp yet", - hasDontRunAnnotation: true, - expectedPhase: v1.IntegrationPhaseBuildComplete, - expectDeploymentTimestamp: false, - }, - } + nextActions := reconciler.newActions(false) + assert.NotSame(t, actions[0], nextActions[0]) + }) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - it := &v1.Integration{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{}, - }, - Status: v1.IntegrationStatus{}, - } + t.Run("synthetic", func(t *testing.T) { + actions := reconciler.newActions(true) + require.Len(t, actions, 6) - if tt.hasDontRunAnnotation { - it.Annotations[v1.IntegrationDontRunAfterBuildAnnotation] = v1.IntegrationDontRunAfterBuildAnnotationTrueValue - } + assert.IsType(t, &monitorSyntheticAction{}, actions[5]) - if it.Annotations[v1.IntegrationDontRunAfterBuildAnnotation] == v1.IntegrationDontRunAfterBuildAnnotationTrueValue { - it.Status.Phase = v1.IntegrationPhaseBuildComplete - } else { - now := metav1.Now().Rfc3339Copy() - it.Status.DeploymentTimestamp = &now - it.Status.Phase = v1.IntegrationPhaseDeploying - } - - assert.Equal(t, tt.expectedPhase, it.Status.Phase) - if tt.expectDeploymentTimestamp { - assert.NotNil(t, it.Status.DeploymentTimestamp) - assert.False(t, it.Status.DeploymentTimestamp.IsZero()) - } else { - assert.Nil(t, it.Status.DeploymentTimestamp) - } - }) - } + nextActions := reconciler.newActions(true) + assert.NotSame(t, actions[0], nextActions[0]) + }) } diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go index 8456db539..95ece1c5c 100644 --- a/pkg/controller/integrationkit/integrationkit_controller.go +++ b/pkg/controller/integrationkit/integrationkit_controller.go @@ -48,6 +48,8 @@ const ( requeueAfterDuration = 2 * time.Second ) +type actionFactory func() Action + // Add creates a new IntegrationKit Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -60,6 +62,12 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-integration-kit-controller"), + actionFactories: []actionFactory{ + NewInitializeAction, + NewBuildAction, + NewMonitorAction, + NewErrorAction, + }, }, schema.GroupVersionKind{ Group: v1.SchemeGroupVersion.Group, @@ -180,9 +188,19 @@ var _ reconcile.Reconciler = &reconcileIntegrationKit{} type reconcileIntegrationKit struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + actionFactories []actionFactory +} + +func (r *reconcileIntegrationKit) newActions() []Action { + actions := make([]Action, 0, len(r.actionFactories)) + for _, newAction := range r.actionFactories { + actions = append(actions, newAction()) + } + + return actions } // Reconcile reads that state of the cluster for a IntegrationKit object and makes changes based on the state read @@ -263,12 +281,7 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci return reconcile.Result{}, err } - actions := []Action{ - NewInitializeAction(), - NewBuildAction(), - NewMonitorAction(), - NewErrorAction(), - } + actions := r.newActions() targetPhase := instance.Status.Phase diff --git a/pkg/controller/integrationkit/integrationkit_controller_test.go b/pkg/controller/integrationkit/integrationkit_controller_test.go new file mode 100644 index 000000000..694aba5e0 --- /dev/null +++ b/pkg/controller/integrationkit/integrationkit_controller_test.go @@ -0,0 +1,50 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integrationkit + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewActions(t *testing.T) { + reconciler := reconcileIntegrationKit{ + actionFactories: []actionFactory{ + NewInitializeAction, + NewBuildAction, + NewMonitorAction, + NewErrorAction, + }, + } + + actions := reconciler.newActions() + require.Len(t, actions, 4) + + assert.IsType(t, &initializeAction{}, actions[0]) + assert.IsType(t, &buildAction{}, actions[1]) + assert.IsType(t, &monitorAction{}, actions[2]) + assert.IsType(t, &errorAction{}, actions[3]) + + nextActions := reconciler.newActions() + assert.NotSame(t, actions[0], nextActions[0]) + assert.NotSame(t, actions[1], nextActions[1]) + assert.NotSame(t, actions[2], nextActions[2]) + assert.NotSame(t, actions[3], nextActions[3]) +} diff --git a/pkg/controller/integrationplatform/integrationplatform_controller.go b/pkg/controller/integrationplatform/integrationplatform_controller.go index 1efbce909..bddf866f4 100644 --- a/pkg/controller/integrationplatform/integrationplatform_controller.go +++ b/pkg/controller/integrationplatform/integrationplatform_controller.go @@ -40,6 +40,8 @@ import ( "github.com/apache/camel-k/v2/pkg/util/monitoring" ) +type actionFactory func() Action + // Add creates a new IntegrationPlatform Controller and adds it to the Manager. The Manager will set fields // on the Controller and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -53,6 +55,11 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { reader: mgr.GetAPIReader(), scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-integration-platform-controller"), + actionFactories: []actionFactory{ + NewInitializeAction, + NewCreateAction, + NewMonitorAction, + }, }, schema.GroupVersionKind{ Group: v1.SchemeGroupVersion.Group, @@ -104,9 +111,19 @@ type reconcileIntegrationPlatform struct { // that reads objects from the cache and writes to the API server client client.Client // Non-caching client - reader ctrl.Reader - scheme *runtime.Scheme - recorder events.EventRecorder + reader ctrl.Reader + scheme *runtime.Scheme + recorder events.EventRecorder + actionFactories []actionFactory +} + +func (r *reconcileIntegrationPlatform) newActions() []Action { + actions := make([]Action, 0, len(r.actionFactories)) + for _, newAction := range r.actionFactories { + actions = append(actions, newAction()) + } + + return actions } // Reconcile reads that state of the cluster for a IntegrationPlatform object and makes changes based @@ -150,11 +167,7 @@ func (r *reconcileIntegrationPlatform) Reconcile(ctx context.Context, request re return reconcile.Result{}, nil } - actions := []Action{ - NewInitializeAction(), - NewCreateAction(), - NewMonitorAction(), - } + actions := r.newActions() var targetPhase v1.IntegrationPlatformPhase var err error diff --git a/pkg/controller/integrationplatform/integrationplatform_controller_test.go b/pkg/controller/integrationplatform/integrationplatform_controller_test.go new file mode 100644 index 000000000..2497a5fe2 --- /dev/null +++ b/pkg/controller/integrationplatform/integrationplatform_controller_test.go @@ -0,0 +1,47 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integrationplatform + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewActions(t *testing.T) { + reconciler := reconcileIntegrationPlatform{ + actionFactories: []actionFactory{ + NewInitializeAction, + NewCreateAction, + NewMonitorAction, + }, + } + + actions := reconciler.newActions() + require.Len(t, actions, 3) + + assert.IsType(t, &initializeAction{}, actions[0]) + assert.IsType(t, &createAction{}, actions[1]) + assert.IsType(t, &monitorAction{}, actions[2]) + + nextActions := reconciler.newActions() + assert.NotSame(t, actions[0], nextActions[0]) + assert.NotSame(t, actions[1], nextActions[1]) + assert.NotSame(t, actions[2], nextActions[2]) +} diff --git a/pkg/controller/pipe/pipe_controller.go b/pkg/controller/pipe/pipe_controller.go index ca8762ed6..e3130e92a 100644 --- a/pkg/controller/pipe/pipe_controller.go +++ b/pkg/controller/pipe/pipe_controller.go @@ -44,6 +44,8 @@ import ( "github.com/apache/camel-k/v2/pkg/util/monitoring" ) +type actionFactory func() Action + // Add creates a new Pipe Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(ctx context.Context, mgr manager.Manager, c client.Client) error { @@ -56,6 +58,10 @@ func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { client: c, scheme: mgr.GetScheme(), recorder: mgr.GetEventRecorder("camel-k-pipe-controller"), + actionFactories: []actionFactory{ + NewInitializeAction, + NewMonitorAction, + }, }, schema.GroupVersionKind{ Group: v1.SchemeGroupVersion.Group, @@ -132,9 +138,19 @@ var _ reconcile.Reconciler = &ReconcilePipe{} type ReconcilePipe struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the API server - client client.Client - scheme *runtime.Scheme - recorder events.EventRecorder + client client.Client + scheme *runtime.Scheme + recorder events.EventRecorder + actionFactories []actionFactory +} + +func (r *ReconcilePipe) newActions() []Action { + actions := make([]Action, 0, len(r.actionFactories)) + for _, newAction := range r.actionFactories { + actions = append(actions, newAction()) + } + + return actions } // Reconcile reads that state of the cluster for a Pipe object and makes changes based @@ -178,10 +194,7 @@ func (r *ReconcilePipe) Reconcile(ctx context.Context, request reconcile.Request return reconcile.Result{}, nil } - actions := []Action{ - NewInitializeAction(), - NewMonitorAction(), - } + actions := r.newActions() var err error diff --git a/pkg/controller/pipe/pipe_controller_test.go b/pkg/controller/pipe/pipe_controller_test.go new file mode 100644 index 000000000..9772cd994 --- /dev/null +++ b/pkg/controller/pipe/pipe_controller_test.go @@ -0,0 +1,44 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pipe + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewActions(t *testing.T) { + reconciler := ReconcilePipe{ + actionFactories: []actionFactory{ + NewInitializeAction, + NewMonitorAction, + }, + } + + actions := reconciler.newActions() + require.Len(t, actions, 2) + + assert.IsType(t, &initializeAction{}, actions[0]) + assert.IsType(t, &monitorAction{}, actions[1]) + + nextActions := reconciler.newActions() + assert.NotSame(t, actions[0], nextActions[0]) + assert.NotSame(t, actions[1], nextActions[1]) +}
