Skip to content

Commit d6b828c

Browse files
committed
merge with develop
2 parents 3405b9b + da4c876 commit d6b828c

File tree

30 files changed

+685
-557
lines changed

30 files changed

+685
-557
lines changed

integration-tests/README.md

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# Integration Tests for Oracle WebLogic Server Kubernetes Operator
22

3-
This documentation describes the functional use cases that are covered in integration testing for the Oracle WebLogic Server Kubernetes Operator. The tests are written in Java (JUnit tests) and driven by Maven profile.
3+
This documentation describes the functional use cases that are covered in integration testing for the Oracle WebLogic Server Kubernetes Operator. The tests are written in Java (JUnit tests) and driven by Maven profile.
44

55
# Environments
66

7-
The tests currently run in three modes: "Wercker", "Jenkins", and "standalone" Oracle Linux, where the mode is controlled by the WERCKER and JENKINS environment variables described below. The default is "standalone".
7+
The tests currently run in three modes: "Wercker", "Jenkins", and "standalone" Oracle Linux, where the mode is controlled by the `WERCKER` and `JENKINS` environment variables described below. The default is "standalone".
88

9-
* "Standalone" Oracle Linux, i.e, run the tests manually with mvn command.
10-
* Wercker - https://app.wercker.com/Oracle/weblogic-kubernetes-operator/runs - integration-test-java is the pipeline name
11-
* Jenkins - http://wls-jenkins.us.oracle.com/view/weblogic-operator/job/weblogic-kubernetes-operator-javatest/ - Jenkins Run is restricted to Oracle Internal development Process
9+
* "Standalone" Oracle Linux, i.e, run the tests manually with the `mvn` command.
10+
* Wercker - https://app.wercker.com/Oracle/weblogic-kubernetes-operator/runs - `integration-test-java` is the pipeline name.
11+
* Jenkins - http://wls-jenkins.us.oracle.com/view/weblogic-operator/job/weblogic-kubernetes-operator-javatest/ - Jenkins Run is restricted to Oracle Internal development process.
1212

13-
Wercker runs only Quick test use cases, Jenkins run both Quick and Full test use cases.
13+
Wercker runs only Quick test use cases, Jenkins runs both Quick and Full test use cases.
1414

1515
# Use Cases
1616

@@ -20,27 +20,28 @@ Quick test Configuration & Use Cases -
2020

2121
| | |
2222
| --- | --- |
23-
| Operator Configuration | operator1 deployed in weblogic-operator1 namespace and manages domains in default and test1 namespaces |
24-
| Domain Configuration | Domain on PV using WLST, traefik load balancer |
23+
| Operator Configuration | operator1 deployed in `weblogic-operator1` namespace and manages domains in `default` and `test1` namespaces |
24+
| Domain Configuration | Domain on PV using WLST, Traefik load balancer |
2525

2626
Basic Use Cases
2727

28-
1. create operator operator1 which manages default and test1 namespaces, verify its deployed successfully, pod created, operator Ready and verify external REST service if configured
29-
2. create domain domain1 in default namespace and verify the pods, services are created and servers are in Ready
30-
3. verify admin external service by accessing admin REST endpoint with nodeport in URL
31-
4. verify admin t3 channel port by exec into the admin pod and deploying webapp using the channel port for WLST
32-
5. verify web app load balancing by accessing the webapp using loadBalancerWebPort
28+
1. Create operator `operator1` which manages `default` and `test1` namespaces, verify it's deployed successfully, pods created, operator ready and verify external REST service, if configured.
29+
2. Create domain `domain1` in `default` namespace and verify the pods, services are created and servers are in ready state.
30+
3. Verify the admin external service by accessing the admin REST endpoint with `nodeport` in URL.
31+
4. Verify admin t3 channel port by exec into the admin pod and deploying webapp using the channel port for WLST.
32+
5. Verify web app load balancing by accessing the webapp using `loadBalancerWebPort`.
3333

3434
Advanced Use Cases
3535

