Skip to content

Commit 5d12dc2

Browse files
authored
Improve Expectation integration test (#3084)
Signed-off-by: David Sondermann <david.sondermann@hivemq.com>
1 parent fe2a54c commit 5d12dc2

File tree

4 files changed

+55
-59
lines changed

4 files changed

+55
-59
lines changed

docs/content/en/blog/releases/v5-2-release.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public class MyReconciler implements Reconciler<MyResource> {
9999

100100
@Override
101101
public UpdateControl<MyResource> reconcile(MyResource primary, Context<MyResource> context) {
102-
103102
// Exit early if expectation is not yet fulfilled or timed out
104103
if (expectationManager.ongoingExpectationPresent(primary, context)) {
105104
return UpdateControl.noUpdate();
@@ -109,7 +108,7 @@ public class MyReconciler implements Reconciler<MyResource> {
109108
if (deployment.isEmpty()) {
110109
createDeployment(primary, context);
111110
expectationManager.setExpectation(
112-
primary, Duration.ofSeconds(30), deploymentReadyExpectation(context));
111+
primary, Duration.ofSeconds(30), deploymentReadyExpectation());
113112
return UpdateControl.noUpdate();
114113
}
115114

docs/content/en/docs/documentation/reconciler.md

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ public class ExpectationReconciler implements Reconciler<ExpectationCustomResour
286286
@Override
287287
public UpdateControl<ExpectationCustomResource> reconcile(
288288
ExpectationCustomResource primary, Context<ExpectationCustomResource> context) {
289-
290289
// exiting asap if there is an expectation that is not timed out neither fulfilled yet
291290
if (expectationManager.ongoingExpectationPresent(primary, context)) {
292291
return UpdateControl.noUpdate();
@@ -296,13 +295,13 @@ public class ExpectationReconciler implements Reconciler<ExpectationCustomResour
296295
if (deployment.isEmpty()) {
297296
createDeployment(primary, context);
298297
expectationManager.setExpectation(
299-
primary, Duration.ofSeconds(timeout), deploymentReadyExpectation(context));
298+
primary, Duration.ofSeconds(timeout), deploymentReadyExpectation());
300299
return UpdateControl.noUpdate();
301300
} else {
302-
// checks if the expectation if it is fulfilled, and also removes it.
303-
//In your logic, you might add a next expectation based on your workflow.
304-
// Expectations have a name, so you can easily distinguish them if there is more of them.
305-
var res = expectationManager.checkExpectation("deploymentReadyExpectation",primary, context);
301+
// Checks the expectation and removes it once it is fulfilled.
302+
// In your logic you might add a next expectation based on your workflow.
303+
// Expectations have a name, so you can easily distinguish multiple expectations.
304+
var res = expectationManager.checkExpectation("deploymentReadyExpectation", primary, context);
306305
if (res.isFulfilled()) {
307306
return pathchStatusWithMessage(primary, DEPLOYMENT_READY);
308307
} else if (res.isTimedOut()) {
@@ -311,10 +310,6 @@ public class ExpectationReconciler implements Reconciler<ExpectationCustomResour
311310
}
312311
}
313312
return UpdateControl.noUpdate();
314-
315313
}
316314
}
317315
```
318-
319-
320-

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/expectation/ExpectationIT.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package io.javaoperatorsdk.operator.baseapi.expectation;
1717

18+
import java.time.Duration;
19+
1820
import org.junit.jupiter.api.Test;
1921
import org.junit.jupiter.api.extension.RegisterExtension;
2022

@@ -35,7 +37,7 @@ class ExpectationIT {
3537

3638
@Test
3739
void testExpectation() {
38-
extension.getReconcilerOfType(ExpectationReconciler.class).setTimeout(30000L);
40+
extension.getReconcilerOfType(ExpectationReconciler.class).setTimeout(Duration.ofSeconds(30));
3941
var res = testResource();
4042
extension.create(res);
4143

@@ -50,7 +52,7 @@ void testExpectation() {
5052

5153
@Test
5254
void expectationTimeouts() {
53-
extension.getReconcilerOfType(ExpectationReconciler.class).setTimeout(300L);
55+
extension.getReconcilerOfType(ExpectationReconciler.class).setTimeout(Duration.ofMillis(300));
5456
var res = testResource();
5557
extension.create(res);
5658

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/expectation/ExpectationReconciler.java

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.time.Duration;
1919
import java.util.List;
2020
import java.util.Map;
21+
import java.util.concurrent.atomic.AtomicReference;
2122

2223
import io.fabric8.kubernetes.api.model.ContainerBuilder;
2324
import io.fabric8.kubernetes.api.model.ContainerPortBuilder;
@@ -45,17 +46,21 @@ public class ExpectationReconciler implements Reconciler<ExpectationCustomResour
4546
public static final String DEPLOYMENT_READY = "Deployment ready";
4647
public static final String DEPLOYMENT_TIMEOUT = "Deployment timeout";
4748
public static final String DEPLOYMENT_READY_EXPECTATION_NAME = "deploymentReadyExpectation";
49+
4850
private final ExpectationManager<ExpectationCustomResource> expectationManager =
4951
new ExpectationManager<>();
52+
private final AtomicReference<Duration> timeoutRef =
53+
new AtomicReference<>(Duration.ofSeconds(30));
5054

51-
private volatile Long timeout = 30000l;
55+
public void setTimeout(Duration timeout) {
56+
timeoutRef.set(timeout);
57+
}
5258

5359
@Override
5460
public UpdateControl<ExpectationCustomResource> reconcile(
5561
ExpectationCustomResource primary, Context<ExpectationCustomResource> context) {
56-
5762
// cleans up expectation manager for the resource on delete event
58-
// in case of cleaner interface used, this can done also there.
63+
// in case of cleaner interface used, this can be done also there
5964
if (context.isPrimaryResourceDeleted()) {
6065
expectationManager.removeExpectation(primary);
6166
}
@@ -70,53 +75,41 @@ public UpdateControl<ExpectationCustomResource> reconcile(
7075
createDeployment(primary, context);
7176
var set =
7277
expectationManager.checkAndSetExpectation(
73-
primary, context, Duration.ofSeconds(timeout), deploymentReadyExpectation(context));
78+
primary, context, timeoutRef.get(), deploymentReadyExpectation());
7479
if (set) {
7580
return UpdateControl.noUpdate();
7681
}
7782
} else {
78-
// checks the expectation if it is fulfilled also removes it,
79-
// in your logic you might add a next expectation based on your workflow
80-
// Expectations have a name, so you can easily distinguish them if there is more of them.
83+
// Checks the expectation and removes it once it is fulfilled.
84+
// In your logic you might add a next expectation based on your workflow.
85+
// Expectations have a name, so you can easily distinguish multiple expectations.
8186
var res =
8287
expectationManager.checkExpectation(DEPLOYMENT_READY_EXPECTATION_NAME, primary, context);
83-
// Note that this happens only once, since if the expectation is fulfilled, it is also removed
84-
// from the manager.
88+
// note that this happens only once, since if the expectation is fulfilled, it is also removed
89+
// from the manager
8590
if (res.isFulfilled()) {
86-
return pathchStatusWithMessage(primary, DEPLOYMENT_READY);
91+
return patchStatusWithMessage(primary, DEPLOYMENT_READY);
8792
} else if (res.isTimedOut()) {
8893
// you might add some other timeout handling here
89-
return pathchStatusWithMessage(primary, DEPLOYMENT_TIMEOUT);
94+
return patchStatusWithMessage(primary, DEPLOYMENT_TIMEOUT);
9095
}
9196
}
9297
return UpdateControl.noUpdate();
9398
}
9499

95-
private static UpdateControl<ExpectationCustomResource> pathchStatusWithMessage(
96-
ExpectationCustomResource primary, String message) {
97-
primary.setStatus(new ExpectationCustomResourceStatus());
98-
primary.getStatus().setMessage(message);
99-
return UpdateControl.patchStatus(primary);
100-
}
101-
102-
private static Expectation<ExpectationCustomResource> deploymentReadyExpectation(
103-
Context<ExpectationCustomResource> context) {
104-
return Expectation.createExpectation(
105-
DEPLOYMENT_READY_EXPECTATION_NAME,
106-
(p, c) ->
107-
context
108-
.getSecondaryResource(Deployment.class)
109-
.map(
110-
ad ->
111-
ad.getStatus() != null
112-
&& ad.getStatus().getReadyReplicas() != null
113-
&& ad.getStatus().getReadyReplicas() == 3)
114-
.orElse(false));
100+
@Override
101+
public List<EventSource<?, ExpectationCustomResource>> prepareEventSources(
102+
EventSourceContext<ExpectationCustomResource> context) {
103+
return List.of(
104+
new InformerEventSource<>(
105+
InformerEventSourceConfiguration.from(Deployment.class, ExpectationCustomResource.class)
106+
.build(),
107+
context));
115108
}
116109

117-
private Deployment createDeployment(
110+
private static void createDeployment(
118111
ExpectationCustomResource primary, Context<ExpectationCustomResource> context) {
119-
var d =
112+
var deployment =
120113
new DeploymentBuilder()
121114
.withMetadata(
122115
new ObjectMetaBuilder()
@@ -147,21 +140,28 @@ private Deployment createDeployment(
147140
.build())
148141
.build())
149142
.build();
150-
d.addOwnerReference(primary);
151-
return context.getClient().resource(d).serverSideApply();
143+
deployment.addOwnerReference(primary);
144+
context.getClient().resource(deployment).serverSideApply();
152145
}
153146

154-
@Override
155-
public List<EventSource<?, ExpectationCustomResource>> prepareEventSources(
156-
EventSourceContext<ExpectationCustomResource> context) {
157-
return List.of(
158-
new InformerEventSource<>(
159-
InformerEventSourceConfiguration.from(Deployment.class, ExpectationCustomResource.class)
160-
.build(),
161-
context));
147+
private static Expectation<ExpectationCustomResource> deploymentReadyExpectation() {
148+
return Expectation.createExpectation(
149+
DEPLOYMENT_READY_EXPECTATION_NAME,
150+
(primary, context) ->
151+
context
152+
.getSecondaryResource(Deployment.class)
153+
.map(
154+
ad ->
155+
ad.getStatus() != null
156+
&& ad.getStatus().getReadyReplicas() != null
157+
&& ad.getStatus().getReadyReplicas() == 3)
158+
.orElse(false));
162159
}
163160

164-
public void setTimeout(Long timeout) {
165-
this.timeout = timeout;
161+
private static UpdateControl<ExpectationCustomResource> patchStatusWithMessage(
162+
ExpectationCustomResource primary, String message) {
163+
primary.setStatus(new ExpectationCustomResourceStatus());
164+
primary.getStatus().setMessage(message);
165+
return UpdateControl.patchStatus(primary);
166166
}
167167
}

0 commit comments

Comments
 (0)