Skip to content

Commit 1ff8cf1

Browse files
authored
Added test to cover scaling via scalingAction.sh for two domains in same namespace (#2412)
* Added test to cover scaling via scalingAction.sh for two domains in same namespace
1 parent bfeb41e commit 1ff8cf1

File tree

3 files changed

+280
-5
lines changed

3 files changed

+280
-5
lines changed

integration-tests/src/test/java/oracle/weblogic/kubernetes/ItUsabilityOperatorHelmChart.java

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import oracle.weblogic.domain.DomainSpec;
2323
import oracle.weblogic.domain.Model;
2424
import oracle.weblogic.domain.ServerPod;
25+
import oracle.weblogic.kubernetes.actions.TestActions;
2526
import oracle.weblogic.kubernetes.actions.impl.OperatorParams;
2627
import oracle.weblogic.kubernetes.actions.impl.primitive.HelmParams;
2728
import oracle.weblogic.kubernetes.actions.impl.primitive.Kubernetes;
@@ -107,11 +108,15 @@ class ItUsabilityOperatorHelmChart {
107108
private static String domain1Namespace = null;
108109
private static String domain2Namespace = null;
109110
private static String domain3Namespace = null;
111+
private static String domain4Namespace = null;
110112

111113
// domain constants
112114
private final String domain1Uid = "usabdomain1";
113115
private final String domain2Uid = "usabdomain2";
114116
private final String domain3Uid = "usabdomain3";
117+
private final String domain4Uid = "usabdomain4";
118+
private final String domain5Uid = "usabdomain5";
119+
115120
private final String clusterName = "cluster-1";
116121
private final int managedServerPort = 8001;
117122
private final int replicaCount = 2;
@@ -137,7 +142,7 @@ class ItUsabilityOperatorHelmChart {
137142
* JUnit engine parameter resolution mechanism
138143
*/
139144
@BeforeAll
140-
public static void initAll(@Namespaces(5) List<String> namespaces) {
145+
public static void initAll(@Namespaces(6) List<String> namespaces) {
141146
logger = getLogger();
142147
// get a unique operator namespace
143148
logger.info("Getting a unique namespace for operator");
@@ -159,10 +164,15 @@ public static void initAll(@Namespaces(5) List<String> namespaces) {
159164
assertNotNull(namespaces.get(3), "Namespace list is null");
160165
domain3Namespace = namespaces.get(3);
161166

167+
// get a unique domain namespace
168+
logger.info("Getting a unique namespace for WebLogic domain 4");
169+
assertNotNull(namespaces.get(4), "Namespace list is null");
170+
domain4Namespace = namespaces.get(4);
171+
162172
// get a unique operator 2 namespace
163173
logger.info("Getting a unique namespace for operator 2");
164-
assertNotNull(namespaces.get(4), "Namespace list is null");
165-
op2Namespace = namespaces.get(4);
174+
assertNotNull(namespaces.get(5), "Namespace list is null");
175+
op2Namespace = namespaces.get(5);
166176
}
167177

168178
@AfterAll
@@ -740,6 +750,91 @@ public void testNotPreexistedOpServiceAccountCreateOperatorNegativeInstall() {
740750
}
741751
}
742752

753+
754+
/**
755+
* Install the Operator successfully.
756+
* Create domain4, domain5 in the same namespace and verify the domains are started
757+
* Verify both domains are managed by the operator by making a REST API call
758+
* Verify domains scaling by calling scalingAction.sh script
759+
*/
760+
@Test
761+
@DisplayName("Create domain4, domain5 in the same namespace managed by operator ,"
762+
+ " verify scaling via scalingAction.sh script and restAPI")
763+
public void testTwoDomainsInSameNameSpaceOnOperator() {
764+
765+
String opReleaseName = OPERATOR_RELEASE_NAME;
766+
HelmParams op1HelmParams = new HelmParams().releaseName(opReleaseName)
767+
.namespace(op2Namespace)
768+
.chartDir(OPERATOR_CHART_DIR);
769+
try {
770+
// install operator
771+
String opServiceAccount = op2Namespace + "-sa";
772+
HelmParams opHelmParams = installAndVerifyOperator(op2Namespace, opServiceAccount, true,
773+
0, op1HelmParams, domain4Namespace).getHelmParams();
774+
assertNotNull(opHelmParams, "Can't install operator");
775+
int externalRestHttpsPort = getServiceNodePort(op2Namespace, "external-weblogic-operator-svc");
776+
assertTrue(externalRestHttpsPort != -1,
777+
"Could not get the Operator external service node port");
778+
logger.info("externalRestHttpsPort {0}", externalRestHttpsPort);
779+
780+
logger.info("Installing and verifying domain4");
781+
assertTrue(createVerifyDomain(domain4Namespace, domain4Uid),
782+
"can't start or verify domain4 in namespace " + domain4Namespace);
783+
logger.info("Installing and verifying domain5");
784+
assertTrue(createVerifyDomain(domain4Namespace, domain5Uid),
785+
"can't start or verify domain5 in namespace " + domain4Namespace);
786+
787+
assertTrue(scaleClusterWithRestApi(domain4Uid, clusterName,3,
788+
externalRestHttpsPort,op2Namespace, opServiceAccount),
789+
"Domain4 " + domain4Namespace + " scaling operation failed");
790+
String managedServerPodName1 = domain4Uid + managedServerPrefix + 3;
791+
logger.info("Checking that the managed server pod {0} exists in namespace {1}",
792+
managedServerPodName1, domain4Namespace);
793+
assertDoesNotThrow(() ->
794+
checkPodExists(managedServerPodName1, domain4Uid, domain4Namespace),
795+
"operator failed to manage domain4, scaling was not succeeded");
796+
logger.info("Domain4 scaled to 3 servers");
797+
798+
assertTrue(scaleClusterWithRestApi(domain5Uid, clusterName,3,
799+
externalRestHttpsPort,op2Namespace, opServiceAccount),
800+
"Domain2 " + domain4Namespace + " scaling operation failed");
801+
String managedServerPodName2 = domain5Uid + managedServerPrefix + 3;
802+
logger.info("Checking that the managed server pod {0} exists in namespace {1}",
803+
managedServerPodName2, domain4Namespace);
804+
assertDoesNotThrow(() ->
805+
checkPodExists(managedServerPodName2, domain5Uid, domain4Namespace),
806+
"operator failed to manage domain2, scaling was not succeeded");
807+
808+
logger.info("Domain4 scaled to 3 servers");
809+
810+
assertDoesNotThrow(() ->
811+
TestActions.scaleClusterWithScalingActionScript(clusterName, domain4Uid, domain4Namespace,
812+
"/u01/domains/" + domain4Uid, "scaleDown", 1,
813+
op2Namespace,opServiceAccount),
814+
"scaling was not succeeded");
815+
assertDoesNotThrow(() ->
816+
checkPodDoesNotExist(managedServerPodName1, domain4Uid, domain4Namespace),
817+
" scaling via scalingAction.sh script was not succeeded for domain4");
818+
logger.info("Domain4 scaled to 2 servers");
819+
assertDoesNotThrow(() ->
820+
TestActions.scaleClusterWithScalingActionScript(clusterName, domain5Uid, domain4Namespace,
821+
"/u01/domains/" + domain5Uid, "scaleDown", 1,
822+
op2Namespace,opServiceAccount),
823+
" scaling via scalingAction.sh script was not succeeded for domain5");
824+
825+
assertDoesNotThrow(() ->
826+
checkPodDoesNotExist(managedServerPodName2, domain5Uid, domain4Namespace),
827+
" scaling via scalingAction.sh script was not succeeded for domain5");
828+
logger.info("Domain5 scaled to 2 servers");
829+
} finally {
830+
uninstallOperator(op1HelmParams);
831+
deleteSecret(OCIR_SECRET_NAME,op2Namespace);
832+
cleanUpSA(op2Namespace);
833+
}
834+
}
835+
836+
837+
743838
private boolean createVerifyDomain(String domainNamespace, String domainUid) {
744839

745840
// create and verify the domain
@@ -767,12 +862,12 @@ private void createAndVerifyMiiDomain(String domainNamespace, String domainUid)
767862

768863
// create secret for admin credentials
769864
logger.info("Creating secret for admin credentials");
770-
String adminSecretName = "weblogic-credentials";
865+
String adminSecretName = "weblogic-credentials-" + domainUid;
771866
createSecretWithUsernamePassword(adminSecretName, domainNamespace, "weblogic", "welcome1");
772867

773868
// create encryption secret
774869
logger.info("Creating encryption secret");
775-
String encryptionSecretName = "encryptionsecret";
870+
String encryptionSecretName = "encryptionsecret" + domainUid;
776871
createSecretWithUsernamePassword(encryptionSecretName, domainNamespace, "weblogicenc", "weblogicenc");
777872

778873
// construct a list of oracle.weblogic.domain.Cluster objects to be used in the domain custom resource

integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/TestActions.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,35 @@ public static boolean scaleClusterWithWLDF(String clusterName,
366366
scalingSize, opNamespace, opServiceAccount, myWebAppName, curlCommand);
367367
}
368368

369+
/**
370+
* Scale the cluster of the domain in the specified namespace with WLDF policy.
371+
*
372+
* @param clusterName name of the WebLogic cluster to be scaled in the domain
373+
* @param domainUid domainUid of the domain to be scaled
374+
* @param domainNamespace domain namespace in which the domain exists
375+
* @param domainHomeLocation domain home location of the domain
376+
* @param scalingAction scaling action, accepted value: scaleUp or scaleDown
377+
* @param scalingSize number of servers to be scaled up or down
378+
* @param opNamespace namespace of WebLogic operator
379+
* @param opServiceAccount service account of operator
380+
* @return true if scaling the cluster succeeds, false otherwise
381+
* @throws ApiException if Kubernetes client API call fails
382+
* @throws InterruptedException if any thread has interrupted the current thread
383+
*/
384+
public static boolean scaleClusterWithScalingActionScript(String clusterName,
385+
String domainUid,
386+
String domainNamespace,
387+
String domainHomeLocation,
388+
String scalingAction,
389+
int scalingSize,
390+
String opNamespace,
391+
String opServiceAccount)
392+
throws ApiException, InterruptedException {
393+
return Domain.scaleClusterWithScalingActionScript(clusterName,
394+
domainUid, domainNamespace, domainHomeLocation, scalingAction,
395+
scalingSize, opNamespace, opServiceAccount);
396+
}
397+
369398
// ------------------------ Ingress Controller ----------------------
370399

371400
/**

integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/Domain.java

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import static oracle.weblogic.kubernetes.utils.ThreadSafeLogger.getLogger;
5858
import static org.awaitility.Awaitility.with;
5959
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
60+
import static org.junit.jupiter.api.Assertions.assertFalse;
6061
import static org.junit.jupiter.api.Assertions.assertTrue;
6162

6263
public class Domain {
@@ -681,6 +682,97 @@ public static String getCurrentIntrospectVersion(String domainUid, String namesp
681682
return introspectVersion;
682683
}
683684

685+
/**
686+
* Scale the cluster of the domain in the specified namespace with WLDF.
687+
*
688+
* @param clusterName name of the WebLogic cluster to be scaled in the domain
689+
* @param domainUid domainUid of the domain to be scaled
690+
* @param domainNamespace domain namespace in which the domain exists
691+
* @param domainHomeLocation domain home location of the domain
692+
* @param scalingAction scaling action, accepted value: scaleUp or scaleDown
693+
* @param scalingSize number of servers to be scaled up or down
694+
* @param opNamespace namespace of WebLogic operator
695+
* @param opServiceAccount service account of operator
696+
* @return true if scaling the cluster succeeds, false otherwise
697+
* @throws ApiException if Kubernetes client API call fails
698+
* @throws InterruptedException if any thread has interrupted the current thread
699+
*/
700+
public static boolean scaleClusterWithScalingActionScript(String clusterName,
701+
String domainUid,
702+
String domainNamespace,
703+
String domainHomeLocation,
704+
String scalingAction,
705+
int scalingSize,
706+
String opNamespace,
707+
String opServiceAccount)
708+
throws ApiException, InterruptedException {
709+
LoggingFacade logger = getLogger();
710+
// create RBAC API objects for WLDF script
711+
logger.info("Creating RBAC API objects for scaling script");
712+
if (!createRbacApiObjectsForWLDFScript(domainNamespace, opNamespace)) {
713+
logger.info("failed to create RBAC objects for scaling script in namespace {0} and {1}",
714+
domainNamespace, opNamespace);
715+
return false;
716+
}
717+
718+
// copy scalingAction.sh to Admin Server pod
719+
// NOTE: you must copy scalingAction.sh to $DOMAIN_HOME/bin/scripts on admin server pod
720+
String adminServerPodName = domainUid + "-" + ADMIN_SERVER_NAME_BASE;
721+
V1Pod adminPod = Kubernetes.getPod(domainNamespace, null, adminServerPodName);
722+
if (adminPod == null) {
723+
logger.info("The admin pod {0} does not exist in namespace {1}!", adminServerPodName, domainNamespace);
724+
return false;
725+
}
726+
727+
// create $DOMAIN_HOME/bin/scripts directory on admin server pod
728+
logger.info("Creating directory {0}/bin/scripts on admin server pod", domainHomeLocation);
729+
withStandardRetryPolicy
730+
.conditionEvaluationListener(
731+
condition -> logger.info("Creating directory {0}/bin/scripts on admin server pod, waiting for success"
732+
+ " (elapsed time {1}ms, remaining time {2}ms)",
733+
domainHomeLocation,
734+
condition.getElapsedTimeInMS(),
735+
condition.getRemainingTimeInMS()))
736+
.until(() -> {
737+
return executeCommandOnPod(adminPod, null, true,
738+
"/bin/sh", "-c", "mkdir -p " + domainHomeLocation + "/bin/scripts");
739+
});
740+
741+
logger.info("Copying scalingAction.sh to admin server pod");
742+
withStandardRetryPolicy
743+
.conditionEvaluationListener(
744+
condition -> logger.info("Copying scalingAction.sh to admin server pod, waiting for success "
745+
+ "(elapsed time {0}ms, remaining time {1}ms)",
746+
condition.getElapsedTimeInMS(),
747+
condition.getRemainingTimeInMS()))
748+
.until(() -> {
749+
return copyFileToPod(domainNamespace, adminServerPodName, null,
750+
Paths.get(PROJECT_ROOT + "/../operator/scripts/scaling/scalingAction.sh"),
751+
Paths.get(domainHomeLocation + "/bin/scripts/scalingAction.sh"));
752+
});
753+
754+
logger.info("Adding execute mode for scalingAction.sh");
755+
withStandardRetryPolicy
756+
.conditionEvaluationListener(
757+
condition -> logger.info("Adding execute mode for scalingAction.sh, waiting for success "
758+
+ "(elapsed time {0}ms, remaining time {1}ms)",
759+
condition.getElapsedTimeInMS(),
760+
condition.getRemainingTimeInMS()))
761+
.until(() -> {
762+
return executeCommandOnPod(adminPod, null, true,
763+
"/bin/sh", "-c", "chmod +x " + domainHomeLocation + "/bin/scripts/scalingAction.sh");
764+
});
765+
766+
if (!scalingAction.equals("scaleUp") && !scalingAction.equals("scaleDown")) {
767+
logger.info("Set scaleAction to either scaleUp or scaleDown");
768+
return false;
769+
}
770+
assertDoesNotThrow(() -> scaleViaScript(opNamespace,domainNamespace,
771+
domainUid,scalingAction,clusterName,opServiceAccount,scalingSize,domainHomeLocation, adminPod),
772+
"scaling failed");
773+
return true;
774+
}
775+
684776
/**
685777
* Create cluster role, cluster role binding and role binding used by WLDF script action.
686778
*
@@ -868,4 +960,63 @@ private static boolean copyFileFromPod(String namespace,
868960
}
869961
return true;
870962
}
963+
964+
private static void scaleViaScript(String opNamespace, String domainNamespace,
965+
String domainUid, String scalingAction, String clusterName,
966+
String opServiceAccount, int scalingSize,
967+
String domainHomeLocation,
968+
V1Pod adminPod) throws ApiException, InterruptedException {
969+
LoggingFacade logger = getLogger();
970+
StringBuffer scalingCommand = new StringBuffer()
971+
.append(Paths.get(domainHomeLocation + "/bin/scripts/scalingAction.sh"))
972+
.append(" --action=")
973+
.append(scalingAction)
974+
.append(" --domain_uid=")
975+
.append(domainUid)
976+
.append(" --wls_domain_namespace=")
977+
.append(domainNamespace)
978+
.append(" --cluster_name=")
979+
.append(clusterName)
980+
.append(" --operator_namespace=")
981+
.append(opNamespace)
982+
.append(" --operator_service_account=")
983+
.append(opServiceAccount)
984+
.append(" --operator_service_name=")
985+
.append("internal-weblogic-operator-svc")
986+
.append(" --scaling_size=")
987+
.append(scalingSize)
988+
.append(" --kubernetes_master=")
989+
.append("https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT");
990+
991+
992+
String commandToExecuteInsidePod = scalingCommand.toString();
993+
994+
ExecResult result = assertDoesNotThrow(() -> Kubernetes.exec(adminPod, null, true,
995+
"/bin/sh", "-c", commandToExecuteInsidePod),
996+
String.format("Could not execute the command %s in pod %s, namespace %s",
997+
commandToExecuteInsidePod, adminPod.getMetadata().getName(), domainNamespace));
998+
logger.info("Command {0} returned with exit value {1}, stderr {2}, stdout {3}",
999+
commandToExecuteInsidePod, result.exitValue(), result.stderr(), result.stdout());
1000+
1001+
// copy scalingAction.log to local
1002+
withStandardRetryPolicy
1003+
.conditionEvaluationListener(
1004+
condition -> logger.info("Copying scalingAction.log from admin server pod, waiting for success "
1005+
+ "(elapsed time {0}ms, remaining time {1}ms)",
1006+
condition.getElapsedTimeInMS(),
1007+
condition.getRemainingTimeInMS()))
1008+
.until(() -> {
1009+
return copyFileFromPod(domainNamespace, adminPod.getMetadata().getName(), null,
1010+
domainHomeLocation + "/bin/scripts/scalingAction.log",
1011+
Paths.get(RESULTS_ROOT + "/" + domainUid + "-scalingAction.log"));
1012+
});
1013+
1014+
// checking for exitValue 0 for success fails sometimes as k8s exec api returns non-zero exit value even on success,
1015+
// so checking for exitValue non-zero and stderr not empty for failure, otherwise its success
1016+
1017+
assertFalse(result.exitValue() != 0 && result.stderr() != null && !result.stderr().isEmpty(),
1018+
String.format("Command %s failed with exit value %s, stderr %s, stdout %s",
1019+
commandToExecuteInsidePod, result.exitValue(), result.stderr(), result.stdout()));
1020+
1021+
}
8711022
}

0 commit comments

Comments
 (0)