|
6 | 6 | import java.io.File;
|
7 | 7 | import java.io.FileOutputStream;
|
8 | 8 | import java.nio.file.Path;
|
| 9 | +import java.time.OffsetDateTime; |
9 | 10 | import java.util.ArrayList;
|
10 | 11 | import java.util.Collections;
|
11 | 12 | import java.util.HashMap;
|
12 | 13 | import java.util.List;
|
13 | 14 | import java.util.Map;
|
14 | 15 | import java.util.Properties;
|
| 16 | +import java.util.concurrent.Callable; |
15 | 17 |
|
16 | 18 | import io.kubernetes.client.custom.Quantity;
|
| 19 | +import io.kubernetes.client.custom.V1Patch; |
17 | 20 | import io.kubernetes.client.openapi.ApiException;
|
18 | 21 | import io.kubernetes.client.openapi.models.V1EnvVar;
|
19 | 22 | import io.kubernetes.client.openapi.models.V1HostPathVolumeSource;
|
|
68 | 71 | import static oracle.weblogic.kubernetes.TestConstants.OKD;
|
69 | 72 | import static oracle.weblogic.kubernetes.TestConstants.OPERATOR_CHART_DIR;
|
70 | 73 | import static oracle.weblogic.kubernetes.TestConstants.OPERATOR_RELEASE_NAME;
|
| 74 | +import static oracle.weblogic.kubernetes.TestConstants.TEST_IMAGES_REPO; |
| 75 | +import static oracle.weblogic.kubernetes.TestConstants.TEST_IMAGES_REPO_PASSWORD; |
| 76 | +import static oracle.weblogic.kubernetes.TestConstants.TEST_IMAGES_REPO_USERNAME; |
71 | 77 | import static oracle.weblogic.kubernetes.actions.ActionConstants.MODEL_DIR;
|
72 | 78 | import static oracle.weblogic.kubernetes.actions.TestActions.deletePod;
|
| 79 | +import static oracle.weblogic.kubernetes.actions.TestActions.imagePush; |
| 80 | +import static oracle.weblogic.kubernetes.actions.TestActions.imageRepoLogin; |
| 81 | +import static oracle.weblogic.kubernetes.actions.TestActions.imageTag; |
| 82 | +import static oracle.weblogic.kubernetes.actions.impl.Domain.patchDomainCustomResource; |
73 | 83 | import static oracle.weblogic.kubernetes.assertions.TestAssertions.pvcExists;
|
| 84 | +import static oracle.weblogic.kubernetes.assertions.TestAssertions.verifyRollingRestartOccurred; |
74 | 85 | import static oracle.weblogic.kubernetes.utils.AuxiliaryImageUtils.createAndPushAuxiliaryImage;
|
75 | 86 | import static oracle.weblogic.kubernetes.utils.ClusterUtils.createClusterAndVerify;
|
76 | 87 | import static oracle.weblogic.kubernetes.utils.ClusterUtils.createClusterResource;
|
|
91 | 102 | import static oracle.weblogic.kubernetes.utils.PersistentVolumeUtils.createPVC;
|
92 | 103 | import static oracle.weblogic.kubernetes.utils.PersistentVolumeUtils.createPVHostPathDir;
|
93 | 104 | import static oracle.weblogic.kubernetes.utils.PodUtils.checkPodDoesNotExist;
|
| 105 | +import static oracle.weblogic.kubernetes.utils.PodUtils.getPodsWithTimeStamps; |
94 | 106 | import static oracle.weblogic.kubernetes.utils.PodUtils.setPodAntiAffinity;
|
95 | 107 | import static oracle.weblogic.kubernetes.utils.SecretUtils.createOpsswalletpasswordSecret;
|
96 | 108 | import static oracle.weblogic.kubernetes.utils.SecretUtils.createSecretWithUsernamePassword;
|
97 | 109 | import static oracle.weblogic.kubernetes.utils.ThreadSafeLogger.getLogger;
|
98 | 110 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
99 | 111 | import static org.junit.jupiter.api.Assertions.assertNotNull;
|
| 112 | +import static org.junit.jupiter.api.Assertions.assertTrue; |
100 | 113 |
|
101 | 114 | /**
|
102 | 115 | * Test to create a FMW domain in persistent volume with new simplified feature.
|
@@ -177,6 +190,7 @@ public static void initAll(@Namespaces(3) List<String> namespaces) {
|
177 | 190 | * Create a basic FMW domain on PV.
|
178 | 191 | * Operator will create PV/PVC/RCU/Domain.
|
179 | 192 | * Verify Pod is ready and service exists for both admin server and managed servers.
|
| 193 | + * Update the base image in the domain spec, verify the domain is rolling-restarted. |
180 | 194 | */
|
181 | 195 | @Test
|
182 | 196 | @DisplayName("Create a FMW domain on PV using simplified feature, Operator creates PV/PVC/RCU/Domain")
|
@@ -272,6 +286,38 @@ void testOperatorCreatesPvPvcRcuDomain() {
|
272 | 286 | // verify that all servers are ready
|
273 | 287 | verifyDomainReady(domainNamespace, domainUid, replicaCount, "nosuffix");
|
274 | 288 |
|
| 289 | + // get the map with server pods and their original creation timestamps |
| 290 | + String adminServerPodName = domainUid + "-admin-server"; |
| 291 | + String managedServerPodNamePrefix = domainUid + "-managed-server"; |
| 292 | + Map<String, OffsetDateTime> podsWithTimeStamps = getPodsWithTimeStamps(domainNamespace, |
| 293 | + adminServerPodName, managedServerPodNamePrefix, replicaCount); |
| 294 | + |
| 295 | + // update the domain with new base image |
| 296 | + int index = FMWINFRA_IMAGE_TO_USE_IN_SPEC.lastIndexOf(":"); |
| 297 | + String newImage = FMWINFRA_IMAGE_TO_USE_IN_SPEC.substring(0, index) + ":newtag"; |
| 298 | + testUntil( |
| 299 | + tagImageAndPushIfNeeded(FMWINFRA_IMAGE_TO_USE_IN_SPEC, newImage), |
| 300 | + logger, |
| 301 | + "tagImageAndPushIfNeeded for image {0} to be successful", |
| 302 | + newImage); |
| 303 | + |
| 304 | + logger.info("patch the domain resource with new image {0}", newImage); |
| 305 | + String patchStr |
| 306 | + = "[" |
| 307 | + + "{\"op\": \"replace\", \"path\": \"/spec/image\", " |
| 308 | + + "\"value\": \"" + newImage + "\"}" |
| 309 | + + "]"; |
| 310 | + logger.info("Updating domain configuration using patch string: {0}\n", patchStr); |
| 311 | + V1Patch patch = new V1Patch(patchStr); |
| 312 | + assertTrue(patchDomainCustomResource(domainUid, domainNamespace, patch, V1Patch.PATCH_FORMAT_JSON_PATCH), |
| 313 | + "Failed to patch domain"); |
| 314 | + |
| 315 | + // verify the server pods are rolling restarted and back to ready state |
| 316 | + logger.info("Verifying rolling restart occurred for domain {0} in namespace {1}", |
| 317 | + domainUid, domainNamespace); |
| 318 | + assertTrue(verifyRollingRestartOccurred(podsWithTimeStamps, 1, domainNamespace), |
| 319 | + String.format("Rolling restart failed for domain %s in namespace %s", domainUid, domainNamespace)); |
| 320 | + |
275 | 321 | // delete the domain
|
276 | 322 | deleteDomainResource(domainNamespace, domainUid);
|
277 | 323 | // delete the cluster
|
@@ -984,4 +1030,22 @@ private String getHostPath(String pvName, String className) {
|
984 | 1030 | Path hostPVPath = createPVHostPathDir(pvName, className);
|
985 | 1031 | return hostPVPath.toString();
|
986 | 1032 | }
|
| 1033 | + |
| 1034 | + private Callable<Boolean> tagImageAndPushIfNeeded(String originalImage, String taggedImage) { |
| 1035 | + return (() -> { |
| 1036 | + boolean result = true; |
| 1037 | + result = result && imageTag(originalImage, taggedImage); |
| 1038 | + // push the image to a registry to make the test work in multi node cluster |
| 1039 | + logger.info("image repo login to registry {0}", TEST_IMAGES_REPO); |
| 1040 | + result = result && imageRepoLogin(TEST_IMAGES_REPO, TEST_IMAGES_REPO_USERNAME, |
| 1041 | + TEST_IMAGES_REPO_PASSWORD); |
| 1042 | + // push image |
| 1043 | + if (!DOMAIN_IMAGES_REPO.isEmpty()) { |
| 1044 | + logger.info("push image {0} to registry", taggedImage); |
| 1045 | + result = result && imagePush(taggedImage); |
| 1046 | + } |
| 1047 | + return result; |
| 1048 | + }); |
| 1049 | + } |
| 1050 | + |
987 | 1051 | }
|
0 commit comments