36-
6. verify domain life cycle(destroy and create) should not any impact on Operator managing the domain and web app load balancing and admin external service
37-
7. cluster scale up/down using Operator REST endpoint, webapp load balancing should adjust accordingly.
38-
8. Operator life cycle(destroy and create) should not impact the running domain
36+
6. Verify domain life cycle (destroy and create) should not have any impact on operator managing the domain and web app load balancing and admin external service.
37+
7. Cluster scale up/down using operator REST endpoint, webapp load balancing should adjust accordingly.
38+
8. Operator life cycle (destroy and create) should not impact the running domain.
3939

40-
Also the below use cases are covered for Quick test
40+
Also the below use cases are covered for Quick test:
41+
42+
9. Verify the liveness probe by killing managed server 1 process 3 times to kick pod auto-restart.
43+
10. Shutdown the domain by changing domain `serverStartPolicy` to `NEVER`.
4144

42-
9. verify liveness probe by killing managed server 1 process 3 times to kick pod auto-restart
43-
10. shutdown the domain by changing domain serverStartPolicy to NEVER
4445

4546
Full test Configuration & Use Cases - Runs Quick test Configuration & Use cases and the below
4647

@@ -68,22 +69,22 @@ Basic Use Cases described above are verified in all the domain configurations. A
6869

6970
Directory structure of source code:
7071

71-
A new module "integration-tests" is added to the Maven project weblogic-kubernetes-operator.
72+
A new module "integration-tests" is added to the Maven project `weblogic-kubernetes-operator`.
7273

73-
weblogic-kubernetes-operator/integration-tests - location of module pom.xml
74-
weblogic-kubernetes-operator/integration-tests/src/test/java - integration test(JUnit) classes and utility classes
75-
weblogic-kubernetes-operator/integration-tests/src/test/resources - properties, yaml files(see Configuration Files section) and other scripts
74+
`weblogic-kubernetes-operator/integration-tests` - location of module pom.xml
75+
`weblogic-kubernetes-operator/integration-tests/src/test/java` - integration test(JUnit) classes and utility classes
76+
`weblogic-kubernetes-operator/integration-tests/src/test/resources` - properties, YAML files (see Configuration Files section) and other scripts.
7677

7778
Directory structure used for the test run:
7879

79-
Main external env vars:
80+
Main external `env vars`:
8081

8182
| Variable | Description |
8283
| --- | --- |
8384
| RESULT_ROOT | Root path for local test files. |
8485
| PV_ROOT | Root NFS path behind PV/C directories. This must have permissions suitable for WL pods to add files |
8586

86-
Defaults for RESULT_ROOT & PV_ROOT:
87+
Defaults for `RESULT_ROOT` & `PV_ROOT`:
8788

8889
| Test Mode | RESULT_ROOT | PV_ROOT | Where initialized |
8990
| --- | --- | --- | --- |
@@ -175,7 +176,7 @@ Integration test classes:
175176

176177
When the integration test class ITOperator is executed, staticPrepare() method is called once before any of the test methods in the class and staticUnPrepare() method once at the end.
177178

178-
staticPrepare() - initializes the application properties from OperatorIT.properties and creates resultRoot, pvRoot, userprojectsDir directories by calling initialize() method from the base class BaseTest.
179+
staticPrepare() - initializes the application properties from OperatorIT.properties and creates resultRoot, pvRoot, userprojectsDir directories by calling initialize() method from the base class BaseTest.
179180

180181
staticUnPrepare() - releases the cluster lease on wercker env.
181182

