use of org.entando.kubernetes.test.common.ValueHolder in project entando-k8s-controller-coordinator by entando-k8s.
the class ControllerCoordinatorProcessingCriteriaTest method testGenerationObservedIsCurrentButForceInstructed.
@Test
@Description("Resource modification events should be processed when using the annotation 'entando.org/processing-instruction=force' even " + "when the 'generation' property on the metadata of the resource is the same as the 'observedGeneration' property on" + " its status")
void testGenerationObservedIsCurrentButForceInstructed() {
step("Given the Coordinator observes this namespace", () -> System.setProperty(EntandoOperatorConfigProperty.ENTANDO_NAMESPACES_TO_OBSERVE.getJvmSystemProperty(), OBSERVED_NAMESPACE));
final ValueHolder<SerializedEntandoResource> testResource = new ValueHolder<>();
step("And I have created an TestResource resource with the 'force' processing instruction", () -> {
testResource.set(createTestResource(10L, Collections.singletonMap(AnnotationNames.PROCESSING_INSTRUCTION.getName(), "force")));
attachment("TestResource", objectMapper.writeValueAsString(testResource.get()));
});
step("And the generation in the metadata is the same as the observedGeneration in the status", () -> {
// NB This step assumes that the ClientDouble is holding this exact instance of the resource when the ControllerCoordinator
// starts
testResource.get().getStatus().updateDeploymentPhase(EntandoDeploymentPhase.STARTED, 10L);
attachment("TestResource", objectMapper.writeValueAsString(testResource.get()));
});
step("When I start the ControllerCoordinator", () -> coordinator.onStartup(new StartupEvent()));
step("Then a new pod gets created", () -> {
coordinator.getObserver(CustomResourceDefinitionContext.fromCustomResourceType(TestResource.class)).shutDownAndWait(1, SECONDS);
await().ignoreExceptions().atMost(3, TimeUnit.SECONDS).until(() -> {
final Map<String, String> labels = labelsFromResource(testResource.get());
return clientDouble.loadPod(CONTROLLER_NAMESPACE, labels) != null;
});
});
step("And the 'force' processing instruction has been removed to avoid recursive processing", () -> {
final SerializedEntandoResource latestKeycloakServer = clientDouble.load(TestResource.class, testResource.get().getMetadata().getNamespace(), testResource.get().getMetadata().getName());
assertThat(CoordinatorUtils.resolveProcessingInstruction(latestKeycloakServer)).isEqualTo(OperatorProcessingInstruction.NONE);
attachment("TestResource", objectMapper.writeValueAsString(testResource.get()));
});
step("And the forced event was logged", () -> {
final Optional<String> logEntry = LogInterceptor.getLogEntries().stream().filter(s -> s.contains("has been forced")).findFirst();
assertThat(logEntry).isPresent();
});
}
use of org.entando.kubernetes.test.common.ValueHolder in project entando-k8s-controller-coordinator by entando-k8s.
the class ControllerCoordinatorProcessingCriteriaTest method testIgnoredWhenOwnedByResourceOfInterest.
@Test
@Description("Resources should be ignored when they are owned by other resources of interest")
void testIgnoredWhenOwnedByResourceOfInterest() {
step("Given the Coordinator observes this namespace", () -> System.setProperty(EntandoOperatorConfigProperty.ENTANDO_NAMESPACES_TO_OBSERVE.getJvmSystemProperty(), OBSERVED_NAMESPACE));
ValueHolder<SerializedEntandoResource> owningResource = new ValueHolder<>();
step("And I have created another resource of interest, a ProvidedCapability", () -> {
owningResource.set(clientDouble.createOrPatchEntandoResource(CoordinatorTestUtils.toSerializedResource(new ProvidedCapabilityBuilder().withNewMetadata().withName("my-capability").withNamespace(OBSERVED_NAMESPACE).endMetadata().withNewSpec().withCapability(StandardCapability.DBMS).endSpec().build())));
attachment("CapabilityResource", objectMapper.writeValueAsString(owningResource.get()));
});
ValueHolder<SerializedEntandoResource> testResource = new ValueHolder<>();
step("And I have created an TestResource resource that is owned by another resource of interest", () -> {
testResource.set(createTestResource(1L, Collections.emptyMap()));
testResource.get().getMetadata().getOwnerReferences().add(ResourceUtils.buildOwnerReference(owningResource.get()));
clientDouble.createOrPatchEntandoResource(testResource.get());
});
step("when I start the ControllerCoordinator", () -> coordinator.onStartup(new StartupEvent()));
step("Then a new pod gets created for the owning resource", () -> {
await().ignoreExceptions().atMost(10, SECONDS).until(() -> clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(owningResource.get())) != null);
attachment("Controller Pod", objectMapper.writeValueAsString(clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(owningResource.get()))));
});
step("Then no new pod gets created for the owned resource", () -> {
assertThat(clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(testResource.get()))).isNull();
});
step("And the ignored event was logged", () -> {
final Optional<String> logEntry = LogInterceptor.getLogEntries().stream().filter(s -> s.contains("is ignored because it is not a top level resource")).findFirst();
assertThat(logEntry).isPresent();
});
}
use of org.entando.kubernetes.test.common.ValueHolder in project entando-k8s-controller-coordinator by entando-k8s.
the class ControllerCoordinatorProcessingCriteriaTest method testUpgrade.
@Test
@Description("A resource should be processed again when the ControllerCoordinator starts up if it was processed with a version of the" + " Operator that is now being replaced")
void testUpgrade() {
step("Given the Coordinator observes this namespace", () -> System.setProperty(EntandoOperatorConfigProperty.ENTANDO_NAMESPACES_TO_OBSERVE.getJvmSystemProperty(), OBSERVED_NAMESPACE));
step("And the current version of the operator is 6.3.1", () -> System.setProperty(ControllerCoordinatorProperty.ENTANDO_K8S_OPERATOR_VERSION.getJvmSystemProperty(), "6.3.1"));
step("And the version of the operator to replace was 6.3.0", () -> System.setProperty(ControllerCoordinatorProperty.ENTANDO_K8S_OPERATOR_VERSION_TO_REPLACE.getJvmSystemProperty(), "6.3.0"));
final ValueHolder<SerializedEntandoResource> testResource = new ValueHolder<>();
step("And I have created an TestResource resource that was processed by version 6.3.0", () -> testResource.set(createTestResource(10L, Collections.singletonMap(AnnotationNames.PROCESSED_BY_OPERATOR_VERSION.getName(), "6.3.0"))));
step("And it has been successfully deployed previously", () -> {
testResource.set(clientDouble.updatePhase(testResource.get(), EntandoDeploymentPhase.SUCCESSFUL));
attachment("Processed Resource", objectMapper.writeValueAsString(testResource.get()));
});
step("When I start the ControllerCoordinator", () -> coordinator.onStartup(new StartupEvent()));
step("Then a new controller pod is created", () -> {
await().ignoreExceptions().atMost(3, TimeUnit.SECONDS).until(() -> clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(testResource.get())) != null);
attachment("Controller Pod", objectMapper.writeValueAsString(clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(testResource.get()))));
});
step("And the resource is marked as having been processed by version 6.3.1 when its deployment succeeds", () -> {
clientDouble.updatePhase(testResource.get(), EntandoDeploymentPhase.SUCCESSFUL);
SerializedEntandoResource latestKeycloakServer = clientDouble.load(TestResource.class, testResource.get().getMetadata().getNamespace(), testResource.get().getMetadata().getName());
assertThat(CoordinatorUtils.resolveAnnotation(latestKeycloakServer, AnnotationNames.PROCESSED_BY_OPERATOR_VERSION)).contains("6.3.1");
});
step("And the upgrade event was logged", () -> {
final Optional<String> logEntry = LogInterceptor.getLogEntries().stream().filter(s -> s.contains("needs to be processed as part of the upgrade to the version")).findFirst();
assertThat(logEntry).isPresent();
});
}
use of org.entando.kubernetes.test.common.ValueHolder in project entando-k8s-controller-coordinator by entando-k8s.
the class ControllerCoordinatorProcessingCriteriaTest method testProcessedByVersion.
@Test
@Description("When a resource is processed successfully, the annotation 'entando.org/processed-by-version' should reflect the current" + " version of the operator")
void testProcessedByVersion() {
step("Given the Coordinator observes this namespace", () -> System.setProperty(EntandoOperatorConfigProperty.ENTANDO_NAMESPACES_TO_OBSERVE.getJvmSystemProperty(), OBSERVED_NAMESPACE));
step("And the current version of the operator is 6.3.1", () -> System.setProperty(ControllerCoordinatorProperty.ENTANDO_K8S_OPERATOR_VERSION.getJvmSystemProperty(), "6.3.1"));
final ValueHolder<SerializedEntandoResource> testResource = new ValueHolder<>();
step("And I have created an TestResource resource with the version annotation set to 6.3.0", () -> {
testResource.set(createTestResource(10L, Collections.singletonMap(AnnotationNames.PROCESSED_BY_OPERATOR_VERSION.getName(), "6.3.0")));
attachment("TestResource", objectMapper.writeValueAsString(testResource.get()));
});
step("And I have start the ControllerCoordinator", () -> coordinator.onStartup(new StartupEvent()));
step("And a new controller pod was created", () -> {
await().ignoreExceptions().atMost(3, TimeUnit.SECONDS).until(() -> clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(testResource.get())) != null);
attachment("Controller Pod", objectMapper.writeValueAsString(clientDouble.loadPod(CONTROLLER_NAMESPACE, labelsFromResource(testResource.get()))));
});
step("When I update the deployment Phase of the resource to 'successful'", () -> {
SerializedEntandoResource latestKeycloakServer = clientDouble.updatePhase(testResource.get(), EntandoDeploymentPhase.SUCCESSFUL);
attachment("Successful Resource", objectMapper.writeValueAsString(latestKeycloakServer));
});
step("Then the TestResource has been annotated with the version 6.3.1", () -> {
coordinator.shutdownObservers(10, TimeUnit.SECONDS);
SerializedEntandoResource latestKeycloakServer = clientDouble.load(TestResource.class, testResource.get().getMetadata().getNamespace(), testResource.get().getMetadata().getName());
assertThat(CoordinatorUtils.resolveAnnotation(latestKeycloakServer, AnnotationNames.PROCESSED_BY_OPERATOR_VERSION)).contains("6.3.1");
});
}
use of org.entando.kubernetes.test.common.ValueHolder in project entando-k8s-controller-coordinator by entando-k8s.
the class CrdManagementTest method crdUpdatesShouldRestartObservers.
@Test
@Description("Updates to my CustomResourceDefinitions should result in their observers being restarted")
void crdUpdatesShouldRestartObservers() throws IOException {
step("Given I have started the Entando Operator", () -> entandoControllerCoordinator.onStartup(new StartupEvent()));
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
final ValueHolder<EntandoResourceObserver> observer = new ValueHolder<>();
final ValueHolder<CustomResourceDefinition> crd = new ValueHolder<>();
crd.set(objectMapper.readValue(Thread.currentThread().getContextClassLoader().getResource("mycrds.test.org.crd.yaml"), CustomResourceDefinition.class));
final MetadataNested<CustomResourceDefinitionBuilder> builder = new CustomResourceDefinitionBuilder(crd.get()).editMetadata();
step("And I have registered a CustomResourceDefinition with", () -> {
step(format("the %s label ", LabelNames.CRD_OF_INTEREST.getName()), () -> {
builder.addToLabels(LabelNames.CRD_OF_INTEREST.getName(), "MyCRD");
});
step(format("and the %s annotation ", AnnotationNames.CONTROLLER_IMAGE), () -> {
builder.addToAnnotations(AnnotationNames.CONTROLLER_IMAGE.getName(), "test/my-controller");
});
step("and I have registered my CustomResourceDefinition", () -> {
crd.set(client.getCluster().putCustomResourceDefinition(builder.withGeneration(1L).endMetadata().build()));
});
attachment("CustomResourceDefinition", objectMapper.writeValueAsString(crd.get()));
});
step("And I have waited for the Operator to start observing state changes against the related CustomResources", () -> {
await().atMost(10, TimeUnit.SECONDS).ignoreExceptions().until(() -> entandoControllerCoordinator.getObserver(CustomResourceDefinitionContext.fromCrd(crd.get())).getCrdGeneration() == 1L);
observer.set(entandoControllerCoordinator.getObserver(CustomResourceDefinitionContext.fromCrd(crd.get())));
});
step("When I apply an updated version of my CustomResourceDefinition ", () -> {
crd.get().getMetadata().setGeneration(2L);
client.getCluster().putCustomResourceDefinition(crd.get());
});
step("Then the Operator has started a new state change observer against the CustomResources", () -> {
await().atMost(10, TimeUnit.SECONDS).ignoreExceptions().until(() -> entandoControllerCoordinator.getObserver(CustomResourceDefinitionContext.fromCrd(crd.get())).getCrdGeneration() == 2L);
assertThat(entandoControllerCoordinator.getObserver(CustomResourceDefinitionContext.fromCrd(crd.get()))).isNotSameAs(observer.get());
});
}
Aggregations