Source Code Cross Referenced for MethodHelper.java in  » Testing » testng » org » testng » internal » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » testng » org.testng.internal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.testng.internal;
002:
003:        import java.lang.reflect.InvocationTargetException;
004:        import java.lang.reflect.Method;
005:        import java.lang.reflect.Modifier;
006:        import java.util.ArrayList;
007:        import java.util.Collection;
008:        import java.util.HashMap;
009:        import java.util.Iterator;
010:        import java.util.List;
011:        import java.util.Map;
012:        import java.util.Set;
013:        import java.util.regex.Pattern;
014:
015:        import org.testng.IHookCallBack;
016:        import org.testng.ITestClass;
017:        import org.testng.ITestContext;
018:        import org.testng.ITestNGMethod;
019:        import org.testng.ITestResult;
020:        import org.testng.TestNGException;
021:        import org.testng.internal.annotations.AnnotationHelper;
022:        import org.testng.internal.annotations.IAnnotationFinder;
023:        import org.testng.internal.annotations.IConfiguration;
024:        import org.testng.internal.annotations.IExpectedExceptions;
025:        import org.testng.internal.annotations.ITest;
026:        import org.testng.internal.annotations.ITestOrConfiguration;
027:        import org.testng.internal.thread.IExecutor;
028:        import org.testng.internal.thread.IFutureResult;
029:        import org.testng.internal.thread.ThreadExecutionException;
030:        import org.testng.internal.thread.ThreadTimeoutException;
031:        import org.testng.internal.thread.ThreadUtil;
032:
033:        /**
034:         * Collection of helper methods to help sort and arrange methods.
035:         * 
036:         * @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
037:         * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
038:         */
039:        public class MethodHelper {
040:            //  static private boolean m_quiet = true;
041:
042:            // ///
043:            // public methods
044:            //
045:
046:            public static ITestNGMethod[] collectAndOrderMethods(
047:                    List<ITestNGMethod> methods, RunInfo runInfo,
048:                    IAnnotationFinder finder,
049:                    List<ITestNGMethod> outExcludedMethods) {
050:                return internalCollectAndOrderMethods(methods
051:                        .toArray(new ITestNGMethod[methods.size()]),
052:                        true /* forTest */, runInfo, finder,
053:                        false /* unique */, outExcludedMethods);
054:            }
055:
056:            /**
057:             * @param methods
058:             * @return All the methods that match the filtered groups. If a method belongs
059:             *         to an excluded group, it is automatically excluded.
060:             */
061:            public static ITestNGMethod[] collectAndOrderConfigurationMethods(
062:                    List<ITestNGMethod> methods, RunInfo runInfo,
063:                    IAnnotationFinder finder, boolean unique,
064:                    List<ITestNGMethod> outExcludedMethods) {
065:                return internalCollectAndOrderMethods(methods
066:                        .toArray(new ITestNGMethod[methods.size()]),
067:                        false /* forTests */, runInfo, finder, unique,
068:                        outExcludedMethods);
069:            }
070:
071:            private static ITestNGMethod[] internalCollectAndOrderMethods(
072:                    ITestNGMethod[] methods, boolean forTests, RunInfo runInfo,
073:                    IAnnotationFinder finder, boolean unique,
074:                    List<ITestNGMethod> outExcludedMethods) {
075:                List<ITestNGMethod> includedMethods = new ArrayList<ITestNGMethod>();
076:                collectMethodsByGroup(methods, forTests, includedMethods,
077:                        outExcludedMethods, runInfo, finder, unique);
078:                List<ITestNGMethod> vResult = sortMethods(forTests,
079:                        includedMethods, finder);
080:
081:                ITestNGMethod[] result = vResult
082:                        .toArray(new ITestNGMethod[vResult.size()]);
083:
084:                return result;
085:            }
086:
087:            /**
088:             * @return all the methods that belong to the group specified by the regular
089:             * expression groupRegExp.  methods[] is the list of all the methods we
090:             * are choosing from and method is the method that owns the dependsOnGroups
091:             * statement (only used if a group is missing to flag an error on that method).
092:             */
093:            public static ITestNGMethod[] findMethodsThatBelongToGroup(
094:                    ITestNGMethod method, ITestNGMethod[] methods,
095:                    String groupRegexp) {
096:                boolean foundGroup = false;
097:                List<ITestNGMethod> vResult = new ArrayList<ITestNGMethod>();
098:                for (ITestNGMethod tm : methods) {
099:                    String[] groups = tm.getGroups();
100:                    for (String group : groups) {
101:                        if (Pattern.matches(groupRegexp, group)) {
102:                            vResult.add(tm);
103:                            foundGroup = true;
104:                        }
105:                    }
106:                }
107:
108:                if (!foundGroup) {
109:                    method.setMissingGroup(groupRegexp);
110:                }
111:
112:                ITestNGMethod[] result = vResult
113:                        .toArray(new ITestNGMethod[vResult.size()]);
114:                return result;
115:            }
116:
117:            public static ITestNGMethod[] findMethodsNamed(String mainMethod,
118:                    ITestNGMethod[] methods, String[] regexps) {
119:                List<ITestNGMethod> vResult = new ArrayList<ITestNGMethod>();
120:                String currentRegexp = null;
121:                for (String fullyQualifiedRegexp : regexps) {
122:                    boolean foundAtLeastAMethod = false;
123:
124:                    if (null != fullyQualifiedRegexp) {
125:                        String regexp = escapeRegexp(fullyQualifiedRegexp);
126:                        currentRegexp = regexp;
127:                        boolean usePackage = regexp.indexOf(".") != -1;
128:
129:                        for (ITestNGMethod method : methods) {
130:                            Method this Method = method.getMethod();
131:                            String this MethodName = this Method.getName();
132:                            String methodName = usePackage ? calculateMethodCanonicalName(this Method)
133:                                    : this MethodName;
134:                            //            ppp("COMPARING\n" + regexp + "\n" + methodName);
135:                            if (Pattern.matches(regexp, methodName)) {
136:                                vResult.add(method);
137:                                foundAtLeastAMethod = true;
138:                            }
139:                        }
140:                    }
141:
142:                    if (!foundAtLeastAMethod) {
143:                        throw new TestNGException(mainMethod
144:                                + "() is depending on nonexistent method "
145:                                + currentRegexp);
146:                    }
147:                }
148:
149:                ITestNGMethod[] result = vResult
150:                        .toArray(new ITestNGMethod[vResult.size()]);
151:
152:                return result;
153:            }
154:
155:            /**
156:             * Escapes $ in regexps as it is not meant for end-line matching, but inner class matches.
157:             * Impl.is weird as the String methods are not available in 1.4
158:             */
159:            private static String escapeRegexp(String regex) {
160:                if (regex.indexOf('$') == -1)
161:                    return regex;
162:                String[] fragments = regex.split("\\$");
163:                StringBuffer result = new StringBuffer();
164:                for (int i = 0; i < fragments.length - 1; i++) {
165:                    result.append(fragments[i]).append("\\$");
166:                }
167:                result.append(fragments[fragments.length - 1]);
168:                if (regex.endsWith("$"))
169:                    result.append("\\$");
170:
171:                return result.toString();
172:            }
173:
174:            /**
175:             * Read the expected exceptions, if any (need to handle both the old and new
176:             * syntax
177:             */
178:            public static Class<?>[] findExpectedExceptions(
179:                    IAnnotationFinder finder, Method method) {
180:                Class<?>[] result = {};
181:                IExpectedExceptions expectedExceptions = (IExpectedExceptions) finder
182:                        .findAnnotation(method, IExpectedExceptions.class);
183:                // Old syntax
184:                if (expectedExceptions != null) {
185:                    result = expectedExceptions.getValue();
186:                } else {
187:                    // New syntax
188:                    ITest testAnnotation = (ITest) finder.findAnnotation(
189:                            method, ITest.class);
190:                    if (testAnnotation != null) {
191:                        Class<?>[] ee = testAnnotation.getExpectedExceptions();
192:                        if (testAnnotation != null && ee.length > 0) {
193:                            result = ee;
194:                        }
195:                    }
196:                }
197:
198:                return result;
199:            }
200:
201:            //
202:            // End of public methods
203:            // ///
204:
205:            public static boolean isEnabled(Class<?> objectClass,
206:                    IAnnotationFinder finder) {
207:                ITest testClassAnnotation = AnnotationHelper.findTest(finder,
208:                        objectClass);
209:
210:                return isEnabled(testClassAnnotation);
211:            }
212:
213:            public static boolean isEnabled(Method m, IAnnotationFinder finder) {
214:                ITest annotation = AnnotationHelper.findTest(finder, m);
215:
216:                // If no method annotation, look for one on the class
217:                if (null == annotation) {
218:                    annotation = AnnotationHelper.findTest(finder, m
219:                            .getDeclaringClass());
220:                }
221:
222:                return isEnabled(annotation);
223:            }
224:
225:            public static boolean isEnabled(ITestOrConfiguration test) {
226:                return null == test || (null != test && test.getEnabled());
227:            }
228:
229:            public static ITestNGMethod[] findMethodsThatBelongToGroup(
230:                    ITestNGMethod method, List<ITestNGMethod> methods,
231:                    String groupRegexp) {
232:                ITestNGMethod[] allMethods = methods
233:                        .toArray(new ITestNGMethod[methods.size()]);
234:                return findMethodsThatBelongToGroup(method, allMethods,
235:                        groupRegexp);
236:            }
237:
238:            /**
239:             * @return The transitive closure of all the groups/methods included.
240:             */
241:            public static void findGroupTransitiveClosure(
242:                    XmlMethodSelector xms, List<ITestNGMethod> includedMethods,
243:                    List<ITestNGMethod> allMethods, String[] includedGroups,
244:                    Set<String> outGroups, Set<ITestNGMethod> outMethods) {
245:                Map<ITestNGMethod, ITestNGMethod> runningMethods = new HashMap<ITestNGMethod, ITestNGMethod>();
246:                for (ITestNGMethod m : includedMethods) {
247:                    runningMethods.put(m, m);
248:                }
249:
250:                Map<String, String> runningGroups = new HashMap<String, String>();
251:                for (String this Group : includedGroups) {
252:                    runningGroups.put(this Group, this Group);
253:                }
254:
255:                boolean keepGoing = true;
256:
257:                Map<ITestNGMethod, ITestNGMethod> newMethods = new HashMap<ITestNGMethod, ITestNGMethod>();
258:                while (keepGoing) {
259:                    for (ITestNGMethod m : includedMethods) {
260:
261:                        //
262:                        // Depends on groups?
263:                        // Adds all included methods to runningMethods
264:                        //
265:                        String[] ig = m.getGroupsDependedUpon();
266:                        for (String g : ig) {
267:                            if (!runningGroups.containsKey(g)) {
268:                                // Found a new included group, add all the methods it contains to
269:                                // our outMethod closure
270:                                runningGroups.put(g, g);
271:                                ITestNGMethod[] im = findMethodsThatBelongToGroup(
272:                                        m, allMethods, g);
273:                                for (ITestNGMethod this Method : im) {
274:                                    if (!runningMethods.containsKey(this Method)) {
275:                                        runningMethods.put(this Method,
276:                                                this Method);
277:                                        newMethods.put(this Method, this Method);
278:                                    }
279:                                }
280:                            }
281:                        } // groups
282:
283:                        //
284:                        // Depends on methods?
285:                        // Adds all depended methods to runningMethods
286:                        //
287:                        String[] mdu = m.getMethodsDependedUpon();
288:                        for (String tm : mdu) {
289:                            ITestNGMethod this Method = findMethodNamed(tm,
290:                                    allMethods);
291:                            if (this Method != null
292:                                    && !runningMethods.containsKey(this Method)) {
293:                                runningMethods.put(this Method, this Method);
294:                                newMethods.put(this Method, this Method);
295:                            }
296:                        }
297:
298:                    } // methods
299:
300:                    //
301:                    // Only keep going if new methods have been added
302:                    //
303:                    keepGoing = newMethods.size() > 0;
304:                    includedMethods = new ArrayList<ITestNGMethod>();
305:                    includedMethods.addAll(newMethods.keySet());
306:                    newMethods = new HashMap<ITestNGMethod, ITestNGMethod>();
307:                } // while keepGoing
308:
309:                outMethods.addAll(runningMethods.keySet());
310:                outGroups.addAll(runningGroups.keySet());
311:            }
312:
313:            /**
314:             * Extracts the map of groups and their corresponding methods from the <code>classes</code>.
315:             */
316:            public static Map<String, List<ITestNGMethod>> findGroupsMethods(
317:                    Collection<ITestClass> classes, boolean before) {
318:                Map<String, List<ITestNGMethod>> result = new HashMap<String, List<ITestNGMethod>>();
319:                for (ITestClass cls : classes) {
320:                    ITestNGMethod[] methods = before ? cls
321:                            .getBeforeGroupsMethods() : cls
322:                            .getAfterGroupsMethods();
323:                    for (ITestNGMethod method : methods) {
324:                        for (String group : before ? method.getBeforeGroups()
325:                                : method.getAfterGroups()) {
326:                            List<ITestNGMethod> methodList = result.get(group);
327:                            if (methodList == null) {
328:                                methodList = new ArrayList<ITestNGMethod>();
329:                                result.put(group, methodList);
330:                            }
331:                            // NOTE(cbeust, 2007/01/23)
332:                            // BeforeGroups/AfterGroups methods should only be invoked once.
333:                            // I should probably use a map instead of a list for a contains(), but 
334:                            // this list should usually be fairly short
335:                            if (!methodList.contains(method)) {
336:                                methodList.add(method);
337:                            }
338:                        }
339:                    }
340:                }
341:
342:                return result;
343:            }
344:
345:            /**
346:             * Extracts the unique list of <code>ITestNGMethod</code>s.
347:             */
348:            public static List<ITestNGMethod> uniqueMethodList(
349:                    Collection<List<ITestNGMethod>> methods) {
350:                Map<ITestNGMethod, ITestNGMethod> uniq = new HashMap<ITestNGMethod, ITestNGMethod>();
351:
352:                for (List<ITestNGMethod> l : methods) {
353:                    for (ITestNGMethod m : l) {
354:                        uniq.put(m, m);
355:                    }
356:                }
357:
358:                List<ITestNGMethod> result = new ArrayList<ITestNGMethod>();
359:                result.addAll(uniq.values());
360:
361:                return result;
362:            }
363:
364:            private static ITestNGMethod findMethodNamed(String tm,
365:                    List<ITestNGMethod> allMethods) {
366:                for (ITestNGMethod m : allMethods) {
367:                    // TODO(cbeust):  account for package
368:                    String methodName = m.getMethod().getDeclaringClass()
369:                            .getName()
370:                            + "." + m.getMethodName();
371:                    if (methodName.equals(tm))
372:                        return m;
373:                }
374:
375:                return null;
376:            }
377:
378:            private static boolean includeMethod(
379:                    ITestOrConfiguration annotation, RunInfo runInfo,
380:                    ITestNGMethod tm, boolean forTests, boolean unique,
381:                    List<ITestNGMethod> outIncludedMethods) {
382:                boolean result = false;
383:
384:                if (isEnabled(annotation)) {
385:                    if (runInfo.includeMethod(tm, forTests)) {
386:                        if (unique) {
387:                            if (!isMethodAlreadyPresent(outIncludedMethods, tm)) {
388:                                result = true;
389:                            }
390:                        } else {
391:                            result = true;
392:                        }
393:                    }
394:                }
395:
396:                return result;
397:            }
398:
399:            /**
400:             * Collect all the methods that belong to the included groups and exclude all
401:             * the methods that belong to an excluded group.
402:             */
403:            private static void collectMethodsByGroup(ITestNGMethod[] methods,
404:                    boolean forTests, List<ITestNGMethod> outIncludedMethods,
405:                    List<ITestNGMethod> outExcludedMethods, RunInfo runInfo,
406:                    IAnnotationFinder finder, boolean unique) {
407:                for (ITestNGMethod tm : methods) {
408:                    boolean in = false;
409:                    Method m = tm.getMethod();
410:                    //
411:                    // @Test method
412:                    //
413:                    if (forTests) {
414:                        in = includeMethod(
415:                                AnnotationHelper.findTest(finder, m), runInfo,
416:                                tm, forTests, unique, outIncludedMethods);
417:                    }
418:
419:                    //
420:                    // @Configuration method
421:                    //
422:                    else {
423:                        IConfiguration annotation = AnnotationHelper
424:                                .findConfiguration(finder, m);
425:                        if (annotation.getAlwaysRun()) {
426:                            in = true;
427:                        } else {
428:                            in = includeMethod(AnnotationHelper.findTest(
429:                                    finder, m), runInfo, tm, forTests, unique,
430:                                    outIncludedMethods);
431:                        }
432:                    }
433:                    if (in) {
434:                        outIncludedMethods.add(tm);
435:                    } else {
436:                        outExcludedMethods.add(tm);
437:                    }
438:                }
439:            }
440:
441:            /**
442:             * @param result
443:             * @param tm
444:             * @return true if a method by a similar name (and same hierarchy) already
445:             *         exists
446:             */
447:            private static boolean isMethodAlreadyPresent(
448:                    List<ITestNGMethod> result, ITestNGMethod tm) {
449:                for (ITestNGMethod m : result) {
450:                    Method jm1 = m.getMethod();
451:                    Method jm2 = tm.getMethod();
452:                    if (jm1.getName().equals(jm2.getName())) {
453:                        // Same names, see if they are in the same hierarchy
454:                        Class<?> c1 = jm1.getDeclaringClass();
455:                        Class<?> c2 = jm2.getDeclaringClass();
456:                        if (c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1)) {
457:                            return true;
458:                        }
459:                    }
460:                }
461:
462:                return false;
463:            }
464:
465:            static public Graph<ITestNGMethod> topologicalSort(
466:                    ITestNGMethod[] methods,
467:                    List<ITestNGMethod> sequentialList,
468:                    List<ITestNGMethod> parallelList) {
469:                Graph<ITestNGMethod> result = new Graph<ITestNGMethod>();
470:
471:                if (methods.length == 0)
472:                    return result;
473:
474:                //
475:                // Create the graph
476:                //
477:                for (ITestNGMethod m : methods) {
478:                    result.addNode(m);
479:
480:                    Map<ITestNGMethod, ITestNGMethod> predecessors = new HashMap<ITestNGMethod, ITestNGMethod>();
481:
482:                    String[] methodsDependedUpon = m.getMethodsDependedUpon();
483:                    String[] groupsDependedUpon = m.getGroupsDependedUpon();
484:                    if (methodsDependedUpon.length > 0) {
485:                        String methodName = calculateMethodCanonicalName(m);
486:                        ITestNGMethod[] methodsNamed = MethodHelper
487:                                .findMethodsNamed(methodName, methods,
488:                                        methodsDependedUpon);
489:                        for (ITestNGMethod pred : methodsNamed) {
490:                            predecessors.put(pred, pred);
491:                        }
492:                    }
493:                    if (groupsDependedUpon.length > 0) {
494:                        for (String group : groupsDependedUpon) {
495:                            ITestNGMethod[] methodsThatBelongToGroup = MethodHelper
496:                                    .findMethodsThatBelongToGroup(m, methods,
497:                                            group);
498:                            for (ITestNGMethod pred : methodsThatBelongToGroup) {
499:                                predecessors.put(pred, pred);
500:                            }
501:                        }
502:                    }
503:
504:                    for (ITestNGMethod predecessor : predecessors.values()) {
505:                        // ppp("METHOD:" + m + " ADDED PREDECESSOR:" + predecessor);
506:                        result.addPredecessor(m, predecessor);
507:                    }
508:                }
509:
510:                result.topologicalSort();
511:                sequentialList.addAll(result.getStrictlySortedNodes());
512:                parallelList.addAll(result.getIndependentNodes());
513:
514:                return result;
515:            }
516:
517:            public static String calculateMethodCanonicalName(ITestNGMethod m) {
518:                return calculateMethodCanonicalName(m.getMethod());
519:            }
520:
521:            private static String calculateMethodCanonicalName(Method m) {
522:                String packageName = m.getDeclaringClass().getName() + "."
523:                        + m.getName();
524:
525:                // Try to find the method on this class or parents
526:                Class<?> cls = m.getDeclaringClass();
527:                while (cls != Object.class) {
528:                    try {
529:                        if (cls.getDeclaredMethod(m.getName(), m
530:                                .getParameterTypes()) != null) {
531:                            packageName = cls.getName();
532:                            break;
533:                        }
534:                    } catch (Exception e) {
535:                        // ignore
536:                    }
537:                    cls = cls.getSuperclass();
538:                }
539:
540:                String result = packageName + "." + m.getName();
541:                return result;
542:            }
543:
544:            private static List<ITestNGMethod> sortMethods(boolean forTests,
545:                    List<ITestNGMethod> allMethods, IAnnotationFinder finder) {
546:                List<ITestNGMethod> sl = new ArrayList<ITestNGMethod>();
547:                List<ITestNGMethod> pl = new ArrayList<ITestNGMethod>();
548:                ITestNGMethod[] allMethodsArray = allMethods
549:                        .toArray(new ITestNGMethod[allMethods.size()]);
550:
551:                // Fix the method inheritance if these are @Configuration methods to make
552:                // sure base classes are invoked before child classes if 'before' and the
553:                // other way around if they are 'after'
554:                if (!forTests && allMethodsArray.length > 0) {
555:                    ITestNGMethod m = allMethodsArray[0];
556:                    boolean before = m.isBeforeClassConfiguration()
557:                            || m.isBeforeMethodConfiguration()
558:                            || m.isBeforeSuiteConfiguration()
559:                            || m.isBeforeTestConfiguration();
560:                    MethodInheritance.fixMethodInheritance(allMethodsArray,
561:                            before);
562:                }
563:
564:                topologicalSort(allMethodsArray, sl, pl);
565:
566:                List<ITestNGMethod> result = new ArrayList<ITestNGMethod>();
567:                result.addAll(sl);
568:                result.addAll(pl);
569:                return result;
570:            }
571:
572:            public static void ppp(String s) {
573:                System.out.println("[MethodHelper] " + s);
574:            }
575:
576:            /**
577:             * @param method
578:             * @param allTestMethods
579:             * @return A sorted array containing all the methods 'method' depends on
580:             */
581:            public static List<ITestNGMethod> getMethodsDependedUpon(
582:                    ITestNGMethod method, ITestNGMethod[] methods) {
583:                List<ITestNGMethod> parallelList = new ArrayList<ITestNGMethod>();
584:                List<ITestNGMethod> sequentialList = new ArrayList<ITestNGMethod>();
585:                Graph<ITestNGMethod> g = topologicalSort(methods,
586:                        sequentialList, parallelList);
587:
588:                List<ITestNGMethod> result = g.findPredecessors(method);
589:                return result;
590:            }
591:
592:            public static Object invokeMethod(Method this Method,
593:                    Object instance, Object[] parameters)
594:                    throws InvocationTargetException, IllegalAccessException {
595:                Object result = null;
596:                boolean isPublic = Modifier.isPublic(this Method.getModifiers());
597:
598:                try {
599:                    if (!isPublic) {
600:                        this Method.setAccessible(true);
601:                    }
602:                    result = this Method.invoke(instance, parameters);
603:                } finally {
604:                    if (!isPublic) {
605:                        this Method.setAccessible(false);
606:                    }
607:                }
608:
609:                return result;
610:            }
611:
612:            public static Iterator<Object[]> createArrayIterator(
613:                    final Object[][] objects) {
614:                ArrayIterator result = new ArrayIterator(objects);
615:                return result;
616:            }
617:
618:            public static Iterator<Object[]> invokeDataProvider(
619:                    Object instance, Method dataProvider, ITestNGMethod method,
620:                    ITestContext testContext) {
621:                Iterator<Object[]> result = null;
622:                Method testMethod = method.getMethod();
623:
624:                // If it returns an Object[][], convert it to an Iterable<Object[]>
625:                try {
626:                    List<Object> lParameters = new ArrayList<Object>();
627:
628:                    // Go through all the parameters declared on this Data Provider and
629:                    // make sure we have at most one Method and one ITestContext.
630:                    // Anything else is an error
631:                    Class<?>[] parameterTypes = dataProvider
632:                            .getParameterTypes();
633:                    if (parameterTypes.length > 2) {
634:                        throw new TestNGException("DataProvider "
635:                                + dataProvider
636:                                + " cannot have more than two parameters");
637:                    }
638:
639:                    for (Class<?> cls : parameterTypes) {
640:                        if (cls.equals(Method.class)) {
641:                            lParameters.add(testMethod);
642:                        } else if (cls.equals(ITestContext.class)) {
643:                            lParameters.add(testContext);
644:                        }
645:                    }
646:                    Object[] parameters = lParameters
647:                            .toArray(new Object[lParameters.size()]);
648:
649:                    Class<?> returnType = dataProvider.getReturnType();
650:                    if (Object[][].class.isAssignableFrom(returnType)) {
651:                        Object[][] oResult = (Object[][]) MethodHelper
652:                                .invokeMethod(dataProvider, instance,
653:                                        parameters);
654:                        method.setParameterInvocationCount(oResult.length);
655:                        result = MethodHelper.createArrayIterator(oResult);
656:                    } else if (Iterator.class.isAssignableFrom(returnType)) {
657:                        // Already an Iterable<Object[]>, assign it directly
658:                        result = (Iterator<Object[]>) MethodHelper
659:                                .invokeMethod(dataProvider, instance,
660:                                        parameters);
661:                    } else {
662:                        throw new TestNGException(
663:                                "Data Provider "
664:                                        + dataProvider
665:                                        + " must return"
666:                                        + " either Object[][] or Iterator<Object>[], not "
667:                                        + returnType);
668:                    }
669:                } catch (InvocationTargetException e) {
670:                    throw new TestNGException(e);
671:                } catch (IllegalAccessException e) {
672:                    throw new TestNGException(e);
673:                }
674:
675:                return result;
676:            }
677:
678:            public static String calculateMethodCanonicalName(
679:                    Class<?> methodClass, String methodName) {
680:                Set<Method> methods = ClassHelper
681:                        .getAvailableMethods(methodClass); // TESTNG-139
682:                Method result = null;
683:                for (Method m : methods) {
684:                    if (methodName.equals(m.getName())) {
685:                        result = m;
686:                        break;
687:                    }
688:                }
689:
690:                return result != null ? calculateMethodCanonicalName(result)
691:                        : null;
692:            }
693:
694:            /**
695:             * Invokes the <code>run</code> method of the <code>IHookable</code>.
696:             * 
697:             * @param instance the instance to invoke the method in
698:             * @param parameters the parameters to be passed to <code>IHookCallBack</code>
699:             * @param testClass the test class
700:             * @param thisMethod the method to be invoked through the <code>IHookCallBack</code>
701:             * @param testResult the current <code>ITestResult</code> passed to <code>IHookable.run</code>
702:             * @throws NoSuchMethodException
703:             * @throws IllegalAccessException
704:             * @throws InvocationTargetException
705:             * @throws Throwable thrown if the reflective call to <tt>thisMethod</code> results in an exception
706:             */
707:            public static void invokeHookable(final Object instance,
708:                    final Object[] parameters, ITestClass testClass,
709:                    final Method this Method, TestResult testResult)
710:                    throws NoSuchMethodException, IllegalAccessException,
711:                    InvocationTargetException, Throwable {
712:                Method runMethod = testClass.getRealClass().getMethod("run",
713:                        new Class[] { IHookCallBack.class, ITestResult.class });
714:                final Throwable[] error = new Throwable[1];
715:
716:                IHookCallBack callback = new IHookCallBack() {
717:                    public void runTestMethod(ITestResult tr) {
718:                        try {
719:                            invokeMethod(this Method, instance, parameters);
720:                        } catch (Throwable t) {
721:                            error[0] = t;
722:                            tr.setThrowable(t); // make Throwable available to IHookable
723:                        }
724:                    }
725:                };
726:                runMethod.invoke(instance,
727:                        new Object[] { callback, testResult });
728:                if (error[0] != null) {
729:                    throw error[0];
730:                }
731:            }
732:
733:            /**
734:             * Invokes a method on a separate thread in order to allow us to timeout the invocation.
735:             * It uses as implementation an <code>Executor</code> and a <code>CountDownLatch</code>.
736:             * @param tm the 
737:             * @param instance
738:             * @param parameterValues
739:             * @param testResult
740:             * @throws InterruptedException
741:             * @throws ThreadExecutionException
742:             */
743:            public static void invokeWithTimeout(ITestNGMethod tm,
744:                    Object instance, Object[] parameterValues,
745:                    ITestResult testResult) throws InterruptedException,
746:                    ThreadExecutionException {
747:                //    ICountDown done= ThreadUtil.createCountDown(1);
748:                //    IThreadFactory factory= ThreadUtil.createFactory();
749:                IExecutor exec = ThreadUtil.createExecutor(1, tm.getMethod()
750:                        .getName());
751:
752:                InvokeMethodRunnable imr = new InvokeMethodRunnable(tm,
753:                        instance, parameterValues);
754:                IFutureResult future = exec.submitRunnable(imr);
755:                exec.shutdown();
756:                boolean finished = exec.awaitTermination(tm.getTimeOut());
757:
758:                if (!finished) {
759:                    exec.stopNow();
760:                    testResult.setThrowable(new ThreadTimeoutException(
761:                            "Method " + tm.getMethod()
762:                                    + " didn't finish within the time-out "
763:                                    + tm.getTimeOut()));
764:                    testResult.setStatus(ITestResult.FAILURE);
765:                } else {
766:                    Utils.log("Invoker " + Thread.currentThread().hashCode(),
767:                            3, "Method " + tm.getMethod()
768:                                    + " completed within the time-out "
769:                                    + tm.getTimeOut());
770:
771:                    // We don't need the result from the future but invoking get() on it
772:                    // will trigger the exception that was thrown, if any
773:                    future.get();
774:                    //      done.await();
775:
776:                    testResult.setStatus(ITestResult.SUCCESS); // if no exception till here than SUCCESS
777:                }
778:            }
779:        }
780:
781:        // ///
782:
783:        class ArrayIterator implements  Iterator {
784:            private Object[][] m_objects;
785:
786:            private int m_count;
787:
788:            public ArrayIterator(Object[][] objects) {
789:                m_objects = objects;
790:                m_count = 0;
791:            }
792:
793:            public boolean hasNext() {
794:                return m_count < m_objects.length;
795:            }
796:
797:            public Object next() {
798:                return m_objects[m_count++];
799:            }
800:
801:            public void remove() {
802:                // TODO Auto-generated method stub
803:
804:            }
805:
806:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.