Skip to content

Commit 401ada2

Browse files
committed
fix: test setups
1 parent a2caad5 commit 401ada2

File tree

8 files changed

+87
-52
lines changed

8 files changed

+87
-52
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.concurrent.Callable;
66
import java.util.concurrent.ExecutionException;
77
import java.util.concurrent.ExecutorService;
8+
import java.util.concurrent.Executors;
89
import java.util.concurrent.Future;
910
import java.util.concurrent.TimeUnit;
1011
import java.util.concurrent.TimeoutException;
@@ -43,6 +44,12 @@ public static void stop() {
4344
instance = null;
4445
}
4546

47+
public static void useTestInstance() {
48+
if (instance == null) {
49+
instance = new ExecutorServiceManager(Executors.newFixedThreadPool(5), 1);
50+
}
51+
}
52+
4653
public static ExecutorServiceManager instance() {
4754
if (instance == null) {
4855
throw new IllegalStateException(

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class ReconciliationDispatcher<R extends HasMetadata> {
3434
private final Controller<R> controller;
3535
private final CustomResourceFacade<R> customResourceFacade;
3636

37-
ReconciliationDispatcher(Controller<R> controller,
38-
CustomResourceFacade<R> customResourceFacade) {
37+
ReconciliationDispatcher(Controller<R> controller, CustomResourceFacade<R> customResourceFacade) {
3938
this.controller = controller;
4039
this.customResourceFacade = customResourceFacade;
4140
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.javaoperatorsdk.operator;
2+
3+
import io.fabric8.kubernetes.api.model.HasMetadata;
4+
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
5+
import io.fabric8.kubernetes.client.KubernetesClient;
6+
import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable;
7+
import io.fabric8.kubernetes.client.dsl.FilterWatchListMultiDeletable;
8+
import io.fabric8.kubernetes.client.dsl.MixedOperation;
9+
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
10+
import io.fabric8.kubernetes.client.dsl.Resource;
11+
import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
12+
13+
import static org.mockito.ArgumentMatchers.anyLong;
14+
import static org.mockito.ArgumentMatchers.anyString;
15+
import static org.mockito.ArgumentMatchers.nullable;
16+
import static org.mockito.Mockito.mock;
17+
import static org.mockito.Mockito.when;
18+
19+
public class MockKubernetesClient {
20+
public static <T extends HasMetadata> KubernetesClient client(Class<T> clazz) {
21+
final var client = mock(KubernetesClient.class);
22+
MixedOperation<T, KubernetesResourceList<T>, Resource<T>> resources =
23+
mock(MixedOperation.class);
24+
NonNamespaceOperation<T, KubernetesResourceList<T>, Resource<T>> nonNamespaceOperation =
25+
mock(NonNamespaceOperation.class);
26+
FilterWatchListMultiDeletable<T, KubernetesResourceList<T>> inAnyNamespace = mock(
27+
FilterWatchListMultiDeletable.class);
28+
FilterWatchListDeletable<T, KubernetesResourceList<T>> filterable =
29+
mock(FilterWatchListDeletable.class);
30+
when(resources.inNamespace(anyString())).thenReturn(nonNamespaceOperation);
31+
when(nonNamespaceOperation.withLabelSelector(nullable(String.class))).thenReturn(filterable);
32+
when(resources.inAnyNamespace()).thenReturn(inAnyNamespace);
33+
when(inAnyNamespace.withLabelSelector(nullable(String.class))).thenReturn(filterable);
34+
SharedIndexInformer<T> informer = mock(SharedIndexInformer.class);
35+
when(filterable.runnableInformer(anyLong())).thenReturn(informer);
36+
when(client.resources(clazz)).thenReturn(resources);
37+
38+
39+
return client;
40+
}
41+
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/OperatorTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@
88
import io.fabric8.kubernetes.client.KubernetesClient;
99
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1010
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
11+
import io.javaoperatorsdk.operator.api.config.RetryConfiguration;
1112
import io.javaoperatorsdk.operator.api.reconciler.Context;
1213
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
1314
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
1415

1516
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
1617
import static org.mockito.Mockito.mock;
17-
import static org.mockito.Mockito.verify;
1818
import static org.mockito.Mockito.when;
1919

2020
class OperatorTest {
2121

22-
private final KubernetesClient kubernetesClient = mock(KubernetesClient.class);
22+
private final KubernetesClient kubernetesClient =
23+
MockKubernetesClient.client(FooCustomResource.class);
2324
private final ConfigurationService configurationService = mock(ConfigurationService.class);
2425
private final ControllerConfiguration configuration = mock(ControllerConfiguration.class);
2526

@@ -33,16 +34,14 @@ public void shouldRegisterReconcilerToController() {
3334
when(configurationService.getConfigurationFor(fooReconciler)).thenReturn(configuration);
3435
when(configuration.watchAllNamespaces()).thenReturn(true);
3536
when(configuration.getName()).thenReturn("FOO");
36-
when(configuration.getResourceClass()).thenReturn(FooReconciler.class);
37+
when(configuration.getResourceClass()).thenReturn(FooCustomResource.class);
38+
when(configuration.getRetryConfiguration()).thenReturn(RetryConfiguration.DEFAULT);
39+
when(configuration.getConfigurationService()).thenReturn(configurationService);
3740

3841
// when
3942
operator.register(fooReconciler);
4043

4144
// then
42-
verify(configuration).watchAllNamespaces();
43-
verify(configuration).getName();
44-
verify(configuration).getResourceClass();
45-
4645
assertThat(operator.getControllers().size()).isEqualTo(1);
4746
assertThat(operator.getControllers().get(0).getReconciler()).isEqualTo(fooReconciler);
4847
}

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
import io.fabric8.kubernetes.api.model.HasMetadata;
1111
import io.fabric8.kubernetes.api.model.ObjectMeta;
1212
import io.fabric8.kubernetes.client.CustomResource;
13+
import io.javaoperatorsdk.operator.MockKubernetesClient;
1314
import io.javaoperatorsdk.operator.TestUtils;
1415
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1516
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
17+
import io.javaoperatorsdk.operator.api.config.ExecutorServiceManager;
18+
import io.javaoperatorsdk.operator.api.config.RetryConfiguration;
1619
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
1720
import io.javaoperatorsdk.operator.api.reconciler.*;
1821
import io.javaoperatorsdk.operator.processing.Controller;
@@ -35,35 +38,41 @@ class ReconciliationDispatcherTest {
3538
private ReconciliationDispatcher<TestCustomResource> reconciliationDispatcher;
3639
private final Reconciler<TestCustomResource> reconciler = mock(Reconciler.class,
3740
withSettings().extraInterfaces(ErrorStatusHandler.class));
38-
private final ControllerConfiguration<TestCustomResource> configuration =
39-
mock(ControllerConfiguration.class);
4041
private final ConfigurationService configService = mock(ConfigurationService.class);
4142
private final CustomResourceFacade<TestCustomResource> customResourceFacade =
4243
mock(ReconciliationDispatcher.CustomResourceFacade.class);
4344

4445
@BeforeEach
4546
void setup() {
47+
ExecutorServiceManager.useTestInstance();
4648
testCustomResource = TestUtils.testCustomResource();
4749
reconciliationDispatcher =
48-
init(testCustomResource, reconciler, configuration, customResourceFacade);
50+
init(testCustomResource, reconciler, null, customResourceFacade, true);
4951
}
5052

5153
private <R extends HasMetadata> ReconciliationDispatcher<R> init(R customResource,
5254
Reconciler<R> reconciler, ControllerConfiguration<R> configuration,
53-
CustomResourceFacade<R> customResourceFacade) {
54-
when(configuration.getFinalizer()).thenReturn(DEFAULT_FINALIZER);
55+
CustomResourceFacade<R> customResourceFacade, boolean useFinalizer) {
56+
configuration = configuration == null ? mock(ControllerConfiguration.class) : configuration;
57+
final var finalizer = useFinalizer ? DEFAULT_FINALIZER : Constants.NO_FINALIZER;
58+
when(configuration.getFinalizer()).thenReturn(finalizer);
5559
when(configuration.useFinalizer()).thenCallRealMethod();
5660
when(configuration.getName()).thenReturn("EventDispatcherTestController");
57-
when(configService.getMetrics()).thenReturn(Metrics.NOOP);
61+
when(configuration.getResourceClass()).thenReturn((Class<R>) customResource.getClass());
62+
when(configuration.getRetryConfiguration()).thenReturn(RetryConfiguration.DEFAULT);
5863
when(configuration.getConfigurationService()).thenReturn(configService);
64+
65+
when(configService.getMetrics()).thenReturn(Metrics.NOOP);
5966
when(configService.getResourceCloner()).thenReturn(ConfigurationService.DEFAULT_CLONER);
67+
6068
when(reconciler.reconcile(eq(customResource), any()))
6169
.thenReturn(UpdateControl.updateResource(customResource));
6270
when(reconciler.cleanup(eq(customResource), any()))
6371
.thenReturn(DeleteControl.defaultDelete());
6472
when(customResourceFacade.replaceWithLock(any())).thenReturn(null);
65-
Controller<R> controller =
66-
new Controller<>(reconciler, configuration, null);
73+
Controller<R> controller = new Controller<>(reconciler, configuration,
74+
MockKubernetesClient.client(customResource.getClass()));
75+
controller.start();
6776

6877
return new ReconciliationDispatcher<>(controller, customResourceFacade);
6978
}
@@ -140,10 +149,12 @@ void callsDeleteIfObjectHasFinalizerAndMarkedForDelete() {
140149
*/
141150
@Test
142151
void callDeleteOnControllerIfMarkedForDeletionWhenNoFinalizerIsConfigured() {
143-
configureToNotUseFinalizer();
152+
final ReconciliationDispatcher<TestCustomResource> dispatcher =
153+
init(testCustomResource, reconciler,
154+
null, customResourceFacade, false);
144155
markForDeletion(testCustomResource);
145156

146-
reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource));
157+
dispatcher.handleExecution(executionScopeWithCREvent(testCustomResource));
147158

148159
verify(reconciler).cleanup(eq(testCustomResource), any());
149160
}
@@ -157,23 +168,13 @@ void doNotCallDeleteIfMarkedForDeletionWhenFinalizerHasAlreadyBeenRemoved() {
157168
verify(reconciler, never()).cleanup(eq(testCustomResource), any());
158169
}
159170

160-
private void configureToNotUseFinalizer() {
161-
ControllerConfiguration<HasMetadata> configuration =
162-
mock(ControllerConfiguration.class);
163-
when(configuration.getName()).thenReturn("EventDispatcherTestController");
164-
when(configService.getMetrics()).thenReturn(Metrics.NOOP);
165-
when(configuration.getConfigurationService()).thenReturn(configService);
166-
when(configuration.useFinalizer()).thenReturn(false);
167-
reconciliationDispatcher =
168-
new ReconciliationDispatcher(new Controller(reconciler, configuration, null),
169-
customResourceFacade);
170-
}
171-
172171
@Test
173172
void doesNotAddFinalizerIfConfiguredNotTo() {
174-
configureToNotUseFinalizer();
173+
final ReconciliationDispatcher<TestCustomResource> dispatcher =
174+
init(testCustomResource, reconciler,
175+
null, customResourceFacade, false);
175176

176-
reconciliationDispatcher.handleExecution(executionScopeWithCREvent(testCustomResource));
177+
dispatcher.handleExecution(executionScopeWithCREvent(testCustomResource));
177178

178179
assertEquals(0, testCustomResource.getMetadata().getFinalizers().size());
179180
}
@@ -312,7 +313,7 @@ void setObservedGenerationForStatusIfNeeded() {
312313
ControllerConfiguration<ObservedGenCustomResource> config =
313314
mock(ControllerConfiguration.class);
314315
CustomResourceFacade<ObservedGenCustomResource> facade = mock(CustomResourceFacade.class);
315-
var dispatcher = init(observedGenResource, reconciler, config, facade);
316+
var dispatcher = init(observedGenResource, reconciler, config, facade, true);
316317

317318
when(config.isGenerationAware()).thenReturn(true);
318319
when(reconciler.reconcile(any(), any()))
@@ -337,7 +338,7 @@ void updatesObservedGenerationOnNoUpdateUpdateControl() {
337338
when(reconciler.reconcile(any(), any()))
338339
.thenReturn(UpdateControl.noUpdate());
339340
when(facade.updateStatus(observedGenResource)).thenReturn(observedGenResource);
340-
var dispatcher = init(observedGenResource, reconciler, config, facade);
341+
var dispatcher = init(observedGenResource, reconciler, config, facade, true);
341342

342343
PostExecutionControl<ObservedGenCustomResource> control = dispatcher.handleExecution(
343344
executionScopeWithCREvent(observedGenResource));

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ControllerResourceEventSourceTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
1010
import io.fabric8.kubernetes.client.dsl.MixedOperation;
1111
import io.fabric8.kubernetes.client.dsl.Resource;
12+
import io.javaoperatorsdk.operator.MockKubernetesClient;
1213
import io.javaoperatorsdk.operator.TestUtils;
1314
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1415
import io.javaoperatorsdk.operator.api.config.DefaultControllerConfiguration;
@@ -28,7 +29,7 @@ class ControllerResourceEventSourceTest {
2829

2930
public static final String FINALIZER = "finalizer";
3031
private static final MixedOperation<TestCustomResource, KubernetesResourceList<TestCustomResource>, Resource<TestCustomResource>> client =
31-
mock(MixedOperation.class);
32+
MockKubernetesClient.client(TestCustomResource.class).resources(TestCustomResource.class);
3233
EventHandler eventHandler = mock(EventHandler.class);
3334
EventSourceRegistry registry = mock(EventSourceRegistry.class);
3435

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/ResourceEventFilterTest.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
import org.junit.jupiter.api.Test;
88

99
import io.fabric8.kubernetes.api.model.HasMetadata;
10-
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
1110
import io.fabric8.kubernetes.api.model.ObjectMeta;
12-
import io.fabric8.kubernetes.client.dsl.MixedOperation;
13-
import io.fabric8.kubernetes.client.dsl.Resource;
11+
import io.javaoperatorsdk.operator.MockKubernetesClient;
1412
import io.javaoperatorsdk.operator.TestUtils;
1513
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
1614
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
@@ -191,12 +189,7 @@ public ControllerConfig(String finalizer, boolean generationAware,
191189
private static class TestController extends Controller<TestCustomResource> {
192190

193191
public TestController(ControllerConfiguration<TestCustomResource> configuration) {
194-
super(null, configuration, null);
195-
}
196-
197-
@Override
198-
public MixedOperation<TestCustomResource, KubernetesResourceList<TestCustomResource>, Resource<TestCustomResource>> getCRClient() {
199-
return mock(MixedOperation.class);
192+
super(null, configuration, MockKubernetesClient.client(TestCustomResource.class));
200193
}
201194
}
202195

@@ -205,12 +198,7 @@ private static class ObservedGenController
205198

206199
public ObservedGenController(
207200
ControllerConfiguration<ObservedGenCustomResource> configuration) {
208-
super(null, configuration, null);
209-
}
210-
211-
@Override
212-
public MixedOperation<ObservedGenCustomResource, KubernetesResourceList<ObservedGenCustomResource>, Resource<ObservedGenCustomResource>> getCRClient() {
213-
return mock(MixedOperation.class);
201+
super(null, configuration, MockKubernetesClient.client(ObservedGenCustomResource.class));
214202
}
215203
}
216204
}

sample-operators/tomcat-operator/pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
<dependency>
3636
<groupId>org.apache.logging.log4j</groupId>
3737
<artifactId>log4j-slf4j-impl</artifactId>
38-
<version>2.13.3</version>
3938
</dependency>
4039
<dependency>
4140
<groupId>org.takes</groupId>

0 commit comments

Comments
 (0)