@@ -238,7 +239,7 @@ WERCKER=true:
238239
Successful run will have the output like below:
239240
```
240241
[INFO] Reactor Summary:
241-
[INFO]
242+
[INFO]
242243
[INFO] weblogic-kubernetes-operator ....................... SUCCESS [ 0.305 s]
243244
[INFO] operator-model ..................................... SUCCESS [ 10.274 s]
244245
[INFO] operator-swagger ................................... SUCCESS [ 0.436 s]
@@ -256,19 +257,19 @@ Successful run will have the output like below:
256257
Failed run will have the output like
257258
```
258259
259-
[INFO]
260+
[INFO]
260261
[INFO] Results:
261-
[INFO]
262-
[ERROR] Errors:
262+
[INFO]
263+
[ERROR] Errors:
263264
[ERROR] ITOperator.testDomainOnPVUsingWLST:145 ? Runtime FAILURE: Couldn't create serv...
264-
[INFO]
265+
[INFO]
265266
[ERROR] Tests run: 9, Failures: 0, Errors: 1, Skipped: 0
266-
[INFO]
267-
[INFO]
267+
[INFO]
268+
[INFO]
268269
[INFO] --- maven-failsafe-plugin:2.20.1:verify (integration-tests) @ operator-integration-tests ---
269270
[INFO] ------------------------------------------------------------------------
270271
[INFO] Reactor Summary:
271-
[INFO]
272+
[INFO]
272273
[INFO] Build Tools ........................................ SUCCESS [ 1.193 s]
273274
[INFO] weblogic-kubernetes-operator ....................... SUCCESS [ 2.671 s]
274275
[INFO] json-schema ........................................ SUCCESS [ 14.917 s]
@@ -311,7 +312,7 @@ $RESULT_ROOT/acceptance_test_tmp is archived under $RESULT_ROOT/acceptance_test_
311312

312313
$PV_ROOT/acceptance_test_pv is archived under $PV_ROOT/acceptance_test_pv_archive
313314

314-
On Wercker, these logs can be downloaded by clicking "Download artifact" on cleanup and store step.
315+
On Wercker, these logs can be downloaded by clicking "Download artifact" on cleanup and store step.
315316

316317
# How to add a new test
317318

@@ -324,3 +325,18 @@ ITOperator.java - take a look at this test for reference
324325
# Future enhancement
325326

