Skip to content

Commit 2073e65

Browse files
committed
test case for reported issue
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent 819b044 commit 2073e65

File tree

7 files changed

+300
-0
lines changed

7 files changed

+300
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import io.fabric8.kubernetes.api.model.ConfigMap;
19+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
20+
import io.javaoperatorsdk.operator.api.reconciler.Context;
21+
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
22+
23+
public class ConfigMapDependentResource
24+
extends CRUDKubernetesDependentResource<ConfigMap, PreconditionAndActivationCustomResource> {
25+
26+
@Override
27+
protected ConfigMap desired(
28+
PreconditionAndActivationCustomResource primary,
29+
Context<PreconditionAndActivationCustomResource> context) {
30+
ConfigMap configMap = new ConfigMap();
31+
configMap.setMetadata(
32+
new ObjectMetaBuilder()
33+
.withName(primary.getMetadata().getName())
34+
.withNamespace(primary.getMetadata().getNamespace())
35+
.build());
36+
return configMap;
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import io.fabric8.kubernetes.api.model.Secret;
19+
import io.javaoperatorsdk.operator.api.reconciler.Context;
20+
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
21+
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
22+
23+
public class FalseActivationCondition
24+
implements Condition<Secret, PreconditionAndActivationCustomResource> {
25+
@Override
26+
public boolean isMet(
27+
DependentResource<Secret, PreconditionAndActivationCustomResource> dependentResource,
28+
PreconditionAndActivationCustomResource primary,
29+
Context<PreconditionAndActivationCustomResource> context) {
30+
return false;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import io.fabric8.kubernetes.api.model.ConfigMap;
19+
import io.javaoperatorsdk.operator.api.reconciler.Context;
20+
import io.javaoperatorsdk.operator.api.reconciler.dependent.DependentResource;
21+
import io.javaoperatorsdk.operator.processing.dependent.workflow.Condition;
22+
23+
public class FalseReconcilePrecondition
24+
implements Condition<ConfigMap, PreconditionAndActivationCustomResource> {
25+
@Override
26+
public boolean isMet(
27+
DependentResource<ConfigMap, PreconditionAndActivationCustomResource> dependentResource,
28+
PreconditionAndActivationCustomResource primary,
29+
Context<PreconditionAndActivationCustomResource> context) {
30+
return false;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import io.fabric8.kubernetes.api.model.Namespaced;
19+
import io.fabric8.kubernetes.client.CustomResource;
20+
import io.fabric8.kubernetes.model.annotation.Group;
21+
import io.fabric8.kubernetes.model.annotation.ShortNames;
22+
import io.fabric8.kubernetes.model.annotation.Version;
23+
24+
@Group("sample.javaoperatorsdk")
25+
@Version("v1")
26+
@ShortNames("paa")
27+
public class PreconditionAndActivationCustomResource extends CustomResource<Void, Void>
28+
implements Namespaced {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.extension.RegisterExtension;
20+
21+
import io.fabric8.kubernetes.api.model.ConfigMap;
22+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
23+
import io.fabric8.kubernetes.api.model.Secret;
24+
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
import static org.awaitility.Awaitility.await;
28+
29+
class PreconditionAndActivationIT {
30+
31+
public static final String TEST_RESOURCE_NAME = "test1";
32+
33+
@RegisterExtension
34+
LocallyRunOperatorExtension extension =
35+
LocallyRunOperatorExtension.builder()
36+
.withReconciler(PreconditionAndActivationReconciler.class)
37+
.build();
38+
39+
@Test
40+
void handlesFalsePreconditionWithNonActive() {
41+
extension.create(testResource());
42+
43+
await()
44+
.untilAsserted(
45+
() -> {
46+
assertThat(
47+
extension
48+
.getReconcilerOfType(PreconditionAndActivationReconciler.class)
49+
.getNumberOfReconciliationExecution())
50+
.isPositive();
51+
});
52+
53+
// Neither resource should be created
54+
var cm = extension.get(ConfigMap.class, TEST_RESOURCE_NAME);
55+
assertThat(cm).isNull();
56+
var secret = extension.get(Secret.class, TEST_RESOURCE_NAME);
57+
assertThat(secret).isNull();
58+
}
59+
60+
private PreconditionAndActivationCustomResource testResource() {
61+
var res = new PreconditionAndActivationCustomResource();
62+
res.setMetadata(new ObjectMetaBuilder().withName(TEST_RESOURCE_NAME).build());
63+
return res;
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import java.util.concurrent.atomic.AtomicInteger;
19+
20+
import io.javaoperatorsdk.operator.api.reconciler.Context;
21+
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
22+
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
23+
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
24+
import io.javaoperatorsdk.operator.api.reconciler.Workflow;
25+
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
26+
27+
@Workflow(
28+
dependents = {
29+
@Dependent(
30+
name = "configmap",
31+
type = ConfigMapDependentResource.class,
32+
reconcilePrecondition = FalseReconcilePrecondition.class),
33+
@Dependent(
34+
type = SecretDependentResource.class,
35+
activationCondition = FalseActivationCondition.class,
36+
dependsOn = "configmap")
37+
})
38+
@ControllerConfiguration
39+
public class PreconditionAndActivationReconciler
40+
implements Reconciler<PreconditionAndActivationCustomResource> {
41+
42+
private final AtomicInteger numberOfReconciliationExecution = new AtomicInteger(0);
43+
44+
@Override
45+
public UpdateControl<PreconditionAndActivationCustomResource> reconcile(
46+
PreconditionAndActivationCustomResource resource,
47+
Context<PreconditionAndActivationCustomResource> context) {
48+
49+
var workflowResult =
50+
context
51+
.managedWorkflowAndDependentResourceContext()
52+
.getWorkflowReconcileResult()
53+
.orElseThrow();
54+
var erroredDependents = workflowResult.getErroredDependents();
55+
if (!erroredDependents.isEmpty()) {
56+
throw new RuntimeException(
57+
"Unexpected workflow error", erroredDependents.values().iterator().next());
58+
}
59+
60+
numberOfReconciliationExecution.incrementAndGet();
61+
return UpdateControl.noUpdate();
62+
}
63+
64+
public int getNumberOfReconciliationExecution() {
65+
return numberOfReconciliationExecution.get();
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright Java Operator SDK Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.javaoperatorsdk.operator.workflow.preconditionandactivation;
17+
18+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
19+
import io.fabric8.kubernetes.api.model.Secret;
20+
import io.javaoperatorsdk.operator.api.reconciler.Context;
21+
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
22+
23+
public class SecretDependentResource
24+
extends CRUDKubernetesDependentResource<Secret, PreconditionAndActivationCustomResource> {
25+
26+
@Override
27+
protected Secret desired(
28+
PreconditionAndActivationCustomResource primary,
29+
Context<PreconditionAndActivationCustomResource> context) {
30+
Secret secret = new Secret();
31+
secret.setMetadata(
32+
new ObjectMetaBuilder()
33+
.withName(primary.getMetadata().getName())
34+
.withNamespace(primary.getMetadata().getNamespace())
35+
.build());
36+
return secret;
37+
}
38+
}

0 commit comments

Comments
 (0)