Skip to content

Commit 3c2e2f1

Browse files
committed
jenkins-ignore Completed JIRA OWLS-72999 - Migrate Sticky Sessions test suite to github
1 parent d461d8e commit 3c2e2f1

File tree

5 files changed

+452
-1
lines changed

5 files changed

+452
-1
lines changed
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
// Copyright 2019, 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.ExecResult;
13+
import oracle.kubernetes.operator.utils.Operator;
14+
import oracle.kubernetes.operator.utils.TestUtils;
15+
import org.junit.AfterClass;
16+
import org.junit.Assume;
17+
import org.junit.BeforeClass;
18+
import org.junit.FixMethodOrder;
19+
import org.junit.Test;
20+
import org.junit.runners.MethodSorters;
21+
22+
/**
23+
* Simple JUnit test file used for testing Operator.
24+
*
25+
* <p>This test is used for testing the affinity between a web client and a Weblogic server for the
26+
* duration of a HTTP session created by Voyager load balancer.
27+
*/
28+
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
29+
public class ITStickySession extends BaseTest {
30+
private static final String testAppName = "stickysessionapp";
31+
private static final String testAppPath = testAppName + "/StickySessionCounterServlet";
32+
// private static final String testAppName = "httpsessionreptestapp";
33+
// private static final String testAppPath = testAppName + "/CounterServlet";
34+
private static final String scriptName = "buildDeployAppInPod.sh";
35+
36+
private static Map<String, String> httpAttrMap;
37+
38+
private static String httpHeaderFile;
39+
40+
private static Operator operator;
41+
private static Domain domain;
42+
43+
/**
44+
* This method gets called only once before any of the test methods are executed. It does the
45+
* initialization of the integration test properties defined in OperatorIT.properties and setting
46+
* the resultRoot, pvRoot and projectRoot attributes. It creates an operator, a Weblogic domain
47+
* and deploy a web application with persistent-store-type configured to replicated_if_clustered.
48+
*
49+
* @throws Exception
50+
*/
51+
@BeforeClass
52+
public static void staticPrepare() throws Exception {
53+
if (!QUICKTEST) {
54+
// initialize test properties and create the directories
55+
initialize(APP_PROPS_FILE);
56+
57+
// Create operator1
58+
if (operator == null) {
59+
logger.info("Creating Operator & waiting for the script to complete execution");
60+
operator = TestUtils.createOperator(OPERATOR1_YAML);
61+
}
62+
63+
// create domain
64+
if (domain == null) {
65+
logger.info("Creating WLS Domain & waiting for the script to complete execution");
66+
System.setProperty("LB_TYPE", "VOYAGER");
67+
domain = TestUtils.createDomain(DOMAINONPV_WLST_YAML);
68+
domain.verifyDomainCreated();
69+
}
70+
71+
httpHeaderFile = BaseTest.getResultDir() + "/headers";
72+
73+
httpAttrMap = new HashMap<String, String>();
74+
httpAttrMap.put("sessioncreatetime", "(.*)sessioncreatetime>(.*)</sessioncreatetime(.*)");
75+
httpAttrMap.put("sessionid", "(.*)sessionid>(.*)</sessionid(.*)");
76+
httpAttrMap.put("servername", "(.*)connectedservername>(.*)</connectedservername(.*)");
77+
httpAttrMap.put("count", "(.*)countattribute>(.*)</countattribute(.*)");
78+
79+
// Build WAR in the admin pod and deploy it from the admin pod to a weblogic target
80+
domain.buildDeployJavaAppInPod(
81+
testAppName, scriptName, BaseTest.getUsername(), BaseTest.getPassword());
82+
83+
// Wait some time for deployment gets ready
84+
Thread.sleep(10 * 1000);
85+
}
86+
}
87+
88+
/**
89+
* Releases k8s cluster lease, archives result, pv directories
90+
*
91+
* @throws Exception
92+
*/
93+
@AfterClass
94+
public static void staticUnPrepare() throws Exception {
95+
logger.info("+++++++++++++++++++++++++++++++++---------------------------------+");
96+
logger.info("BEGIN");
97+
logger.info("Run once, release cluster lease");
98+
99+
tearDown(new Object() {}.getClass().getEnclosingClass().getSimpleName());
100+
101+
logger.info("SUCCESS");
102+
}
103+
104+
/**
105+
* Use a web application deployed on Weblogic cluster to track HTTP session. In-memory replication
106+
* persistence method is configured to implement session persistence. server-affinity is achieved
107+
* by Voyager load balancer based on HTTP session information. This test sends two HTTP requests
108+
* to Weblogic and verify that all requests are directed to same Weblogic server.
109+
*
110+
* @throws Exception
111+
*/
112+
@Test
113+
public void testSameSessionStickiness() throws Exception {
114+
Assume.assumeFalse(QUICKTEST);
115+
String testMethodName = new Object() {}.getClass().getEnclosingMethod().getName();
116+
logTestBegin(testMethodName);
117+
118+
Map<String, Object> domainMap = domain.getDomainMap();
119+
String domainNS = domainMap.get("namespace").toString();
120+
String domainUid = domain.getDomainUid();
121+
122+
int counterNum = 4;
123+
String webServiceSetUrl = testAppPath + "?setCounter=" + counterNum;
124+
String webServiceGetUrl = testAppPath + "?getCounter";
125+
126+
String serverNameAttr = "servername";
127+
String sessionIDAttr = "sessionid";
128+
String countAttr = "count";
129+
130+
// Send the first HTTP request to the cluster to establish a connection
131+
ExecResult result = getHTTPResponse(webServiceSetUrl, " -D ");
132+
133+
// Retrieve the session id and connected server name from the first HTTP response
134+
String serverName1 = getHttpResponseAttribute(result.stdout(), serverNameAttr);
135+
String serverID1 = getHttpResponseAttribute(result.stdout(), sessionIDAttr);
136+
137+
Assume.assumeNotNull(serverName1);
138+
Assume.assumeNotNull(serverID1);
139+
140+
logger.info(
141+
"The first HTTP request established a connection with server <"
142+
+ serverName1
143+
+ ">, HTTP session id is <"
144+
+ serverID1
145+
+ ">");
146+
147+
// Send the second HTTP request to the cluster to get the count number
148+
result = getHTTPResponse(webServiceGetUrl, " -b ");
149+
150+
// Retrieve the session id and connected server name from the second HTTP response
151+
String serverName2 = getHttpResponseAttribute(result.stdout(), serverNameAttr);
152+
String serverID2 = getHttpResponseAttribute(result.stdout(), sessionIDAttr);
153+
String count = getHttpResponseAttribute(result.stdout(), countAttr);
154+
155+
Assume.assumeNotNull(serverName2);
156+
Assume.assumeNotNull(serverID2);
157+
Assume.assumeNotNull(count);
158+
159+
logger.info(
160+
"The second HTTP request connected to server <"
161+
+ serverName2
162+
+ "> with HTTP session id <"
163+
+ serverID2
164+
+ ">");
165+
166+
// Verify that the same session info is used
167+
Assume.assumeTrue("HTTP session should NOT change!", serverID1.equals(serverID2));
168+
logger.info("Same HTTP session id <" + serverID1 + "> is used");
169+
170+
// Verify server-affinity
171+
Assume.assumeTrue("Weblogic server name should NOT change!", serverName1.equals(serverName2));
172+
logger.info("Two HTTP requests are directed to same Weblogic server <" + serverName1 + ">");
173+
174+
// Verify that count numbers from two HTTP responses match
175+
Assume.assumeTrue("Count number does not match", Integer.parseInt(count) == counterNum);
176+
logger.info(
177+
"Count number <"
178+
+ count
179+
+ "> got from HTTP response matches "
180+
+ "original setting <"
181+
+ counterNum
182+
+ ">");
183+
184+
logger.info("SUCCESS - " + testMethodName);
185+
}
186+
187+
/**
188+
* Use a web application deployed on Weblogic cluster to track HTTP sessions. This test sends two
189+
* HTTP requests from two different clients to Weblogic and verify that HTTP sessions are
190+
* isolated.
191+
*
192+
* @throws Exception
193+
*/
194+
@Test
195+
public void testDiffSessionsNoSharing() throws Exception {
196+
Assume.assumeFalse(QUICKTEST);
197+
String testMethodName = new Object() {}.getClass().getEnclosingMethod().getName();
198+
logTestBegin(testMethodName);
199+
200+
Map<String, Object> domainMap = domain.getDomainMap();
201+
String domainNS = domainMap.get("namespace").toString();
202+
String domainUid = domain.getDomainUid();
203+
204+
int counterNum = 4;
205+
String webServiceSetUrl = testAppPath + "?setCounter=" + counterNum;
206+
String webServiceGetUrl = testAppPath + "?getCounter";
207+
208+
String sessionIDAttr = "sessionid";
209+
String countAttr = "count";
210+
211+
// Client1 sends a HTTP request to set a count number
212+
ExecResult result = getHTTPResponse(webServiceSetUrl);
213+
214+
// Retrieve the session id from HTTP response
215+
String serverIDClient1 = getHttpResponseAttribute(result.stdout(), sessionIDAttr);
216+
Assume.assumeNotNull(serverIDClient1);
217+
218+
logger.info(
219+
"Client1 created a connection with HTTP session id <"
220+
+ serverIDClient1
221+
+ "> and set a count number to <"
222+
+ counterNum
223+
+ ">");
224+
225+
// Client2 sends a HTTP request to get a count number
226+
result = getHTTPResponse(webServiceGetUrl);
227+
228+
// Retrieve the session id and count number from HTTP response
229+
String serverIDClient2 = getHttpResponseAttribute(result.stdout(), sessionIDAttr);
230+
String count = getHttpResponseAttribute(result.stdout(), countAttr);
231+
232+
Assume.assumeNotNull(serverIDClient2);
233+
Assume.assumeNotNull(count);
234+
235+
logger.info(
236+
"Client2 created a connection with HTTP session id <"
237+
+ serverIDClient2
238+
+ "> and retrieved a count number <"
239+
+ count
240+
+ ">");
241+
242+
// Verify that each client session has a different session ID
243+
Assume.assumeFalse("HTTP session should NOT be same!", serverIDClient1.equals(serverIDClient2));
244+
245+
// Verify that HTTP session state is not shared between two clients
246+
Assume.assumeTrue(
247+
"Count number <" + counterNum + "> set by client1 should be invisible to client2",
248+
count.equals("0"));
249+
250+
logger.info("SUCCESS - " + testMethodName);
251+
}
252+
253+
private String getHttpResponseAttribute(String httpResponseString, String attribute)
254+
throws Exception {
255+
256+
String attrPatn = httpAttrMap.get(attribute);
257+
258+
Assume.assumeNotNull(attrPatn);
259+
260+
String httpAttribute = null;
261+
262+
Pattern pattern = Pattern.compile(attrPatn);
263+
Matcher matcher = pattern.matcher(httpResponseString);
264+
265+
if (matcher.find()) {
266+
httpAttribute = matcher.group(2);
267+
}
268+
269+
return httpAttribute;
270+
}
271+
272+
private ExecResult getHTTPResponse(String webServiceURL, String... args) throws Exception {
273+
String headerOption = (args.length == 0) ? "" : args[0] + httpHeaderFile;
274+
275+
// Send a HTTP request
276+
String curlCmd = buildWebServiceUrl(webServiceURL, headerOption);
277+
logger.info("Send a HTTP request: " + curlCmd);
278+
279+
ExecResult result = TestUtils.exec(curlCmd);
280+
281+
return result;
282+
}
283+
284+
private String buildWebServiceUrl(String curlURLPath, String paramToAppend) throws Exception {
285+
String nodePortHost = domain.getHostNameForCurl();
286+
int nodePort = domain.getLoadBalancerWebPort();
287+
288+
StringBuffer webServiceUrl = new StringBuffer("curl --silent ");
289+
webServiceUrl
290+
.append(" -H 'host: ")
291+
.append(domain.getDomainUid())
292+
.append(".org' ")
293+
.append(" http://")
294+
.append(nodePortHost)
295+
.append(":")
296+
.append(nodePort)
297+
.append("/")
298+
.append(curlURLPath)
299+
.append(paramToAppend);
300+
301+
return webServiceUrl.toString();
302+
}
303+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,9 @@ private void initialize(Map<String, Object> inputDomainMap) throws Exception {
12911291
"cp -rf " + BaseTest.getProjectRoot() + "/kubernetes/samples " + BaseTest.getResultDir());
12921292

12931293
this.voyager =
1294-
System.getenv("LB_TYPE") != null && System.getenv("LB_TYPE").equalsIgnoreCase("VOYAGER");
1294+
(System.getenv("LB_TYPE") != null && System.getenv("LB_TYPE").equalsIgnoreCase("VOYAGER"))
1295+
|| (System.getProperty("LB_TYPE") != null
1296+
&& System.getProperty("LB_TYPE").equalsIgnoreCase("VOYAGER"));
12951297
if (System.getenv("INGRESSPERDOMAIN") != null) {
12961298
INGRESSPERDOMAIN = new Boolean(System.getenv("INGRESSPERDOMAIN")).booleanValue();
12971299
}

0 commit comments

Comments
 (0)