326327
Add functional tests
328+
329+
## Troubleshooting
330+
331+
The integration tests are not completely independent of the environment.
332+
333+
You may run into one or more of the following errors when you attempt to execute the command:
334+
```
335+
mvn clean verify -P java-integration-tests 2>&1 | tee log.txt
336+
```
337+
1. `[ERROR] No permision to create directory /scratch/...`
338+
339+
There are a couple ways to resolve this issue:
340+
341+
* Create a world writable directory named `/scratch`.
342+
* Create some other world writable directory and then define the environment variables `RESULT_ROOT` and `PV_ROOT` to point to that directory. If you want, you can create two directories to keep things separated. See [Directory Configuration and Structure](#directory-configuration-and-structure) for more details.

integration-tests/src/test/java/oracle/kubernetes/operator/BaseTest.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ public void testAdminT3ChannelWithJMS(Domain domain) throws Exception {
251251
c.close();
252252
logger.info("Done - testAdminT3ChannelWithJMS");
253253
}
254+
254255
/**
255256
* Restarting the domain should not have any impact on Operator managing the domain, web app load
256257
* balancing and node port service
@@ -271,6 +272,7 @@ public void testDomainLifecyle(Operator operator, Domain domain) throws Exceptio
271272
domain.verifyWebAppLoadBalancing(TESTWEBAPP);
272273
}
273274
domain.verifyAdminServerExternalService(getUsername(), getPassword());
275+
domain.verifyHasClusterServiceChannelPort("TCP", 8011, TESTWEBAPP + "/");
274276
logger.info("Done - testDomainLifecyle");
275277
}
276278

@@ -315,22 +317,23 @@ public void testClusterScaling(Operator operator, Domain domain) throws Exceptio
315317

316318
// make sure cluster service endpoint is updated with the scaled up servers before verifying
317319
// load balancing
318-
int i = 0;
319-
while (i < BaseTest.getMaxIterationsPod()) {
320-
int numberOfServersInEndpoint =
321-
domain.getNumberOfServersInClusterServiceEndpoint((String) domainMap.get("clusterName"));
322-
if (replicaCnt != numberOfServersInEndpoint) {
323-
// check for last iteration
324-
if (i == (BaseTest.getMaxIterationsPod() - 1)) {
325-
throw new RuntimeException("FAILURE: Cluster Serice Endpoint is not updated");
326-
}
327-
Thread.sleep(BaseTest.getWaitTimePod() * 1000);
328-
i++;
329-
} else {
330-
logger.info("Number of servers addresses in endpoint is same as replica count ");
331-
break;
332-
}
333-
}
320+
// int i = 0;
321+
// while (i < BaseTest.getMaxIterationsPod()) {
322+
// int numberOfServersInEndpoint =
323+
// domain.getNumberOfServersInClusterServiceEndpoint((String)
324+
// domainMap.get("clusterName"));
325+
// if (replicaCnt != numberOfServersInEndpoint) {
326+
// // check for last iteration
327+
// if (i == (BaseTest.getMaxIterationsPod() - 1)) {
328+
// throw new RuntimeException("FAILURE: Cluster Serice Endpoint is not updated");
329+
// }
330+
// Thread.sleep(BaseTest.getWaitTimePod() * 1000);
331+
// i++;
332+
// } else {
333+
// logger.info("Number of servers addresses in endpoint is same as replica count ");
334+
// break;
335+
// }
336+
// }
334337
// commenting the load balance check, bug 29325139
335338
// domain.verifyWebAppLoadBalancing(TESTWEBAPP);
336339

integration-tests/src/test/java/oracle/kubernetes/operator/ITOperator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ public void testAutoAndCustomSitConfigOverrides() throws Exception {
433433
// load input yaml to map and add configOverrides
434434
Map<String, Object> domainMap = TestUtils.loadYaml(domainonpvwlstFile);
435435
domainMap.put("configOverrides", "sitconfigcm");
436+
domainMap.put(
437+
"configOverridesFile",
438+
"/integration-tests/src/test/resources/domain-home-on-pv/customsitconfig");
436439
domainMap.put("domainUID", "customsitdomain");
437440
domainMap.put("adminNodePort", new Integer("30704"));
438441
domainMap.put("t3ChannelPort", new Integer("30051"));

integration-tests/src/test/java/oracle/kubernetes/operator/utils/Domain.java

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ public void verifyServersReady() throws Exception {
234234
}
235235
}
236236
}
237+
237238
/**
238239
* verify nodeport by accessing admin REST endpoint
239240
*
@@ -280,6 +281,73 @@ public void verifyAdminServerExternalService(String username, String password) t
280281
}
281282
}
282283

284+
/**
285+
* Verify that we have the channel set for the cluster
286+
*
287+
* @param protocol
288+
* @param port
289+
* @param path
290+
* @throws Exception
291+
*/
292+
public void verifyHasClusterServiceChannelPort(String protocol, int port, String path)
293+
throws Exception {
294+
295+
/* Make sure the service exists in k8s */
296+
if (!TestUtils.checkHasServiceChannelPort(
297+
this.getDomainUid() + "-cluster-" + this.clusterName, domainNS, protocol, port)) {
298+
throw new RuntimeException(
299+
"FAILURE: Cannot find channel port in cluster, but expecting one: "
300+
+ port
301+
+ "/"
302+
+ protocol);
303+
}
304+
305+
/*
306+
* Construct a curl command that will be run via kubectl exec on the admin server
307+
*/
308+
StringBuffer curlCmd =
309+
new StringBuffer(
310+
"kubectl exec " + this.getDomainUid() + "-" + this.adminServerName + " /usr/bin/curl ");
311+
312+
/*
313+
* Make sure we can reach the port,
314+
* first via each managed server URL
315+
*/
316+
for (int i = 1; i <= TestUtils.getClusterReplicas(domainUid, clusterName, domainNS); i++) {
317+
StringBuffer serverAppUrl = new StringBuffer("http://");
318+
serverAppUrl
319+
.append(this.getDomainUid() + "-" + managedServerNameBase + i)
320+
.append(":")
321+
.append(port)
322+
.append("/");
323+
serverAppUrl.append(path);
324+
325+
callWebAppAndWaitTillReady(
326+
new StringBuffer(curlCmd.toString())
327+
.append(serverAppUrl.toString())
328+
.append(" -- --write-out %{http_code} -o /dev/null")
329+
.toString());
330+
}
331+
332+
/*
333+
* Make sure we can reach the port,
334+
* second via cluster URL which should round robin through each managed server.
335+
* Use the callWebAppAndCheckForServerNameInResponse method with verifyLoadBalancing
336+
* enabled to verify each managed server is responding.
337+
*/
338+
StringBuffer clusterAppUrl = new StringBuffer("http://");
339+
clusterAppUrl
340+
.append(this.getDomainUid() + "-cluster-" + this.clusterName)
341+
.append(":")
342+
.append(port)
343+
.append("/");
344+
clusterAppUrl.append(path);
345+
346+
// execute curl and look for each managed server name in response
347+
callWebAppAndCheckForServerNameInResponse(
348+
new StringBuffer(curlCmd.toString()).append(clusterAppUrl.toString()).toString(), true);
349+
}
350+
283351
/**
284352
* deploy webapp using nodehost and nodeport
285353
*
@@ -416,8 +484,8 @@ public void callWebAppAndVerifyLoadBalancing(String webappName, boolean verifyLo
416484
StringBuffer curlCmdResCode = new StringBuffer(curlCmd.toString());
417485
curlCmdResCode.append(" --write-out %{http_code} -o /dev/null");
418486

419-
logger.info("Curd cmd with response code " + curlCmdResCode);
420-
logger.info("Curd cmd " + curlCmd);
487+
logger.info("Curl cmd with response code " + curlCmdResCode);
488+
logger.info("Curl cmd " + curlCmd);
421489

422490
// call webapp iteratively till its deployed/ready
423491
callWebAppAndWaitTillReady(curlCmdResCode.toString());
@@ -1103,9 +1171,12 @@ private void initialize(Map<String, Object> inputDomainMap) throws Exception {
11031171
domainMap.values().removeIf(Objects::isNull);
11041172

11051173
// create config map and secret for custom sit config
1106-
if (domainMap.get("configOverrides") != null) {
1174+
if ((domainMap.get("configOverrides") != null)
1175+
&& (domainMap.get("configOverridesFile") != null)) {
11071176
// write hostname in config file for public address
11081177

1178+
String configOverridesFile = domainMap.get("configOverridesFile").toString();
1179+
11091180
String cmd =
11101181
"kubectl -n "
11111182
+ domainNS
@@ -1115,7 +1186,7 @@ private void initialize(Map<String, Object> inputDomainMap) throws Exception {
11151186
+ domainMap.get("configOverrides")
11161187
+ " --from-file "
11171188
+ BaseTest.getProjectRoot()
1118-
+ "/integration-tests/src/test/resources/domain-home-on-pv/customsitconfig";
1189+
+ configOverridesFile;
11191190
ExecResult result = ExecCommand.exec(cmd);
11201191
if (result.exitValue() != 0) {
11211192
throw new RuntimeException(

integration-tests/src/test/java/oracle/kubernetes/operator/utils/TestUtils.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,39 @@ public static boolean checkPVReleased(String pvBaseName, String namespace) throw
220220
}
221221
return true;
222222
}
223+
224+
/**
225+
* NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) domain1-cluster-cluster-1 ClusterIP 10.105.146.61
226+
* <none> 30032/TCP,8001/TCP domain1-managed-server1 ClusterIP None <none> 30032/TCP,8001/TCP
227+
*
228+
* @param service
229+
* @param namespace
230+
* @param protocol
231+
* @param port
232+
* @return
233+
* @throws Exception
234+
*/
235+
public static boolean checkHasServiceChannelPort(
236+
String service, String namespace, String protocol, int port) throws Exception {
237+
StringBuffer cmd = new StringBuffer("kubectl get services ");
238+
cmd.append(" -n ").append(namespace);
239+
logger.info(" Find services in namespage " + namespace + " with command: '" + cmd + "'");
240+
241+
ExecResult result = ExecCommand.exec(cmd.toString());
242+
String stdout = result.stdout();
243+
logger.info(" Services found: ");
244+
logger.info(stdout);
245+
String stdoutlines[] = stdout.split("\\r?\\n");
246+
if (result.exitValue() == 0 && stdoutlines.length > 0) {
247+
for (String stdoutline : stdoutlines) {
248+
if (stdoutline.contains(service) && stdoutline.contains(port + "/" + protocol)) {
249+
return true;
250+
}
251+
}
252+
}
253+
return false;
254+
}
255+
223256
/**
224257
* First, kill the mgd server process in the container three times to cause the node manager to
225258
* mark the server 'failed not restartable'. This in turn is detected by the liveness probe, which

0 commit comments

Comments
 (0)