001: package com.tctest.rife.tests;
002:
003: import java.io.IOException;
004: import java.net.MalformedURLException;
005: import java.util.Date;
006: import java.util.HashMap;
007:
008: import junit.framework.Test;
009:
010: import org.xml.sax.SAXException;
011:
012: import com.meterware.httpunit.WebConversation;
013: import com.meterware.httpunit.WebForm;
014: import com.meterware.httpunit.WebRequest;
015: import com.meterware.httpunit.WebResponse;
016: import com.tc.test.server.appserver.deployment.AbstractTwoServerDeploymentTest;
017: import com.tc.test.server.appserver.deployment.DeploymentBuilder;
018: import com.tc.test.server.appserver.deployment.WebApplicationServer;
019: import com.tc.test.server.util.TcConfigBuilder;
020: import com.tc.util.TIMUtil;
021: import com.tc.util.runtime.Vm;
022: import com.tctest.rife.elements.AllTypes;
023: import com.uwyn.rife.engine.ReservedParameters;
024: import com.uwyn.rife.servlet.RifeFilter;
025: import com.uwyn.rife.tools.StringUtils;
026:
027: public class ContinuationsTest extends AbstractTwoServerDeploymentTest {
028: public static Test suite() {
029: return new ContinuationsTestSetup();
030: }
031:
032: public ContinuationsTest() {
033: if (shouldDisable()) {
034: disableAllUntil(new Date(Long.MAX_VALUE));
035: }
036: }
037:
038: public boolean shouldDisable() {
039: return super .shouldDisable() || Vm.isIBM();
040: }
041:
042: /**
043: * This test simply counts to 10 inside a while loop.
044: * The execution is paused in the middle of the loop so that the user can
045: * press a button on the form to increase the count.
046: * This test will migrate continuations between servers and check if earlier
047: * continuations are properly isolated from newer ones.
048: */
049: public void testPause() throws Exception {
050: WebConversation conversation = new WebConversation();
051:
052: // start counting on the first server, creating the first continuation
053: // in this conversation, counter is 0
054: WebResponse response1a = server0.ping(
055: "/continuations-test/counter", conversation);
056: String count1a = getCurrentCount(response1a);
057: assertEquals("0", count1a);
058: WebForm form1a = getCountForm(response1a);
059: String contid1a = getFormContinuationId(form1a);
060:
061: // increase the count on the first server, counter is now 1
062: WebResponse response1b = form1a.submit();
063: String count1b = getCurrentCount(response1b);
064: assertEquals("1", count1b);
065: WebForm form1b = getCountForm(response1b);
066: String contid1b = getFormContinuationId(form1b);
067:
068: // start counting on the second server, creating the first continuation
069: // in a new conversation on the second server, the counter there starts
070: // at 0
071: WebResponse response2a = server1.ping(
072: "/continuations-test/counter", conversation);
073: String count2a = getCurrentCount(response2a);
074: assertEquals("0", count2a);
075: WebForm form2a = getCountForm(response2a);
076: String contid2a = getFormContinuationId(form2a);
077:
078: // modify the request to the second server so that it will use the
079: // continuation
080: // ID from the last response that was sent by the first server, this should
081: // resume the count that was active on the first server
082: WebRequest request2a = form2a.newUnvalidatedRequest();
083: request2a.setParameter(ReservedParameters.CONTID, contid1b);
084:
085: // resume the conversation of the first server, the count should be 2
086: WebResponse response2b = conversation.getResponse(request2a);
087: String count2b = getCurrentCount(response2b);
088: assertEquals("2", count2b);
089: WebForm form2b = getCountForm(response2b);
090: String contid2b = getFormContinuationId(form2b);
091:
092: // ensure that this created a totally new continuation
093: assertNotEquals(contid1a, contid2b);
094: assertNotEquals(contid1b, contid2b);
095: assertNotEquals(contid2a, contid2b);
096:
097: // increase the count on the second server, counter is now 3
098: WebResponse response2c = form2b.submit();
099: assertEquals("3", getCurrentCount(response2c));
100:
101: // increase the count on the second server, counter is now 4
102: WebResponse response2d = getCountForm(response2c).submit();
103: assertEquals("4", getCurrentCount(response2d));
104:
105: // increase the count on the second server, counter is now 5
106: WebResponse response2e = getCountForm(response2d).submit();
107: WebForm form2e = getCountForm(response2e);
108: assertEquals("5", getCurrentCount(response2e));
109:
110: // increase the count on the first server, where is was left last time
111: // this should be isolated and the count in that branch of the conversion
112: // will be 2 after increasing
113: WebForm form1c = getCountForm(response1b);
114: WebResponse response1c = form1c.submit();
115: assertEquals("2", getCurrentCount(response1c));
116:
117: // modify the last request to the first server to use the continuation
118: // ID that was returned in the last response of the second server, this
119: // should resume the count that was active on the second server, counter
120: // is now 6
121: WebRequest request1d = form1c.newUnvalidatedRequest();
122: request1d.setParameter(ReservedParameters.CONTID,
123: getFormContinuationId(form2e));
124: WebResponse response1e = conversation.getResponse(request1d);
125: assertEquals("6", getCurrentCount(response1e));
126:
127: // increase the count on the first server, counter is now 7
128: WebResponse response1f = getCountForm(response1e).submit();
129: assertEquals("7", getCurrentCount(response1f));
130:
131: // increase the count on the first server, counter is now 8
132: WebResponse response1g = getCountForm(response1f).submit();
133: assertEquals("8", getCurrentCount(response1g));
134:
135: // increase the count on the first server, counter is now 9
136: WebResponse response1h = getCountForm(response1g).submit();
137: assertEquals("9", getCurrentCount(response1h));
138:
139: // increase the count on the first server, counting will be finished now
140: WebResponse response1i = getCountForm(response1h).submit();
141: WebForm form1i = getCountForm(response1i);
142: assertNull(form1i);
143: assertEquals("finished", getCurrentCount(response1i));
144: }
145:
146: private String getCurrentCount(WebResponse response)
147: throws SAXException {
148: return response.getElementWithID("currentcount").getText();
149: }
150:
151: private WebForm getCountForm(WebResponse response)
152: throws SAXException {
153: return response.getFormWithID("count");
154: }
155:
156: private String getFormContinuationId(WebForm form) {
157: return form.getParameterValue(ReservedParameters.CONTID);
158: }
159:
160: /**
161: * This test uses pause() and stepback() on the server to simulate
162: * a loop, it will continue until the total counter reaches 50
163: * the counter starts at 0 and will increase by the value that is
164: * sent through the form.
165: */
166: public void testStepBack() throws Exception {
167: final String url = "/continuations-test/stepback";
168:
169: WebForm form;
170:
171: // start the addition by accessing the first server
172: WebResponse response1 = doQueryStringRequest(server0, url, null);
173: form = response1.getFormWithName("getanswer");
174: assertEquals(": true", response1.getTitle());
175: assertNotNull(form);
176: form.setCheckbox("start", true);
177:
178: // submit the first value to the second server
179: WebResponse response2 = doQueryStringRequest(server1, url, form);
180: assertEquals("0 : false", response2.getTitle());
181: form = response2.getFormWithName("getanswer");
182: assertNotNull(form);
183: form.setParameter("answer", "12");
184:
185: // submit the second value to the first server
186: WebResponse response3 = doQueryStringRequest(server0, url, form);
187: assertEquals("12 : true", response3.getTitle());
188: form = response3.getFormWithName("getanswer");
189: assertNotNull(form);
190: form.setParameter("answer", "32");
191:
192: // submit the third value to the second server
193: WebResponse response4 = doQueryStringRequest(server1, url, form);
194: assertEquals("44 : true", response4.getTitle());
195: form = response4.getFormWithName("getanswer");
196: assertNotNull(form);
197: form.setParameter("answer", "41");
198:
199: // submit the fourth value to the first server, this will exceed the
200: // total amount of 50 and thus print out the final message
201: WebResponse response5 = doQueryStringRequest(server0, url, form);
202: assertEquals("got a total of 85 : false", response5.getTitle());
203: }
204:
205: private WebResponse doQueryStringRequest(
206: WebApplicationServer server, String location, WebForm form)
207: throws MalformedURLException, IOException, SAXException {
208: return server
209: .ping(location
210: + (null == form ? "" : "?"
211: + form.newUnvalidatedRequest()
212: .getQueryString()));
213: }
214:
215: /**
216: * This test contains operations on all basic JDK types as member fields,
217: * static fields and local variables in an element that uses continuations.
218: * It switches between servers to ensure that all the types are correctly
219: * propagated through the shared roots.
220: */
221: public void testAllTypes() throws Exception {
222: WebResponse response = null;
223: String text = null;
224: String[] lines = null;
225:
226: response = server0.ping("/continuations-test/alltypes");
227:
228: WebApplicationServer[] servers = new WebApplicationServer[] {
229: server0, server1 };
230: for (int i = 8; i < 40; i++) {
231: text = response.getText();
232: lines = StringUtils.splitToArray(text, "\n");
233: assertEquals(2, lines.length);
234: assertEquals(AllTypes.BEFORE + " while " + i, lines[0]);
235:
236: response = servers[i % 2]
237: .ping("/continuations-test/alltypes?"
238: + ReservedParameters.CONTID + "="
239: + lines[1]);
240: }
241:
242: text = response.getText();
243: lines = StringUtils.splitToArray(text, "\n");
244: assertEquals(2, lines.length);
245: assertEquals(AllTypes.BEFORE + " a", lines[0]);
246:
247: response = server0.ping("/continuations-test/alltypes?"
248: + ReservedParameters.CONTID + "=" + lines[1]);
249:
250: text = response.getText();
251: lines = StringUtils.splitToArray(text, "\n");
252: assertEquals(2, lines.length);
253: assertEquals(AllTypes.BEFORE + " b", lines[0]);
254:
255: response = server1.ping("/continuations-test/alltypes?"
256: + ReservedParameters.CONTID + "=" + lines[1]);
257:
258: text = response.getText();
259: lines = StringUtils.splitToArray(text, "\n");
260: assertEquals(2, lines.length);
261: assertEquals(AllTypes.BEFORE + " c", lines[0]);
262:
263: response = server0.ping("/continuations-test/alltypes?"
264: + ReservedParameters.CONTID + "=" + lines[1]);
265:
266: assertEquals(
267: "40,1209000,11,16,7,8,\n"
268: + "9223372036854775807,0,9223372036854775709,922337203685477570,8,-1,99,\n"
269: + "0.4,8.4,-80.4,-80.0,0.0,-1.0,\n"
270: + "2389.98,2407.3799996185303,-10.0,-1.0,-0.0,2397.3799996185303,\n"
271: + "local ok,some value 6899,\n"
272: + "true|false|false,K|O,54.7|9.8,82324.45|997823.23|87.8998,98|12,8|11,\n"
273: + "111111|444444|666666|999999,111111|444444|666666|999999,333|8888|99,333|66|99,\n"
274: + "zero|one|two|null,zero|one|two|null,ini|mini|moo,\n"
275: + "3:str 0 0|replaced|str 0 2|str 0 3||str 1 0|str 1 1|str 1 2|str 1 3||str 2 0|str 2 1|str 2 2|str 2 3,\n"
276: + "3:str 0 0|replaced|str 0 2|str 0 3||str 1 0|str 1 1|str 1 2|str 1 3||str 2 0|str 2 1|str 2 2|str 2 3,\n"
277: + "2:str 0 0|str 0 1||str 1 0|str 1 1,\n"
278: + "-98|97,-98|97,98|23|11,\n"
279: + "2:0|1|2|3|4||100|101|102|-89|104,\n"
280: + "2:0|1|2|3|4||100|101|102|-89|104,\n"
281: + "3:0|1|2||100|101|102||200|201|202,\n"
282: + "2,4,member ok,8111|8333,2:31|32|33|34||35|36|37|38,\n"
283: + "1,3,static ok,9111|9333,3:1|2|3|4||5|6|7|8||9|10|11|12,\n"
284: + "2,4,member ok,8111|8333,2:31|32|33|34||35|36|37|38,\n"
285: + "1,3,static ok,9111|9333,3:1|2|3|4||5|6|7|8||9|10|11|12,\n"
286: + "100,400,member ok two,8333|8111|23687,1:35|36|37|38,\n"
287: + "60,600,static ok two,23476|9333|9111|8334,2:9|10|11|12||1|2|3|4,\n"
288: + "2:3:3:0|1|2|3|4|5|6|7||10|11|12|13|14|15|16|17||20|21|22|23|24|25|26|27|||100|101|102|103|104|105|106|107||110|111|112|113|114|115|116|117||120|121|122|123|-99|null|126|127,\n"
289: + "2:3:3:0|1|2|3|4|5|6|7||10|11|12|13|14|15|16|17||20|21|22|23|24|25|26|27|||100|101|102|103|104|105|106|107||110|111|112|113|114|115|116|117||120|121|122|123|-99|null|126|127,\n"
290: + "4:1|3||5|7||11|-199||17|19,\n"
291: + "4:1|3||5|7||11|-199||17|19,\n"
292: + "me value 6899,\n"
293: + "2147483647,25,4,109912,118,-2147483648",
294: response.getText());
295: }
296:
297: /**
298: * This test checks if continuations also work over a cluster when the
299: * element doesn't extend Element, but rather implements the
300: * ElementAware interface.
301: */
302: public void testSimpleInterface() throws Exception {
303: WebResponse response;
304:
305: response = server0.ping("/continuations-test/simpleinterface");
306:
307: String text = response.getText();
308: String[] lines = StringUtils.splitToArray(text, "\n");
309: assertEquals(2, lines.length);
310: assertEquals("before simple pause", lines[0]);
311:
312: response = server1.ping("/continuations-test/simpleinterface?"
313: + ReservedParameters.CONTID + "=" + lines[1]);
314:
315: assertEquals("after simple pause", response.getText());
316: }
317:
318: /**
319: * This test checks if call/answer continuations work correctly over
320: * several nodes.
321: */
322: public void testCallAnswer() throws Exception {
323: WebResponse response;
324:
325: response = server0.ping("/continuations-test/callanswer");
326:
327: String text = response.getText();
328: String[] lines = StringUtils.splitToArray(text, "\n");
329: assertEquals(6, lines.length);
330: assertEquals("before call", lines[0]);
331: assertEquals("the data:somevalue", lines[2]);
332: assertEquals("before answer", lines[3]);
333: assertEquals("the exit's answer", lines[4]);
334: assertEquals("after call", lines[5]);
335:
336: response = server1.ping("/continuations-test/callanswer?"
337: + ReservedParameters.CONTID + "=" + lines[1]);
338:
339: assertEquals("after call", response.getText());
340: }
341:
342: private static class ContinuationsTestSetup extends
343: TwoServerTestSetup {
344: private ContinuationsTestSetup() {
345: super (ContinuationsTest.class,
346: "/tc-config-files/continuations-tc-config.xml",
347: "continuations-test");
348: }
349:
350: @SuppressWarnings({"serial","unchecked"})
351: protected void configureWar(DeploymentBuilder builder) {
352: builder
353: .addDirectoryOrJARContainingClass(
354: com.uwyn.rife.Version.class)
355: // rife jar
356: .addFilter("RIFE", "/*", RifeFilter.class,
357: new HashMap() {
358: {
359: put("rep.path",
360: "rife-config-files/continuations/participants.xml");
361: }
362: }).addResourceFullpath("/web-resources",
363: "counter.html",
364: "WEB-INF/classes/counter.html")
365: .addResourceFullpath("/web-resources",
366: "stepback.html",
367: "WEB-INF/classes/stepback.html");
368: }
369:
370: @SuppressWarnings({"serial","unchecked"})
371: protected void configureTcConfig(TcConfigBuilder clientConfig) {
372: clientConfig.addModule(TIMUtil.RIFE_1_6_0, TIMUtil
373: .getVersion(TIMUtil.RIFE_1_6_0));
374: }
375: }
376: }
|