001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: ProcRuns.java,v 1.5 2007/03/27 21:59:42 mlipp Exp $
021: *
022: * $Log: ProcRuns.java,v $
023: * Revision 1.5 2007/03/27 21:59:42 mlipp
024: * Fixed lots of checkstyle warnings.
025: *
026: * Revision 1.4 2006/10/13 13:58:32 drmlipp
027: * Adapted to new environment.
028: *
029: * Revision 1.3 2006/10/07 20:41:34 mlipp
030: * Merged J2EE 1.4 adaptions from test branch.
031: *
032: * Revision 1.2 2006/09/29 12:32:10 drmlipp
033: * Consistently using WfMOpen as projct name now.
034: *
035: * Revision 1.1.1.3 2004/08/18 15:18:47 drmlipp
036: * Update to 1.2
037: *
038: * Revision 1.6 2004/01/27 11:45:33 lipp
039: * Preserve newlines when reading process definitions.
040: *
041: * Revision 1.5 2003/10/21 21:00:45 lipp
042: * Moved EJBClientTest to new junit sub-package.
043: *
044: * Revision 1.4 2003/10/08 11:52:55 huaiyang
045: * make test weblogic compatible.
046: *
047: * Revision 1.3 2003/09/19 13:12:29 lipp
048: * Adapted to closed.completed having a substate.
049: *
050: * Revision 1.2 2003/06/27 09:44:13 lipp
051: * Fixed copyright/license information.
052: *
053: * Revision 1.1 2003/04/26 16:46:55 lipp
054: * Made unittests and systemtests coexist in eclipse.
055: *
056: * Revision 1.19 2003/04/16 19:25:04 lipp
057: * Adapted to jdk 1.4
058: *
059: * Revision 1.18 2003/02/25 17:08:27 lipp
060: * Reorganized requester implementation.
061: *
062: * Revision 1.17 2003/02/24 10:46:41 lipp
063: * Removed usage of System.out and .err.
064: *
065: * Revision 1.16 2003/02/05 15:57:06 lipp
066: * Replaced DummyRequester with DefaultRequester.
067: *
068: * Revision 1.15 2002/12/09 10:52:57 lipp
069: * Updated to abort() modifications.
070: *
071: * Revision 1.14 2002/11/20 15:31:55 huaiyang
072: * Add test method of removeClosedProcessjut1.
073: *
074: * Revision 1.13 2002/11/19 15:14:52 lipp
075: * New transition manager.
076: *
077: * Revision 1.12 2002/11/06 13:27:17 barzik
078: * add test case for removing a process from the system
079: *
080: * Revision 1.11 2002/10/23 11:36:47 lipp
081: * Got them running again.
082: *
083: * Revision 1.10 2002/10/23 07:29:15 lipp
084: * Adapted to state handling changes.
085: *
086: * Revision 1.9 2002/10/22 17:19:01 lipp
087: * Still adapting to state handling changes.
088: *
089: * Revision 1.8 2002/09/08 18:49:18 lipp
090: * Proper use of packageId and processId.
091: *
092: * Revision 1.7 2002/09/04 20:50:44 lipp
093: * Adapted to new process manager name schema.
094: *
095: * Revision 1.6 2002/08/30 13:37:05 lipp
096: * Using Workflow engine facade now.
097: *
098: * Revision 1.5 2002/08/26 20:23:14 lipp
099: * Lots of method renames.
100: *
101: * Revision 1.4 2002/08/21 22:06:48 lipp
102: * Finished transition to ProcessMgrStub.
103: *
104: * Revision 1.3 2002/08/19 13:58:14 lipp
105: * Javadoc fixes.
106: *
107: * Revision 1.2 2002/08/16 12:52:00 huaiyang
108: * Add the test of ProcessAPI.
109: *
110: * Revision 1.1 2002/08/16 12:08:52 huaiyang
111: * Initial.
112: *
113: *
114: */
115: package process;
116:
117: import java.io.BufferedReader;
118: import java.io.InputStream;
119: import java.io.InputStreamReader;
120: import java.util.Arrays;
121: import java.util.Collection;
122: import java.util.Comparator;
123: import java.util.Iterator;
124:
125: import junit.framework.Test;
126: import junit.framework.TestCase;
127: import junit.framework.TestSuite;
128:
129: import common.UTLoginContext;
130: import javax.security.auth.login.LoginException;
131:
132: import de.danet.an.util.EJBUtil;
133: import de.danet.an.util.junit.EJBClientTest;
134: import de.danet.an.workflow.api.CannotRemoveException;
135: import de.danet.an.workflow.api.DefaultRequester;
136: import de.danet.an.workflow.api.FactoryConfigurationError;
137: import de.danet.an.workflow.api.Process;
138: import de.danet.an.workflow.api.ProcessDefinitionDirectory;
139: import de.danet.an.workflow.api.ProcessDirectory;
140: import de.danet.an.workflow.api.ProcessMgr;
141: import de.danet.an.workflow.api.WorkflowService;
142: import de.danet.an.workflow.api.WorkflowServiceFactory;
143: import de.danet.an.workflow.ejbs.admin.ProcessDefinitionDirectoryHome;
144: import de.danet.an.workflow.ejbs.admin.ProcessDirectoryHome;
145: import de.danet.an.workflow.omgcore.WfActivity;
146: import de.danet.an.workflow.omgcore.WfExecutionObject;
147: import de.danet.an.workflow.omgcore.WfProcess;
148: import de.danet.an.workflow.omgcore.WfRequester;
149:
150: /**
151: * Test the life cycle of different processes.
152: */
153: public class ProcRuns extends TestCase {
154: private static UTLoginContext plc = null;
155: static {
156: try {
157: plc = new UTLoginContext();
158: plc.login();
159: } catch (LoginException e) {
160: throw new IllegalStateException(e.getMessage());
161: }
162: }
163:
164: /**
165: * A process directory reference.
166: */
167: private ProcessDirectory pdd = null;
168:
169: /**
170: * Constructor of this TestCase
171: */
172: public ProcRuns(String name) {
173: super (name);
174: }
175:
176: /**
177: * Stellt diese TestSuite zusammen.
178: */
179: public static Test suite() {
180: TestSuite suite = new TestSuite();
181: suite.addTest(new ProcRuns("importProcessDefinitions"));
182: suite.addTest(new ProcRuns("processjut2"));
183: suite.addTest(new ProcRuns("processjut4"));
184: suite.addTest(new ProcRuns("processjut6"));
185: suite.addTest(new ProcRuns("processAPI"));
186: suite.addTest(new ProcRuns("removejut1"));
187: suite.addTest(new ProcRuns("removeClosedProcessjut1"));
188: return new EJBClientTest(plc, suite);
189: }
190:
191: private static final String OPEN_RUNNING = WfExecutionObject.OpenState.RUNNING
192: .toString();
193: private static final String OPEN_NOT_RUNNING = WfExecutionObject.OpenState.NOT_RUNNING
194: .toString();
195: private static final String CLOSED_COMPLETED = WfExecutionObject.ClosedState.COMPLETED
196: .toString();
197: private static final String CLOSED_ABORTED = WfExecutionObject.ClosedState.ABORTED
198: .toString();
199: private static final String NOT_STARTED = WfExecutionObject.NotRunningState.NOT_STARTED
200: .toString();
201:
202: private WorkflowService workflowService = null;
203:
204: /**
205: * Initialisierung.
206: */
207: protected void setUp() throws Exception {
208: try {
209: WorkflowServiceFactory wfsf = WorkflowServiceFactory
210: .newInstance();
211: workflowService = wfsf.newWorkflowService();
212: } catch (FactoryConfigurationError e) {
213: throw new IllegalStateException(e.getMessage());
214: }
215: }
216:
217: protected void tearDown() throws Exception {
218: workflowService.release(workflowService);
219: workflowService = null;
220: }
221:
222: private static WorkflowService wfsCache = null;
223:
224: /**
225: * Import the process definitions from a XPDL file
226: * unsing the ProcessDefinitionDirectory bean.
227: */
228: public void importProcessDefinitions() throws Exception {
229: // Create process definition directory bean
230: ProcessDefinitionDirectory pdd = workflowService
231: .processDefinitionDirectory();
232:
233: InputStream is = getClass().getResourceAsStream(
234: "/process/testXPDL.xml");
235: assertTrue(is != null);
236: BufferedReader br = new BufferedReader(new InputStreamReader(
237: is, "ISO-8859-1"));
238: StringBuffer sb = new StringBuffer();
239: String st;
240: while ((st = br.readLine()) != null) {
241: sb.append(st + "\n");
242: }
243: pdd.importProcessDefinitions(sb.toString());
244: Collection processDefinitions = pdd.processDefinitions();
245: assertTrue(processDefinitions.size() > 0);
246:
247: }
248:
249: private WfProcess createProcess(String pkgId, String prcId,
250: WfRequester req) throws Exception {
251: ProcessDefinitionDirectory procDir = null;
252: try {
253: procDir = workflowService.processDefinitionDirectory();
254: ProcessMgr pmgr = procDir.processMgr(pkgId, prcId);
255: return pmgr.createProcess(req);
256: } finally {
257: workflowService.release(procDir);
258: }
259: }
260:
261: /**
262: * Test a simple process definition. The activities will be started
263: * manually and stopped manually one after another.
264: * <pre>
265: * A21 --> A22 --> A23 --> A24
266: * </pre>
267: * without any branched activity.
268: */
269: public void processjut2() throws Exception {
270: WfRequester req = new DefaultRequester(workflowService);
271: // create the process
272: WfProcess process = createProcess("ut-process", "jut2", req);
273: assertTrue(process.state().equals(
274: "open.not_running.not_started"));
275: // start the process
276: process.start();
277: assertTrue(process.state().startsWith("open.running"));
278: Thread.sleep(1000);
279: // start the activities and stop it.
280: for (int i = 1; i <= 4; i++) {
281: Collection c = process.steps();
282: WfActivity a = null;
283: for (Iterator it = c.iterator(); it.hasNext();) {
284: a = (WfActivity) it.next();
285: if (a.name().equals("A2" + i)) {
286: break;
287: }
288: }
289: assertTrue(a.state() != null);
290: boolean exceptionCaught = false;
291: assertTrue(a.name() + " not open.not_running.suspended: "
292: + a.state(), a.state().startsWith(
293: "open.not_running.suspended"));
294: a.resume();
295: Thread.sleep(1000);
296: a.resume();
297: Thread.sleep(1000);
298: assertTrue(
299: a.name() + " not closed.completed: " + a.state(), a
300: .state().startsWith("closed.completed"));
301: }
302: assertTrue(process.state().startsWith("closed.completed"));
303: }
304:
305: /**
306: * Test a process definition with XOR-splitted activity.
307: * The activities will be started manually and stopped manually one
308: * after another.
309: * <pre>
310: * |--> A42 --|
311: * A41 --| --| --> A44
312: * |--> A43 --|
313: * </pre>
314: */
315: public void processjut4() throws Exception {
316: WfRequester req = new DefaultRequester(workflowService);
317: // create the process
318: WfProcess process = createProcess("ut-process", "jut4", req);
319: assertTrue(process.state().equals(
320: "open.not_running.not_started"));
321: // start the process
322: process.start();
323: assertTrue(process.state().startsWith("open.running"));
324: Thread.sleep(1000);
325: // start the activities and stop it.
326: Object[] actArray = process.steps().toArray();
327: assertTrue(actArray.length == 4);
328: Arrays.sort(actArray, new Comparator() {
329: public int compare(Object o1, Object o2) {
330: return ((WfActivity) o1).toString().compareTo(
331: ((WfActivity) o2).toString());
332: }
333: });
334: WfActivity a41 = (WfActivity) actArray[0];
335: WfActivity a42 = (WfActivity) actArray[1];
336: WfActivity a43 = (WfActivity) actArray[2];
337: WfActivity a44 = (WfActivity) actArray[3];
338: // start A41
339: assertTrue(a41.state().startsWith("open.not_running.suspended"));
340: a41.resume();
341: Thread.sleep(1000);
342: assertTrue(a42.state().startsWith("open.not_running.suspended"));
343: assertTrue(a43.state().startsWith(
344: "open.not_running.not_started"));
345: assertTrue(a44.state().startsWith(
346: "open.not_running.not_started"));
347: // start A42
348: a42.resume();
349: Thread.sleep(1000);
350: assertTrue(a43.state().startsWith(
351: "open.not_running.not_started"));
352: assertTrue(a44.state().startsWith("open.not_running.suspended"));
353: // start A44
354: a44.resume();
355: Thread.sleep(1000);
356: // process terminated
357: assertTrue(process.state().startsWith("closed.completed"));
358: }
359:
360: /**
361: * Test a complex process definition.
362: * The activities will be finished manually.
363: */
364: public void processjut6() throws Exception {
365: WfRequester req = new DefaultRequester(workflowService);
366: // create the process
367: WfProcess process = createProcess("ut-process", "jut6", req);
368: assertTrue(process.state().equals(
369: "open.not_running.not_started"));
370: // start the process
371: process.start();
372: assertTrue(process.state().startsWith("open.running"));
373: Thread.sleep(1000);
374: // start the activities and stop it.
375: Object[] actArray = process.steps().toArray();
376: assertTrue(actArray.length == 8);
377: Arrays.sort(actArray, new Comparator() {
378: public int compare(Object o1, Object o2) {
379: return ((WfActivity) o1).toString().compareTo(
380: ((WfActivity) o2).toString());
381: }
382: });
383: WfActivity a61 = (WfActivity) actArray[0];
384: WfActivity a62 = (WfActivity) actArray[1];
385: WfActivity a63 = (WfActivity) actArray[2];
386: WfActivity a64 = (WfActivity) actArray[3];
387: WfActivity a65 = (WfActivity) actArray[4];
388: WfActivity a66 = (WfActivity) actArray[5];
389: WfActivity a67 = (WfActivity) actArray[6];
390: WfActivity a68 = (WfActivity) actArray[7];
391: // start A61
392: assertTrue(a61.state().startsWith("open.not_running.suspended"));
393: a61.resume();
394: Thread.sleep(1000);
395: assertTrue(a62.state().startsWith(
396: "open.not_running.not_started"));
397: assertTrue(a63.state().startsWith("open.not_running.suspended"));
398: assertTrue(a64.state().startsWith(
399: "open.not_running.not_started"));
400: // start A63
401: a63.resume();
402: Thread.sleep(1000);
403: assertTrue(a66.state().startsWith("open.not_running.suspended"));
404: assertTrue(a65.state().startsWith(
405: "open.not_running.not_started"));
406: // start A66 and then stop it.
407: a66.resume();
408: Thread.sleep(1000);
409: // start A67
410: a67.resume();
411: Thread.sleep(1000);
412: // start A68
413: a68.resume();
414: Thread.sleep(1000);
415: // process terminated
416: assertTrue(process.state().startsWith("closed.completed"));
417: }
418:
419: public void processAPI() throws Exception {
420: abortProcess();
421: //suspendresumeProcess();
422: }
423:
424: //Abort Process
425: private void abortProcess() throws Exception {
426: WfRequester req = new DefaultRequester(workflowService);
427: WfProcess process = createProcess("ut-process", "jut2", req);
428: assertTrue(process.state().equals(
429: "open.not_running.not_started"));
430: process.start();
431: assertTrue(process.state().startsWith("open.running"));
432: process.suspend();
433: process.abort();
434: assertTrue(process.state().equals("closed.aborted"));
435: }
436:
437: //Suspend Process then resume it
438: private void suspendresumeProcess() throws Exception {
439: WfRequester req = new DefaultRequester(workflowService);
440: WfProcess process = createProcess("ut-process", "jut2", req);
441: assertTrue(process.state().equals(
442: "open.not_running.not_started"));
443: process.start();
444: assertTrue(process.state().equals("open.running"));
445: process.suspend();
446: assertTrue(process.state().equals("open.not_running.suspended"));
447: process.resume();
448: assertTrue(process.state().equals("open.running"));
449: }
450:
451: private boolean allActivitiesOfProcessHaveState(WfProcess proc,
452: String state) throws Exception {
453: Iterator it = proc.steps().iterator();
454: while (it.hasNext()) {
455: WfActivity a = (WfActivity) it.next();
456: if (!a.state().startsWith(state)) {
457: return false;
458: }
459: }
460: return true;
461: }
462:
463: /**
464: * Test a simple process definition according to remove the process.
465: * A process may be removed only and if only its state is CLOSED.
466: * Tests:
467: * 1.) remove not closed process
468: * 2.) remove closed process
469: * Please note definitions matching the (logical) code flow, e.g. start and
470: * finish mode of the corresponding activities.
471: */
472: public void removejut1() throws Exception {
473: WfRequester req = new DefaultRequester(workflowService);
474: // create the process
475: Process process = (Process) (createProcess("ut-process",
476: "jut1", req));
477: assertTrue(process.state().equals(
478: "open.not_running.not_started"));
479: // start the process
480: process.start();
481: assertTrue(process.state().startsWith("open.running"));
482: Thread.sleep(1000);
483: // start the first two activities and stop it.
484: Collection c = process.steps();
485: for (int i = 1; i <= 2; i++) {
486: WfActivity a = null;
487: for (Iterator it = c.iterator(); it.hasNext();) {
488: a = (WfActivity) it.next();
489: if (a.name().equals("A1" + i)) {
490: break;
491: }
492: }
493: if (a.name().equals("A12")) {
494: Thread.sleep(1000);
495: a.resume();
496: }
497: Thread.sleep(1000);
498: assertTrue(
499: a.name() + " not closed.completed: " + a.state(), a
500: .state().startsWith("closed.completed"));
501: }
502: assertTrue(!process.state().equals("closed.completed"));
503:
504: // try to remove the process (should result into an exception)
505: boolean removeExceptionCaught = false;
506: try {
507: //Process p = processDirectory().lookupProcess(null, process.key());
508: processDirectory().removeProcess(process);
509: assertTrue(false);
510: } catch (CannotRemoveException cre) {
511: removeExceptionCaught = true;
512: } catch (Exception e) {
513: e.printStackTrace();
514: assertTrue("Unexpected exception caugth", false);
515: }
516: assertTrue(
517: "did not receive CannotRemoveException for a process "
518: + "that has not been terminated",
519: removeExceptionCaught);
520:
521: // start the last activity and stop it.
522: for (int i = 3; i <= 3; i++) {
523: WfActivity a = null;
524: for (Iterator it = c.iterator(); it.hasNext();) {
525: a = (WfActivity) it.next();
526: if (a.name().equals("A1" + i)) {
527: break;
528: }
529: }
530: assertTrue(a.state() != null);
531: boolean exceptionCaught = false;
532: assertTrue(a.name() + " not open.not_running.suspended: "
533: + a.state(), a.state().startsWith(
534: "open.not_running.suspended"));
535: a.resume();
536: Thread.sleep(1000);
537: a.resume();
538: Thread.sleep(1000);
539: assertTrue(
540: a.name() + " not closed.completed: " + a.state(), a
541: .state().startsWith("closed.completed"));
542: }
543: assertTrue(process + " not closed.completed: "
544: + process.state(), process.state().startsWith(
545: "closed.completed"));
546:
547: // finally remove the process and retry to access it
548: boolean exceptionCaught = false;
549: Process p = processDirectory().lookupProcess(null,
550: process.key());
551: processDirectory().removeProcess(process);
552: try {
553: process.start();
554: } catch (Exception e) {
555: //e.printStackTrace();
556: exceptionCaught = true;
557: }
558: assertTrue("Could start a removed process", exceptionCaught);
559: }
560:
561: /**
562: * Test a simple process definition according to remove the process.
563: * A process can be removed automatically only if its state is CLOSED and
564: * the extendedAttribute of removeClosedProcess in procss definition is
565: * AUTOMATIC (Default: AUTOMATIC).
566: */
567: public void removeClosedProcessjut1() throws Exception {
568: WfRequester req = new DefaultRequester(workflowService);
569: ProcessDirectory procDir = processDirectory();
570: // create the process
571: Process process = (Process) (createProcess("ut-process",
572: "jut5", req));
573: String processKey = process.key();
574: assertTrue(process.state().equals(
575: "open.not_running.not_started"));
576: // start the process
577: process.start();
578: assertTrue(process.state().startsWith("open.running"));
579: Thread.sleep(1000);
580: process.suspend();
581: process.abort();
582: Thread.sleep(1000);
583: boolean procExists = true;
584: try {
585: procDir.lookupProcess("ut-process/jut5", processKey);
586: } catch (Exception e) {
587: procExists = false;
588: }
589: assertTrue(!procExists);
590: }
591:
592: /**
593: * Returns a reference to a process directory.
594: * @return the process directory
595: */
596: private ProcessDirectory processDirectory() throws Exception {
597: if (pdd == null) {
598: pdd = workflowService.processDirectory();
599: }
600: return pdd;
601: }
602:
603: }
|