Skip to content

Commit afb8b77

Browse files
committed
Completed JIRA OWLS-71984 - Migrate Session Migration test suite to github
1 parent 029faf1 commit afb8b77

File tree

3 files changed

+455
-1
lines changed

3 files changed

+455
-1
lines changed
Lines changed: 393 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,393 @@
1+
// Copyright 2018, Oracle Corporation and/or its affiliates. All rights reserved.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at
3+
// http://oss.oracle.com/licenses/upl.
4+
5+
package oracle.kubernetes.operator;
6+
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.regex.Matcher;
10+
import java.util.regex.Pattern;
11+
import oracle.kubernetes.operator.utils.Domain;
12+
import oracle.kubernetes.operator.utils.ExecCommand;
13+
import oracle.kubernetes.operator.utils.ExecResult;
14+
import oracle.kubernetes.operator.utils.Operator;
15+
import oracle.kubernetes.operator.utils.TestUtils;
16+
import org.junit.AfterClass;
17+
import org.junit.Assume;
18+
import org.junit.BeforeClass;
19+
import org.junit.FixMethodOrder;
20+
import org.junit.Ignore;
21+
import org.junit.Test;
22+
import org.junit.runners.MethodSorters;
23+
24+
/**
25+
* Simple JUnit test file used for testing Operator.
26+
*
27+
* <p>This test is used for creating Operator(s) and domain(s) which are managed by the Operator(s).
28+
* And to test WLS Session Migration feature
29+
*/
30+
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
31+
public class ITSessionMigration extends BaseTest {
32+
33+
// property file used to customize operator properties for operator inputs yaml
34+
private static String operatorYmlFile = "operator1.yaml";
35+
36+
// file used to customize domain properties for domain, PV and LB inputs yaml
37+
private static String domainonpvwlstFile = "domainonpvwlst.yaml";
38+
39+
// property file used to configure constants for integration tests
40+
private static String appPropsFile = "OperatorIT.properties";
41+
42+
private static final String TESTAPPNAME = "httpsessionreplication";
43+
private static Map<String, String> httpAttrMap;
44+
45+
private static String httpHeaderFile;
46+
47+
private static Operator operator;
48+
private static Domain domain;
49+
50+
private static boolean QUICKTEST;
51+
private static boolean SMOKETEST;
52+
private static boolean JENKINS;
53+
private static boolean INGRESSPERDOMAIN = true;
54+
55+
// Set QUICKTEST env var to true to run a small subset of tests.
56+
// Set SMOKETEST env var to true to run an even smaller subset
57+
// of tests, plus leave domain1 up and running when the test completes.
58+
// set INGRESSPERDOMAIN to false to create LB's ingress by kubectl yaml file
59+
static {
60+
QUICKTEST =
61+
System.getenv("QUICKTEST") != null && System.getenv("QUICKTEST").equalsIgnoreCase("true");
62+
SMOKETEST =
63+
System.getenv("SMOKETEST") != null && System.getenv("SMOKETEST").equalsIgnoreCase("true");
64+
if (SMOKETEST) QUICKTEST = true;
65+
if (System.getenv("JENKINS") != null) {
66+
JENKINS = new Boolean(System.getenv("JENKINS")).booleanValue();
67+
}
68+
if (System.getenv("INGRESSPERDOMAIN") != null) {
69+
INGRESSPERDOMAIN = new Boolean(System.getenv("INGRESSPERDOMAIN")).booleanValue();
70+
}
71+
}
72+
73+
/**
74+
* This method gets called only once before any of the test methods are executed. It does the
75+
* initialization of the integration test properties defined in OperatorIT.properties and setting
76+
* the resultRoot, pvRoot and projectRoot attributes.
77+
*
78+
* <p>It also create operator and verify its deployed successfully. Create domain and verify
79+
* domain is created.
80+
*
81+
* @throws Exception
82+
*/
83+
@BeforeClass
84+
public static void staticPrepare() throws Exception {
85+
if (!QUICKTEST) {
86+
// initialize test properties and create the directories
87+
initialize(appPropsFile);
88+
89+
// create operator1
90+
if (operator == null) {
91+
logger.info("Creating Operator & waiting for the script to complete execution");
92+
operator = TestUtils.createOperator(operatorYmlFile);
93+
}
94+
95+
// create domain
96+
if (domain == null) {
97+
logger.info("Creating WLS Domain & waiting for the script to complete execution");
98+
domain = TestUtils.createDomain(domainonpvwlstFile);
99+
domain.verifyDomainCreated();
100+
101+
domain.deployWebAppViaREST(
102+
TESTAPPNAME,
103+
BaseTest.getProjectRoot() + "/src/integration-tests/apps/httpsessionreplication.war",
104+
BaseTest.getUsername(),
105+
BaseTest.getPassword());
106+
107+
// wait sometime for deployment gets ready
108+
Thread.sleep(30 * 1000);
109+
110+
httpHeaderFile = BaseTest.getResultDir() + "/headers";
111+
112+
httpAttrMap = new HashMap<String, String>();
113+
httpAttrMap.put("sessioncreatetime", "(.*)sessioncreatetime>(.*)</sessioncreatetime(.*)");
114+
httpAttrMap.put("sessionid", "(.*)sessionid>(.*)</sessionid(.*)");
115+
httpAttrMap.put("primary", "(.*)primary>(.*)</primary(.*)");
116+
httpAttrMap.put("secondary", "(.*)secondary>(.*)</secondary(.*)");
117+
httpAttrMap.put("count", "(.*)countattribute>(.*)</countattribute(.*)");
118+
}
119+
}
120+
}
121+
122+
/**
123+
* Releases k8s cluster lease, archives result, pv directories
124+
*
125+
* @throws Exception
126+
*/
127+
@AfterClass
128+
public static void staticUnPrepare() throws Exception {
129+
if (!QUICKTEST) {
130+
logger.info("++++++++++++++++++++++++++++++++++");
131+
logger.info("BEGIN");
132+
logger.info("Run once, release cluster lease");
133+
134+
tearDown();
135+
136+
logger.info("SUCCESS");
137+
}
138+
}
139+
140+
/**
141+
* verify that after the primary server shutdown, a new and running managed server is picked up as
142+
* the primary server
143+
*
144+
* @throws Exception
145+
*/
146+
@Test
147+
public void testRepickPrimary() throws Exception {
148+
Assume.assumeFalse(QUICKTEST);
149+
String testMethodName = new Object() {}.getClass().getEnclosingMethod().getName();
150+
logTestBegin(testMethodName);
151+
152+
Map<String, Object> domainMap = domain.getDomainMap();
153+
String domainNS = domainMap.get("namespace").toString();
154+
String domainUid = domain.getDomainUid();
155+
156+
String testAppPath = TESTAPPNAME + "/CounterServlet";
157+
String sessCreateTime = "sessioncreatetime";
158+
String primaryServ = "primary";
159+
160+
// Send the 1st HTTP request and save http header/sessionID info
161+
logger.info("Send the first HTTP request to query Primary server name.");
162+
String curlSaveHttpHeader = " -D " + httpHeaderFile;
163+
String curlCmd = buildWebServiceUrl(testAppPath, curlSaveHttpHeader);
164+
ExecResult result = execCurlCmd(curlCmd);
165+
// logger.info("HTTP resp bf promary server is stopped:\n " + result.stdout());
166+
167+
// get primary server name & session create time bf primaryServName1 is stopped
168+
String primaryServName1 = getHttpResponseAttribute(result.stdout(), primaryServ);
169+
String sessCreateTime1 = getHttpResponseAttribute(result.stdout(), sessCreateTime);
170+
logger.info("Primary server before is: " + primaryServName1);
171+
logger.info("Session created time before is: " + sessCreateTime1);
172+
173+
// stop primary server
174+
// TODO this doesn't work. need to file a bug
175+
// domain.shutdownManagedServerUsingServerStartPolicy(primaryServName1);
176+
String msPodName = domainUid + "-" + primaryServName1;
177+
String cmd = "kubectl delete po/" + msPodName + " -n " + domainNS;
178+
logger.info("Stop managed server <" + primaryServName1 + "> using command:\n" + cmd);
179+
result = ExecCommand.exec(cmd);
180+
logger.info(result.stdout());
181+
182+
// Send the 2nd HTTP request by use http header/sessionID info save before
183+
logger.info("Send the second HTTP request to query Primary server name.");
184+
String curlUseHttpHeader = " -b " + httpHeaderFile;
185+
curlCmd = buildWebServiceUrl(testAppPath, curlUseHttpHeader);
186+
result = execCurlCmd(curlCmd);
187+
// logger.info("HTTP resp af promary server is stopped:\n " + result.stdout());
188+
189+
// get primary server name & session create time af primaryServName1 is stopped
190+
String primaryServName2 = getHttpResponseAttribute(result.stdout(), primaryServ);
191+
String sessCreateTime2 = getHttpResponseAttribute(result.stdout(), sessCreateTime);
192+
logger.info("Primary server after is: " + primaryServName2);
193+
logger.info("Session created time after is: " + sessCreateTime2);
194+
195+
// verify that the same session info is used
196+
Assume.assumeTrue("HTTP Session should NOT change!", sessCreateTime1.equals(sessCreateTime2));
197+
198+
// verify that a new primary server is picked
199+
Assume.assumeFalse(
200+
"A new primary server should be picked!",
201+
primaryServName1.trim().equals(primaryServName2.trim()));
202+
203+
// restore test env
204+
// TODO will use this when it works
205+
// domain.restartManagedServerUsingServerStartPolicy(primaryServName1);
206+
// wait sometime for ms pod gets ready
207+
Thread.sleep(30 * 1000);
208+
TestUtils.checkPodCreated(domainUid + "-" + primaryServName1, domainNS);
209+
TestUtils.checkPodReady(domainUid + "-" + primaryServName1, domainNS);
210+
211+
logger.info("SUCCESS - " + testMethodName + ". ms <" + primaryServName2 + "> now is primary.");
212+
}
213+
214+
/**
215+
* verify that after the primary server shutdown, HTTP session state is migrated to the new
216+
* primary server
217+
*
218+
* @throws Exception
219+
*/
220+
@Test
221+
public void testHttpSessionMigr() throws Exception {
222+
Assume.assumeFalse(QUICKTEST);
223+
String testMethodName = new Object() {}.getClass().getEnclosingMethod().getName();
224+
logTestBegin(testMethodName);
225+
226+
Map<String, Object> domainMap = domain.getDomainMap();
227+
String domainNS = domainMap.get("namespace").toString();
228+
String domainUid = domain.getDomainUid();
229+
230+
int counterNum = 4;
231+
String testAppPath = TESTAPPNAME + "/CounterServlet";
232+
String webServiceSetUrl = testAppPath + "?setCounter=" + counterNum;
233+
String webServiceGetUrl = testAppPath + "?getCounter";
234+
235+
String primaryServ = "primary";
236+
String count = "count";
237+
238+
// Send the 1st HTTP request and save http header/sessionID info
239+
logger.info("Send the first HTTP request to set a count number.");
240+
String curlSaveHttpHeader = " -D " + httpHeaderFile;
241+
String curlCmd = buildWebServiceUrl(webServiceSetUrl, curlSaveHttpHeader);
242+
ExecResult result = execCurlCmd(curlCmd);
243+
// logger.info("HTTP resp bf promary server is stopped:\n " + result.stdout());
244+
245+
// get primary server name & count number bf primaryServName1 is stopped
246+
String primaryServName1 = getHttpResponseAttribute(result.stdout(), primaryServ);
247+
String countattribute1 = getHttpResponseAttribute(result.stdout(), count);
248+
logger.info("Primary server before is: " + primaryServName1);
249+
logger.info("count is set to: " + countattribute1);
250+
251+
// stop primary server
252+
// TODO this doesn't work. need to file a bug
253+
// domain.shutdownManagedServerUsingServerStartPolicy(primaryServName1);
254+
String msPodName = domainUid + "-" + primaryServName1;
255+
String cmd = "kubectl delete po/" + msPodName + " -n " + domainNS;
256+
logger.info("Stop managed server <" + msPodName + "> using command:\n" + cmd);
257+
result = ExecCommand.exec(cmd);
258+
logger.info(result.stdout());
259+
260+
// Send the 2nd HTTP request by use http header/sessionID info save before
261+
logger.info("Send the second HTTP request to get a count number.");
262+
String curlUseHttpHeader = " -b " + httpHeaderFile;
263+
curlCmd = buildWebServiceUrl(webServiceGetUrl, curlUseHttpHeader);
264+
result = execCurlCmd(curlCmd);
265+
// logger.info("HTTP response af promary server is stopped: \n" + result.stdout());
266+
267+
// get primary server name & count number af primaryServName1 is stopped
268+
String primaryServName2 = getHttpResponseAttribute(result.stdout(), primaryServ);
269+
String countattribute2 = getHttpResponseAttribute(result.stdout(), count);
270+
271+
logger.info("Primary server after is: " + primaryServName2);
272+
logger.info("Get count: " + countattribute2);
273+
274+
// verify that the count number is from a new primary server
275+
Assume.assumeFalse(
276+
"A new primary server should be picked!",
277+
primaryServName1.trim().equals(primaryServName2.trim()));
278+
279+
// verify that HTTP session state is migrated by checking the count number same
280+
// bf and af primaryServName1 stopped
281+
Assume.assumeTrue(
282+
"HTTP session state is NOT migrated!", countattribute1.equals(countattribute2));
283+
284+
// restore test env
285+
// TODO will use this when it works
286+
// domain.restartManagedServerUsingServerStartPolicy(primaryServName1);
287+
// wait sometime for ms pod gets ready
288+
Thread.sleep(30 * 1000);
289+
TestUtils.checkPodCreated(domainUid + "-" + primaryServName1, domainNS);
290+
TestUtils.checkPodReady(domainUid + "-" + primaryServName1, domainNS);
291+
292+
logger.info("SUCCESS - " + testMethodName + ". HTTP session state is migrated!");
293+
}
294+
295+
@Ignore
296+
@Test
297+
public void myTest1() throws Exception {
298+
Assume.assumeFalse(QUICKTEST);
299+
Map<String, Object> domainMap = domain.getDomainMap();
300+
String domainNS = domainMap.get("namespace").toString();
301+
302+
domain.shutdownManagedServerUsingServerStartPolicy("managed-server2");
303+
TestUtils.checkPodDeleted("domainonpvwlst-managed-server2", domainNS);
304+
}
305+
306+
@Ignore
307+
@Test
308+
public void myTest2() throws Exception {
309+
Assume.assumeFalse(QUICKTEST);
310+
Map<String, Object> domainMap = domain.getDomainMap();
311+
String domainNS = domainMap.get("namespace").toString();
312+
313+
domain.shutdownManagedServerUsingServerStartPolicy("domainonpvwlst-managed-server1");
314+
TestUtils.checkPodDeleted("domainonpvwlst-managed-server1", domainNS);
315+
}
316+
317+
/**
318+
* build
319+
*
320+
* @throws Exception
321+
*/
322+
private String getHttpResponseAttribute(String httpResponseString, String attribute)
323+
throws Exception {
324+
// logger.info("Looking for <" + attribute + "> in\n " + httpResponseString);
325+
String attrPatn = httpAttrMap.get(attribute);
326+
327+
Assume.assumeNotNull(attrPatn);
328+
329+
String httpAttribute = null;
330+
331+
Pattern pattern = Pattern.compile(attrPatn);
332+
Matcher matcher = pattern.matcher(httpResponseString);
333+
if (matcher.find()) {
334+
httpAttribute = matcher.group(2);
335+
}
336+
337+
// logger.info("Value for HTTP attribute found.: " + attribute + " = " + httpAttribute);
338+
339+
return httpAttribute;
340+
}
341+
342+
/**
343+
* build
344+
*
345+
* @throws Exception
346+
*/
347+
private String buildWebServiceUrl(String curlURLPath, String paramToAppend) throws Exception {
348+
String nodePortHost = domain.getHostNameForCurl();
349+
int nodePort = domain.getLoadBalancerWebPort();
350+
351+
StringBuffer webServiceUrl = new StringBuffer("curl --silent ");
352+
webServiceUrl
353+
.append(" -H 'host: ")
354+
.append(domain.getDomainUid())
355+
.append(".org' ")
356+
.append(" http://")
357+
.append(nodePortHost)
358+
.append(":")
359+
.append(nodePort)
360+
.append("/")
361+
.append(curlURLPath)
362+
.append(paramToAppend);
363+
364+
logger.info("Built web service url: " + webServiceUrl);
365+
366+
return webServiceUrl.toString();
367+
}
368+
369+
/**
370+
* build
371+
*
372+
* @throws Exception
373+
*/
374+
private ExecResult execCurlCmd(String curlCmd) throws Exception {
375+
logger.info("curl command to exec is:\n" + curlCmd);
376+
377+
ExecResult result = ExecCommand.exec(curlCmd);
378+
379+
if (result.exitValue() != 0) {
380+
throw new RuntimeException(
381+
"FAILURE: command "
382+
+ curlCmd
383+
+ " failed, returned "
384+
+ result.stderr()
385+
+ "\n "
386+
+ result.stdout());
387+
}
388+
389+
// logger.info("HTTP response is:\n " + result.stdout());
390+
391+
return result;
392+
}
393+
}

0 commit comments

Comments
 (0)