001: package org.mvel.tests.main;
002:
003: import junit.framework.TestCase;
004: import org.mvel.MVEL;
005: import static org.mvel.MVEL.compileExpression;
006: import static org.mvel.MVEL.executeExpression;
007: import org.mvel.ParserContext;
008: import org.mvel.compiler.CompiledExpression;
009: import org.mvel.compiler.ExpressionCompiler;
010: import static org.mvel.debug.DebugTools.decompile;
011: import org.mvel.debug.DebugTools;
012: import org.mvel.integration.impl.MapVariableResolverFactory;
013: import static org.mvel.optimizers.OptimizerFactory.setDefaultOptimizer;
014: import org.mvel.tests.main.res.*;
015: import org.mvel.util.StringAppender;
016:
017: import java.io.*;
018: import static java.lang.Integer.parseInt;
019: import static java.lang.String.valueOf;
020: import static java.lang.System.currentTimeMillis;
021: import static java.lang.System.getProperty;
022: import java.math.BigDecimal;
023: import java.math.BigInteger;
024: import java.text.SimpleDateFormat;
025: import java.util.*;
026:
027: public abstract class AbstractTest extends TestCase {
028:
029: private boolean silentTests = Boolean
030: .getBoolean("mvel.tests.silent");
031:
032: public void testNothing() {
033: // to satify Eclipse and Surefire.
034: }
035:
036: protected void setUp() throws Exception {
037:
038: }
039:
040: protected static Map createTestMap() {
041: Map map = new HashMap();
042: map.put("foo", new Foo());
043: map.put("a", null);
044: map.put("b", null);
045: map.put("c", "cat");
046: map.put("BWAH", "");
047:
048: map.put("misc", new MiscTestClass());
049:
050: map.put("pi", "3.14");
051: map.put("hour", "60");
052: map.put("zero", 0);
053:
054: map.put("order", new Order());
055: map.put("$id", 20);
056:
057: map.put("five", 5);
058:
059: map.put("testImpl", new TestInterface() {
060:
061: public String getName() {
062: return "FOOBAR!";
063: }
064:
065: public boolean isFoo() {
066: return true;
067: }
068: });
069:
070: map.put("derived", new DerivedClass());
071:
072: map.put("dt1", new Date(currentTimeMillis() - 100000));
073: map.put("dt2", new Date(currentTimeMillis()));
074: return map;
075: }
076:
077: protected void tearDown() throws Exception {
078: }
079:
080: protected Object test(final String ex) {
081: Thread[] threads;
082:
083: if (Boolean.getBoolean("mvel.tests.quick")) {
084: threads = new Thread[1];
085: } else if (getProperty("mvel.tests.threadcount") != null) {
086: threads = new Thread[parseInt(getProperty("mvel.tests.threadcount"))];
087: } else {
088: threads = new Thread[5];
089: }
090:
091: final AbstractTest aTest = this ;
092: final Collection<Object> results = Collections
093: .synchronizedCollection(new LinkedList<Object>());
094: long time = currentTimeMillis();
095:
096: for (int i = 0; i < threads.length; i++) {
097: threads[i] = new Thread(new TestRunner(results, ex));
098: }
099:
100: if (!silentTests) {
101: System.out
102: .println("\n[test] begin test for:\n----------------------");
103: System.out.println(ex);
104: System.out.println("----------------------");
105: }
106:
107: for (Thread thread1 : threads) {
108: if (threads.length > 1) {
109: System.out.println("Start Thread.");
110: thread1.setPriority(Thread.MIN_PRIORITY);
111: thread1.start();
112: } else {
113: thread1.run();
114: }
115: }
116:
117: if (threads.length > 1) {
118: boolean threadsRunning = true;
119: while (threadsRunning) {
120: threadsRunning = false;
121: for (Thread thread : threads) {
122: if (thread.isAlive()) {
123: System.out.println("Thread Alive.");
124: threadsRunning = true;
125: break;
126: }
127: }
128:
129: try {
130: Thread.sleep(250);
131: } catch (InterruptedException e) {
132: break;
133: }
134: }
135: }
136:
137: System.out.println("All threads have stopped.");
138: System.out.println("Result Count: " + results.size());
139:
140: // analyze results
141:
142: if (!silentTests) {
143: System.out.println("[test] finished in: "
144: + (currentTimeMillis() - time)
145: + "ms (execution count: " + (threads.length * 8)
146: + " [mixed modes])");
147: System.out.print("[test] analyzing results ... ");
148: }
149:
150: Object last = null;
151: if (!results.isEmpty()) {
152: last = results.iterator().next();
153: if (last != null) {
154: for (Object o : results) {
155: if (o == null) {
156: throw new AssertionError(
157: "differing result in multi-thread test (first array has: "
158: + valueOf(last)
159: + "; second has: " + valueOf(o)
160: + ")");
161: } else if (!o.equals(last)) {
162: if (o.getClass().isArray()) {
163: Object[] a1 = (Object[]) o;
164: Object[] a2 = (Object[]) last;
165:
166: if (a1.length == a2.length) {
167: for (int i = 0; i < a1.length; i++) {
168: if (a1[i] == null && a2[i] == null) {
169: continue;
170: } else if (!a1[i].equals(a2[i])) {
171: throw new AssertionError(
172: "differing result in multi-thread test (first array has: "
173: + valueOf(last)
174: + "; second has: "
175: + valueOf(o)
176: + ")");
177: }
178: }
179: } else {
180: throw new AssertionError(
181: "differing result in multi-thread test: array sizes differ.");
182: }
183: } else {
184: throw new AssertionError(
185: "differing result in multi-thread test (last was: "
186: + valueOf(last)
187: + "; current is: "
188: + valueOf(o) + ")");
189: }
190: }
191: last = o;
192: }
193: }
194: }
195:
196: if (!silentTests) {
197: System.out.println("good!");
198: }
199: return last;
200: }
201:
202: protected static class TestRunner implements Runnable {
203: private Collection results;
204: private String expression;
205:
206: public TestRunner(Collection results, String expression) {
207: this .results = results;
208: this .expression = expression;
209: }
210:
211: public void run() {
212: try {
213: Object result = runSingleTest(expression);
214: results.add(result);
215: } catch (Throwable e) {
216: System.out
217: .println("thread terminating due to exception");
218: e.printStackTrace();
219: return;
220: }
221:
222: }
223: }
224:
225: protected static Object runSingleTest(final String ex) {
226: return _test(ex);
227: }
228:
229: protected static Object testCompiledSimple(String ex) {
230: return MVEL.executeExpression(MVEL.compileExpression(ex));
231: }
232:
233: protected static Object testCompiledSimple(String ex, Map map) {
234: return MVEL.executeExpression(MVEL.compileExpression(ex), map);
235: }
236:
237: protected static Object testCompiledSimple(String ex, Object base,
238: Map map) {
239: return MVEL.executeExpression(MVEL.compileExpression(ex), base,
240: map);
241: }
242:
243: protected static Object _test(String ex) {
244: ExpressionCompiler compiler = new ExpressionCompiler(ex);
245: StringAppender failErrors = new StringAppender();
246:
247: CompiledExpression compiled = compiler.compile();
248: Object first = null, second = null, third = null, fourth = null, fifth = null, sixth = null, seventh = null, eighth = null;
249:
250: System.out.println(DebugTools
251: .decompile((Serializable) compiled));
252:
253: if (!Boolean.getBoolean("mvel.disable.jit")) {
254:
255: setDefaultOptimizer("ASM");
256:
257: try {
258: first = executeExpression(compiled, new Base(),
259: createTestMap());
260: } catch (Exception e) {
261: failErrors.append("\nFIRST TEST: { " + ex
262: + " }: EXCEPTION REPORT: \n\n");
263:
264: CharArrayWriter writer = new CharArrayWriter();
265: e.printStackTrace(new PrintWriter(writer));
266:
267: failErrors.append(writer.toCharArray());
268: }
269:
270: try {
271: second = executeExpression(compiled, new Base(),
272: createTestMap());
273: } catch (Exception e) {
274: failErrors.append("\nSECOND TEST: { " + ex
275: + " }: EXCEPTION REPORT: \n\n");
276:
277: CharArrayWriter writer = new CharArrayWriter();
278: e.printStackTrace(new PrintWriter(writer));
279:
280: failErrors.append(writer.toCharArray());
281: }
282:
283: }
284:
285: try {
286: third = MVEL.eval(ex, new Base(), createTestMap());
287: } catch (Exception e) {
288: failErrors.append("\nTHIRD TEST: { " + ex
289: + " }: EXCEPTION REPORT: \n\n");
290:
291: CharArrayWriter writer = new CharArrayWriter();
292: e.printStackTrace(new PrintWriter(writer));
293:
294: failErrors.append(writer.toCharArray());
295: }
296:
297: if (first != null && !first.getClass().isArray()) {
298: if (!first.equals(second)) {
299: System.out.println(failErrors.toString());
300:
301: throw new AssertionError(
302: "Different result from test 1 and 2 (Compiled Re-Run / JIT) [first: "
303: + valueOf(first) + "; second: "
304: + valueOf(second) + "]");
305: }
306:
307: if (!first.equals(third)) {
308: if (failErrors != null)
309: System.out.println(failErrors.toString());
310:
311: throw new AssertionError(
312: "Different result from test 1 and 3 (Compiled to Interpreted) [first: "
313: + valueOf(first)
314: + " ("
315: + (first != null ? first.getClass()
316: .getName() : null)
317: + "); third: "
318: + valueOf(third)
319: + " ("
320: + (third != null ? third.getClass()
321: .getName() : "null") + ")]");
322: }
323: }
324:
325: setDefaultOptimizer("reflective");
326: Serializable compiled2 = compileExpression(ex);
327:
328: try {
329: fourth = executeExpression(compiled2, new Base(),
330: createTestMap());
331: } catch (Exception e) {
332: if (failErrors == null)
333: failErrors = new StringAppender();
334: failErrors.append("\nFOURTH TEST: { " + ex
335: + " }: EXCEPTION REPORT: \n\n");
336:
337: CharArrayWriter writer = new CharArrayWriter();
338: e.printStackTrace(new PrintWriter(writer));
339:
340: failErrors.append(writer.toCharArray());
341: }
342:
343: try {
344: fifth = executeExpression(compiled2, new Base(),
345: createTestMap());
346: } catch (Exception e) {
347: if (failErrors == null)
348: failErrors = new StringAppender();
349: failErrors.append("\nFIFTH TEST: { " + ex
350: + " }: EXCEPTION REPORT: \n\n");
351:
352: CharArrayWriter writer = new CharArrayWriter();
353: e.printStackTrace(new PrintWriter(writer));
354:
355: failErrors.append(writer.toCharArray());
356: }
357:
358: if (fourth != null && !fourth.getClass().isArray()) {
359: if (!fourth.equals(fifth)) {
360: throw new AssertionError(
361: "Different result from test 4 and 5 (Compiled Re-Run / Reflective) [first: "
362: + valueOf(first) + "; second: "
363: + valueOf(second) + "]");
364: }
365: }
366:
367: ParserContext ctx = new ParserContext();
368: ctx.setSourceFile("unittest");
369: ExpressionCompiler debuggingCompiler = new ExpressionCompiler(
370: ex);
371: debuggingCompiler.setDebugSymbols(true);
372:
373: CompiledExpression compiledD = debuggingCompiler.compile(ctx);
374:
375: try {
376: sixth = executeExpression(compiledD, new Base(),
377: createTestMap());
378: } catch (Exception e) {
379: if (failErrors == null)
380: failErrors = new StringAppender();
381: failErrors.append("\nSIXTH TEST: { " + ex
382: + " }: EXCEPTION REPORT: \n\n");
383:
384: CharArrayWriter writer = new CharArrayWriter();
385: e.printStackTrace(new PrintWriter(writer));
386:
387: failErrors.append(writer.toCharArray());
388: }
389:
390: if (sixth != null && !sixth.getClass().isArray()) {
391: if (!fifth.equals(sixth)) {
392: System.out.println("Payload 1 -- No Symbols: ");
393: System.out.println(decompile(compiled));
394: System.out.println();
395:
396: System.out.println("Payload 2 -- With Symbols: ");
397: System.out.println(decompile(compiledD));
398: System.out.println();
399:
400: throw new AssertionError(
401: "Different result from test 5 and 6 (Compiled to Compiled+DebuggingSymbols) [first: "
402: + valueOf(fifth)
403: + "; second: "
404: + valueOf(sixth) + "]");
405: }
406: }
407:
408: try {
409: seventh = executeExpression(compiledD, new Base(),
410: createTestMap());
411: } catch (Exception e) {
412: if (failErrors == null)
413: failErrors = new StringAppender();
414: failErrors.append("\nSEVENTH TEST: { " + ex
415: + " }: EXCEPTION REPORT: \n\n");
416:
417: CharArrayWriter writer = new CharArrayWriter();
418: e.printStackTrace(new PrintWriter(writer));
419:
420: failErrors.append(writer.toCharArray());
421: }
422:
423: if (seventh != null && !seventh.getClass().isArray()) {
424: if (!seventh.equals(sixth)) {
425: throw new AssertionError(
426: "Different result from test 4 and 5 (Compiled Re-Run / Reflective) [first: "
427: + valueOf(first) + "; second: "
428: + valueOf(second) + "]");
429: }
430: }
431:
432: try {
433: eighth = executeExpression(serializationTest(compiledD),
434: new Base(), new MapVariableResolverFactory(
435: createTestMap()));
436: } catch (Exception e) {
437: if (failErrors == null)
438: failErrors = new StringAppender();
439: failErrors.append("\nEIGHTH TEST (Serializability): { "
440: + ex + " }: EXCEPTION REPORT: \n\n");
441:
442: CharArrayWriter writer = new CharArrayWriter();
443: e.printStackTrace(new PrintWriter(writer));
444:
445: failErrors.append(writer.toCharArray());
446: }
447:
448: if (eighth != null && !eighth.getClass().isArray()) {
449: if (!eighth.equals(seventh)) {
450: throw new AssertionError(
451: "Different result from test 4 and 5 (Compiled Re-Run / Reflective) [first: "
452: + valueOf(first) + "; second: "
453: + valueOf(second) + "]");
454: }
455: }
456:
457: if (failErrors.length() > 0) {
458: System.out.println(decompile(compiledD));
459: throw new AssertionError("Detailed Failure Report:\n"
460: + failErrors.toString());
461: }
462:
463: return fourth;
464: }
465:
466: protected static Object serializationTest(Serializable s)
467: throws Exception {
468: File file = new File("./mvel_ser_test" + currentTimeMillis()
469: + Math.round(Math.random() * 1000) + ".tmp");
470: InputStream inputStream = null;
471: ObjectInputStream objectIn = null;
472: try {
473: file.createNewFile();
474: file.deleteOnExit();
475:
476: FileOutputStream fileStream = new FileOutputStream(file);
477: ObjectOutputStream objectOut = new ObjectOutputStream(
478: new BufferedOutputStream(fileStream));
479: objectOut.writeObject(s);
480:
481: objectOut.flush();
482: fileStream.flush();
483: fileStream.close();
484:
485: inputStream = new BufferedInputStream(new FileInputStream(
486: file));
487:
488: objectIn = new ObjectInputStream(inputStream);
489:
490: return objectIn.readObject();
491: } finally {
492: if (inputStream != null)
493: inputStream.close();
494: if (objectIn != null)
495: objectIn.close();
496: // file.delete();
497: }
498:
499: }
500:
501: public static class MiscTestClass {
502: int exec = 0;
503:
504: @SuppressWarnings({"unchecked","UnnecessaryBoxing"})
505: public List toList(Object object1, String string, int integer,
506: Map map, List list) {
507: exec++;
508: List l = new ArrayList();
509: l.add(object1);
510: l.add(string);
511: l.add(new Integer(integer));
512: l.add(map);
513: l.add(list);
514: return l;
515: }
516:
517: public int getExec() {
518: return exec;
519: }
520: }
521:
522: public static class Bean {
523: private Date myDate = new Date();
524:
525: public Date getToday() {
526: return new Date();
527: }
528:
529: public Date getNullDate() {
530: return null;
531: }
532:
533: public String getNullString() {
534: return null;
535: }
536:
537: public Date getMyDate() {
538: return myDate;
539: }
540:
541: public void setMyDate(Date myDate) {
542: this .myDate = myDate;
543: }
544: }
545:
546: public static class Context {
547: private final SimpleDateFormat dateFormat = new SimpleDateFormat(
548: "MM/dd/yy");
549: private Bean bean;
550:
551: public Bean getBean() {
552: return bean;
553: }
554:
555: public void setBean(Bean bean) {
556: this .bean = bean;
557: }
558:
559: public String formatDate(Date date) {
560: return date == null ? null : dateFormat.format(date);
561: }
562:
563: public String formatString(String str) {
564: return str == null ? "<NULL>" : str;
565: }
566: }
567:
568: public static class Person {
569: private String name;
570:
571: private int age;
572:
573: public Person() {
574:
575: }
576:
577: public Person(String name) {
578: this .name = name;
579: }
580:
581: public String getName() {
582: return name;
583: }
584:
585: public void setName(String name) {
586: this .name = name;
587: }
588:
589: public int getAge() {
590: return age;
591: }
592:
593: public void setAge(int age) {
594: this .age = age;
595: }
596:
597: }
598:
599: public static class Address {
600: private String street;
601:
602: public Address(String street) {
603: super ();
604: this .street = street;
605: }
606:
607: public String getStreet() {
608: return street;
609: }
610:
611: public void setStreet(String street) {
612: this .street = street;
613: }
614: }
615:
616: public static class Drools {
617: public void insert(Object obj) {
618: }
619: }
620:
621: public static class Model {
622: private List latestHeadlines;
623:
624: public List getLatestHeadlines() {
625: return latestHeadlines;
626: }
627:
628: public void setLatestHeadlines(List latestHeadlines) {
629: this .latestHeadlines = latestHeadlines;
630: }
631: }
632:
633: public static class Message {
634: public static final int HELLO = 0;
635: public static final int GOODBYE = 1;
636:
637: private List items = new ArrayList();
638:
639: private String message;
640:
641: private int status;
642:
643: public String getMessage() {
644: return this .message;
645: }
646:
647: public void setMessage(String message) {
648: this .message = message;
649: }
650:
651: public int getStatus() {
652: return this .status;
653: }
654:
655: public void setStatus(int status) {
656: this .status = status;
657: }
658:
659: public void addItem(Item item) {
660: this .items.add(item);
661: }
662:
663: public List getItems() {
664: return items;
665: }
666: }
667:
668: public static class Item {
669: private String name;
670:
671: public Item(String name) {
672: this .name = name;
673: }
674:
675: public String getName() {
676: return name;
677: }
678:
679: public void setName(String name) {
680: this .name = name;
681: }
682: }
683:
684: public class ClassA {
685: private Integer i;
686: private double d;
687: private String s;
688: public Date date;
689: private BigDecimal bigdec;
690: private BigInteger bigint;
691:
692: public Integer getI() {
693: return i;
694: }
695:
696: public void setI(Integer i) {
697: this .i = i;
698: }
699:
700: public double getD() {
701: return d;
702: }
703:
704: public void setD(double d) {
705: this .d = d;
706: }
707:
708: public String getS() {
709: return s;
710: }
711:
712: public void setS(String s) {
713: this .s = s;
714: }
715:
716: public Date getDate() {
717: return date;
718: }
719:
720: public void setDate(Date date) {
721: this .date = date;
722: }
723:
724: public BigDecimal getBigdec() {
725: return bigdec;
726: }
727:
728: public void setBigdec(BigDecimal bigdec) {
729: this .bigdec = bigdec;
730: }
731:
732: public BigInteger getBigint() {
733: return bigint;
734: }
735:
736: public void setBigint(BigInteger bigint) {
737: this .bigint = bigint;
738: }
739: }
740:
741: public class ClassB {
742: private Integer i;
743: private double d;
744: private String s;
745: public String date;
746: private BigDecimal bigdec;
747: private BigInteger bigint;
748:
749: public Integer getI() {
750: return i;
751: }
752:
753: public void setI(Integer i) {
754: this .i = i;
755: }
756:
757: public double getD() {
758: return d;
759: }
760:
761: public void setD(double d) {
762: this .d = d;
763: }
764:
765: public String getS() {
766: return s;
767: }
768:
769: public void setS(String s) {
770: this .s = s;
771: }
772:
773: public String getDate() {
774: return date;
775: }
776:
777: public void setDate(String date) {
778: this .date = date;
779: }
780:
781: public BigDecimal getBigdec() {
782: return bigdec;
783: }
784:
785: public void setBigdec(BigDecimal bigdec) {
786: this .bigdec = bigdec;
787: }
788:
789: public BigInteger getBigint() {
790: return bigint;
791: }
792:
793: public void setBigint(BigInteger bigint) {
794: this .bigint = bigint;
795: }
796: }
797:
798: public static class Order {
799: private int number = 20;
800:
801: public int getNumber() {
802: return number;
803: }
804:
805: public void setNumber(int number) {
806: this.number = number;
807: }
808: }
809: }
|