|
28 | 28 | import io.kubernetes.client.custom.Quantity; |
29 | 29 | import io.kubernetes.client.custom.V1Patch; |
30 | 30 | import io.kubernetes.client.openapi.ApiException; |
| 31 | +import io.kubernetes.client.openapi.models.CoreV1Event; |
31 | 32 | import io.kubernetes.client.openapi.models.NetworkingV1beta1HTTPIngressPath; |
32 | 33 | import io.kubernetes.client.openapi.models.NetworkingV1beta1HTTPIngressRuleValue; |
33 | 34 | import io.kubernetes.client.openapi.models.NetworkingV1beta1IngressBackend; |
|
185 | 186 | import static oracle.weblogic.kubernetes.actions.TestActions.createService; |
186 | 187 | import static oracle.weblogic.kubernetes.actions.TestActions.createServiceAccount; |
187 | 188 | import static oracle.weblogic.kubernetes.actions.TestActions.defaultAppParams; |
| 189 | +import static oracle.weblogic.kubernetes.actions.TestActions.deleteDomainCustomResource; |
188 | 190 | import static oracle.weblogic.kubernetes.actions.TestActions.dockerLogin; |
189 | 191 | import static oracle.weblogic.kubernetes.actions.TestActions.dockerPush; |
190 | 192 | import static oracle.weblogic.kubernetes.actions.TestActions.getJob; |
191 | 193 | import static oracle.weblogic.kubernetes.actions.TestActions.getOperatorImageName; |
192 | 194 | import static oracle.weblogic.kubernetes.actions.TestActions.getPersistentVolume; |
193 | 195 | import static oracle.weblogic.kubernetes.actions.TestActions.getPersistentVolumeClaim; |
| 196 | +import static oracle.weblogic.kubernetes.actions.TestActions.getPod; |
194 | 197 | import static oracle.weblogic.kubernetes.actions.TestActions.getPodCreationTimestamp; |
195 | 198 | import static oracle.weblogic.kubernetes.actions.TestActions.getPodLog; |
196 | 199 | import static oracle.weblogic.kubernetes.actions.TestActions.getServiceNodePort; |
|
220 | 223 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.credentialsNotValid; |
221 | 224 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.credentialsValid; |
222 | 225 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.doesImageExist; |
| 226 | +import static oracle.weblogic.kubernetes.assertions.TestAssertions.domainDoesNotExist; |
223 | 227 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.domainExists; |
224 | 228 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.domainStatusReasonMatches; |
225 | 229 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.isApacheReady; |
|
247 | 251 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.serviceExists; |
248 | 252 | import static oracle.weblogic.kubernetes.utils.ExecCommand.exec; |
249 | 253 | import static oracle.weblogic.kubernetes.utils.FileUtils.checkDirectory; |
| 254 | +import static oracle.weblogic.kubernetes.utils.K8sEvents.checkDomainEvent; |
| 255 | +import static oracle.weblogic.kubernetes.utils.K8sEvents.getEvent; |
250 | 256 | import static oracle.weblogic.kubernetes.utils.TestUtils.callWebAppAndCheckForServerNameInResponse; |
251 | 257 | import static oracle.weblogic.kubernetes.utils.TestUtils.callWebAppAndWaitTillReady; |
252 | 258 | import static oracle.weblogic.kubernetes.utils.TestUtils.getNextFreePort; |
@@ -3866,6 +3872,27 @@ public static String getIntrospectJobName(String domainUid) { |
3866 | 3872 | return domainUid + TestConstants.DEFAULT_INTROSPECTOR_JOB_NAME_SUFFIX; |
3867 | 3873 | } |
3868 | 3874 |
|
| 3875 | + /** |
| 3876 | + * Get the introspector pod name. |
| 3877 | + * @param domainUid domain uid of the domain |
| 3878 | + * @param domainNamespace domain namespace in which introspector runs |
| 3879 | + * @return the introspector pod name |
| 3880 | + * @throws ApiException if Kubernetes API calls fail |
| 3881 | + */ |
| 3882 | + public static String getIntrospectorPodName(String domainUid, String domainNamespace) throws ApiException { |
| 3883 | + checkPodExists(getIntrospectJobName(domainUid), domainUid, domainNamespace); |
| 3884 | + |
| 3885 | + String labelSelector = String.format("weblogic.domainUID in (%s)", domainUid); |
| 3886 | + |
| 3887 | + V1Pod introspectorPod = getPod(domainNamespace, labelSelector, getIntrospectJobName(domainUid)); |
| 3888 | + |
| 3889 | + if (introspectorPod != null && introspectorPod.getMetadata() != null) { |
| 3890 | + return introspectorPod.getMetadata().getName(); |
| 3891 | + } else { |
| 3892 | + return ""; |
| 3893 | + } |
| 3894 | + } |
| 3895 | + |
3869 | 3896 | /** |
3870 | 3897 | * Set the inter-pod anti-affinity for the domain custom resource |
3871 | 3898 | * so that server instances spread over the available Nodes. |
@@ -4352,4 +4379,116 @@ public static String getDockerExtraArgs() { |
4352 | 4379 | } |
4353 | 4380 | return extraArgs.toString(); |
4354 | 4381 | } |
| 4382 | + |
| 4383 | + /** |
| 4384 | + * Wait until a given event is logged by the operator. |
| 4385 | + * |
| 4386 | + * @param opNamespace namespace in which the operator is running |
| 4387 | + * @param domainNamespace namespace in which the domain exists |
| 4388 | + * @param domainUid UID of the domain |
| 4389 | + * @param reason event to check for Created, Changed, deleted, processing etc |
| 4390 | + * @param type type of event, Normal of Warning |
| 4391 | + * @param timestamp the timestamp after which to see events |
| 4392 | + */ |
| 4393 | + public static void checkEvent( |
| 4394 | + String opNamespace, String domainNamespace, String domainUid, |
| 4395 | + String reason, String type, OffsetDateTime timestamp) { |
| 4396 | + withStandardRetryPolicy |
| 4397 | + .conditionEvaluationListener(condition -> |
| 4398 | + getLogger().info("Waiting for domain event {0} to be logged in namespace {1} " |
| 4399 | + + "(elapsed time {2}ms, remaining time {3}ms)", |
| 4400 | + reason, |
| 4401 | + domainNamespace, |
| 4402 | + condition.getElapsedTimeInMS(), |
| 4403 | + condition.getRemainingTimeInMS())) |
| 4404 | + .until(checkDomainEvent(opNamespace, domainNamespace, domainUid, reason, type, timestamp)); |
| 4405 | + } |
| 4406 | + |
| 4407 | + /** |
| 4408 | + * Delete a domain in the specified namespace. |
| 4409 | + * @param domainNS the namespace in which the domain exists |
| 4410 | + * @param domainUid domain uid |
| 4411 | + */ |
| 4412 | + public static void deleteDomainResource(String domainNS, String domainUid) { |
| 4413 | + //clean up domain resources in namespace and set namespace to label , managed by operator |
| 4414 | + getLogger().info("deleting domain custom resource {0}", domainUid); |
| 4415 | + assertTrue(deleteDomainCustomResource(domainUid, domainNS)); |
| 4416 | + |
| 4417 | + // wait until domain was deleted |
| 4418 | + withStandardRetryPolicy |
| 4419 | + .conditionEvaluationListener( |
| 4420 | + condition -> getLogger().info("Waiting for domain {0} to be deleted in namespace {1} " |
| 4421 | + + "(elapsed time {2}ms, remaining time {3}ms)", |
| 4422 | + domainUid, |
| 4423 | + domainNS, |
| 4424 | + condition.getElapsedTimeInMS(), |
| 4425 | + condition.getRemainingTimeInMS())) |
| 4426 | + .until(domainDoesNotExist(domainUid, DOMAIN_VERSION, domainNS)); |
| 4427 | + } |
| 4428 | + |
| 4429 | + private static Callable<Boolean> podLogContainsString(String namespace, String podName, String expectedString) { |
| 4430 | + return () -> { |
| 4431 | + String podLog; |
| 4432 | + try { |
| 4433 | + podLog = getPodLog(podName, namespace); |
| 4434 | + getLogger().info("pod log for pod {0} in namespace {1} : {2}", podName, namespace, podLog); |
| 4435 | + } catch (ApiException apiEx) { |
| 4436 | + getLogger().severe("got ApiException while getting pod log: ", apiEx); |
| 4437 | + return false; |
| 4438 | + } |
| 4439 | + |
| 4440 | + return podLog.contains(expectedString); |
| 4441 | + }; |
| 4442 | + } |
| 4443 | + |
| 4444 | + /** |
| 4445 | + * Wait and check the pod log contains the expected string. |
| 4446 | + * @param namespace the namespace in which the pod exists |
| 4447 | + * @param podName the pod to get the log |
| 4448 | + * @param expectedString the expected string to check in the pod log |
| 4449 | + */ |
| 4450 | + public static void checkPodLogContainsString(String namespace, String podName, String expectedString) { |
| 4451 | + |
| 4452 | + getLogger().info("Wait for string {0} existing in pod {1} in namespace {2}", expectedString, podName, namespace); |
| 4453 | + withStandardRetryPolicy |
| 4454 | + .conditionEvaluationListener( |
| 4455 | + condition -> getLogger().info("Waiting for string {0} existing in pod {1} in namespace {2} " |
| 4456 | + + "(elapsed time {3}ms, remaining time {4}ms)", |
| 4457 | + expectedString, |
| 4458 | + podName, |
| 4459 | + namespace, |
| 4460 | + condition.getElapsedTimeInMS(), |
| 4461 | + condition.getRemainingTimeInMS())) |
| 4462 | + .until(assertDoesNotThrow(() -> podLogContainsString(namespace, podName, expectedString), |
| 4463 | + "podLogContainsString failed with IOException, ApiException or InterruptedException")); |
| 4464 | + } |
| 4465 | + |
| 4466 | + /** |
| 4467 | + * Check the domain event contains the expected error msg. |
| 4468 | + * |
| 4469 | + * @param opNamespace namespace in which the operator is running |
| 4470 | + * @param domainNamespace namespace in which the domain exists |
| 4471 | + * @param domainUid UID of the domain |
| 4472 | + * @param reason event to check for Created, Changed, deleted, processing etc |
| 4473 | + * @param type type of event, Normal of Warning |
| 4474 | + * @param timestamp the timestamp after which to see events |
| 4475 | + * @param expectedMsg the expected message in the domain event message |
| 4476 | + */ |
| 4477 | + public static void checkDomainEventContainsExpectedMsg(String opNamespace, |
| 4478 | + String domainNamespace, |
| 4479 | + String domainUid, |
| 4480 | + String reason, |
| 4481 | + String type, |
| 4482 | + OffsetDateTime timestamp, |
| 4483 | + String expectedMsg) { |
| 4484 | + checkEvent(opNamespace, domainNamespace, domainUid, reason, type, timestamp); |
| 4485 | + CoreV1Event event = |
| 4486 | + getEvent(opNamespace, domainNamespace, domainUid, reason, type, timestamp); |
| 4487 | + if (event != null && event.getMessage() != null) { |
| 4488 | + assertTrue(event.getMessage().contains(expectedMsg), |
| 4489 | + String.format("The event message does not contain the expected msg %s", expectedMsg)); |
| 4490 | + } else { |
| 4491 | + fail("event is null or event message is null"); |
| 4492 | + } |
| 4493 | + } |
4355 | 4494 | } |
0 commit comments