• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.testng.xml;
2 
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Properties;
8 import java.util.UUID;
9 
10 import org.testng.TestNG;
11 import org.testng.TestNGException;
12 import org.testng.collections.Lists;
13 import org.testng.collections.Maps;
14 import org.testng.reporters.XMLStringBuffer;
15 import org.testng.xml.dom.ParentSetter;
16 
17 /**
18  * This class describes the tag <test>  in testng.xml.
19  *
20  * @author <a href = "mailto:cedric&#64;beust.com">Cedric Beust</a>
21  * @author <a href = 'mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
22  */
23 public class XmlTest implements Serializable, Cloneable {
24   private static final long serialVersionUID = 6533504325942417606L;
25 
26   public static final int DEFAULT_TIMEOUT_MS = Integer.MAX_VALUE;
27 
28   private XmlSuite m_suite;
29   private String m_name;
30   private Integer m_verbose = XmlSuite.DEFAULT_VERBOSE;
31   private Boolean m_isJUnit = XmlSuite.DEFAULT_JUNIT;
32   private int m_threadCount= -1;
33 
34   private List<XmlClass> m_xmlClasses = Lists.newArrayList();
35 
36   private List<String> m_includedGroups = Lists.newArrayList();
37   private List<String> m_excludedGroups = Lists.newArrayList();
38 
39   private Map<String, List<String>> m_metaGroups = Maps.newHashMap();
40   private Map<String, String> m_parameters = Maps.newHashMap();
41   private XmlSuite.ParallelMode m_parallel;
42 
43   private List<XmlMethodSelector> m_methodSelectors = Lists.newArrayList();
44   // test level packages
45   private List<XmlPackage> m_xmlPackages = Lists.newArrayList();
46 
47   private String m_timeOut;
48   private Boolean m_skipFailedInvocationCounts = XmlSuite.DEFAULT_SKIP_FAILED_INVOCATION_COUNTS;
49   private Map<String, List<Integer>> m_failedInvocationNumbers = null; // lazily initialized
50 
51   private String m_preserveOrder = XmlSuite.DEFAULT_PRESERVE_ORDER;
52 
53   private int m_index;
54 
55   private Boolean m_groupByInstances;
56 
57   private Boolean m_allowReturnValues = null;
58 
59   private Map<String, String> m_xmlDependencyGroups = Maps.newHashMap();
60 
61   /**
62    * Constructs a <code>XmlTest</code> and adds it to suite's list of tests.
63    *
64    * @param suite the parent suite.
65    * @param index the index of this test tag in testng.xml
66    */
XmlTest(XmlSuite suite, int index)67   public XmlTest(XmlSuite suite, int index) {
68     init(suite, index);
69   }
70 
XmlTest(XmlSuite suite)71   public XmlTest(XmlSuite suite) {
72     init(suite, 0);
73   }
74 
init(XmlSuite suite, int index)75   private void init(XmlSuite suite, int index) {
76     m_suite = suite;
77     m_suite.getTests().add(this);
78     m_index = index;
79     //no two tests in the same suite should have the same name.
80     //so, make the default test name unique
81     m_name = TestNG.DEFAULT_COMMAND_LINE_TEST_NAME
82       + " " + UUID.randomUUID().toString();
83   }
84 
85   // For YAML
XmlTest()86   public XmlTest() {
87   }
88 
setXmlPackages(List<XmlPackage> packages)89   public void setXmlPackages(List<XmlPackage> packages) {
90     m_xmlPackages = Lists.newArrayList(packages);
91   }
92 
getXmlPackages()93   public List<XmlPackage> getXmlPackages() {
94     return m_xmlPackages;
95   }
96 
97   // For YAML
getPackages()98   public List<XmlPackage> getPackages() {
99     return getXmlPackages();
100   }
101 
102   // For YAML
setPackages(List<XmlPackage> p)103   public void setPackages(List<XmlPackage> p) {
104     setXmlPackages(p);
105   }
106 
getMethodSelectors()107   public List<XmlMethodSelector> getMethodSelectors() {
108     return m_methodSelectors;
109   }
110 
setMethodSelectors(List<XmlMethodSelector> methodSelectors)111   public void setMethodSelectors(List<XmlMethodSelector> methodSelectors) {
112     m_methodSelectors = Lists.newArrayList(methodSelectors);
113   }
114 
115   /**
116    * Returns the suite this test is part of.
117    * @return the suite this test is part of.
118    */
getSuite()119   public XmlSuite getSuite() {
120     return m_suite;
121   }
122 
123   /**
124    * @return the includedGroups.
125    * Note: do not modify the returned value, use {@link #addIncludedGroup(String)}.
126    */
getIncludedGroups()127   public List<String> getIncludedGroups() {
128     List<String> result;
129     if (m_xmlGroups != null) {
130       result = m_xmlGroups.getRun().getIncludes();
131       result.addAll(m_suite.getIncludedGroups());
132     } else {
133       // deprecated
134       result = Lists.newArrayList(m_includedGroups);
135       result.addAll(m_suite.getIncludedGroups());
136     }
137     return result;
138   }
139 
140   /**
141    * Sets the XML Classes.
142    * @param classes The classes to set.
143    * @deprecated use setXmlClasses
144    */
145   @Deprecated
setClassNames(List<XmlClass> classes)146   public void setClassNames(List<XmlClass> classes) {
147     m_xmlClasses = classes;
148   }
149 
150   /**
151    * @return Returns the classes.
152    */
getXmlClasses()153   public List<XmlClass> getXmlClasses() {
154     return m_xmlClasses;
155   }
156 
157   // For YAML
getClasses()158   public List<XmlClass> getClasses() {
159     return getXmlClasses();
160   }
161 
162   // For YAML
setClasses(List<XmlClass> c)163   public void setClasses(List<XmlClass> c) {
164     setXmlClasses(c);
165   }
166 
167   /**
168    * Sets the XML Classes.
169    * @param classes The classes to set.
170    */
setXmlClasses(List<XmlClass> classes)171   public void setXmlClasses(List<XmlClass> classes) {
172     m_xmlClasses = classes;
173   }
174 
175   /**
176    * @return Returns the name.
177    */
getName()178   public String getName() {
179     return m_name;
180   }
181 
182   /**
183    * @param name The name to set.
184    */
setName(String name)185   public void setName(String name) {
186     m_name = name;
187   }
188 
189   /**
190    * @param v
191    */
setVerbose(int v)192   public void setVerbose(int v) {
193     m_verbose = v;
194   }
195 
getThreadCount()196   public int getThreadCount() {
197     return m_threadCount > 0 ? m_threadCount : getSuite().getThreadCount();
198   }
199 
setThreadCount(int threadCount)200   public void setThreadCount(int threadCount) {
201     m_threadCount = threadCount;
202   }
203 
204   /**
205    * @param g
206    */
setIncludedGroups(List<String> g)207   public void setIncludedGroups(List<String> g) {
208     m_includedGroups = g;
209   }
210 
211   /**
212    * @param g The excludedGrousps to set.
213    */
setExcludedGroups(List<String> g)214   public void setExcludedGroups(List<String> g) {
215     m_excludedGroups = g;
216   }
217 
218   /**
219    * @return Returns the excludedGroups.
220    * Note: do not modify the returned value, use {@link #addExcludedGroup(String)}.
221    */
getExcludedGroups()222   public List<String> getExcludedGroups() {
223     List<String> result = new ArrayList(m_excludedGroups);
224     result.addAll(m_suite.getExcludedGroups());
225     return result;
226   }
227 
addIncludedGroup(String g)228   public void addIncludedGroup(String g) {
229     m_includedGroups.add(g);
230   }
231 
addExcludedGroup(String g)232   public void addExcludedGroup(String g) {
233     m_excludedGroups.add(g);
234   }
235 
236   /**
237    * @return Returns the verbose.
238    */
getVerbose()239   public int getVerbose() {
240     Integer result = m_verbose;
241     if (null == result || XmlSuite.DEFAULT_VERBOSE.equals(m_verbose)) {
242       result = m_suite.getVerbose();
243     }
244 
245     if (null != result) {
246       return result;
247     } else {
248       return 1;
249     }
250   }
251 
getGroupByInstances()252   public boolean getGroupByInstances() {
253     Boolean result = m_groupByInstances;
254     if (result == null || XmlSuite.DEFAULT_GROUP_BY_INSTANCES.equals(m_groupByInstances)) {
255       result = m_suite.getGroupByInstances();
256     }
257     if (result != null) {
258       return result;
259     } else {
260       return XmlSuite.DEFAULT_GROUP_BY_INSTANCES;
261     }
262   }
263 
setGroupByInstances(boolean f)264   public void setGroupByInstances(boolean f) {
265     m_groupByInstances = f;
266   }
267 
268   /**
269    * @return Returns the isJUnit.
270    */
isJUnit()271   public boolean isJUnit() {
272     Boolean result = m_isJUnit;
273     if (null == result || XmlSuite.DEFAULT_JUNIT.equals(result)) {
274       result = m_suite.isJUnit();
275     }
276 
277     return result;
278   }
279 
280   /**
281    * @param isJUnit The isJUnit to set.
282    */
setJUnit(boolean isJUnit)283   public void setJUnit(boolean isJUnit) {
284     m_isJUnit = isJUnit;
285   }
286 
287   // For YAML
setJunit(boolean isJUnit)288   public void setJunit(boolean isJUnit) {
289     setJUnit(isJUnit);
290   }
291 
setSkipFailedInvocationCounts(boolean skip)292   public void setSkipFailedInvocationCounts(boolean skip) {
293     m_skipFailedInvocationCounts = skip;
294   }
295 
296   /**
297    * @return Returns the isJUnit.
298    */
skipFailedInvocationCounts()299   public boolean skipFailedInvocationCounts() {
300     Boolean result = m_skipFailedInvocationCounts;
301     if (null == result) {
302       result = m_suite.skipFailedInvocationCounts();
303     }
304 
305     return result;
306   }
307 
addMetaGroup(String name, List<String> metaGroup)308   public void addMetaGroup(String name, List<String> metaGroup) {
309     m_metaGroups.put(name, metaGroup);
310   }
311 
312   // For YAML
setMetaGroups(Map<String, List<String>> metaGroups)313   public void setMetaGroups(Map<String, List<String>> metaGroups) {
314     m_metaGroups = metaGroups;
315   }
316 
317   /**
318    * @return Returns the metaGroups.
319    */
getMetaGroups()320   public Map<String, List<String>> getMetaGroups() {
321     if (m_xmlGroups != null) {
322       Map<String, List<String>> result = Maps.newHashMap();
323       List<XmlDefine> defines = m_xmlGroups.getDefines();
324       for (XmlDefine xd : defines) {
325         result.put(xd.getName(), xd.getIncludes());
326       }
327       return result;
328     } else {
329       // deprecated
330       return m_metaGroups;
331     }
332   }
333 
334   /**
335    * @param parameters
336    */
setParameters(Map<String, String> parameters)337   public void setParameters(Map<String, String> parameters) {
338     m_parameters = parameters;
339   }
340 
addParameter(String key, String value)341   public void addParameter(String key, String value) {
342     m_parameters.put(key, value);
343   }
344 
getParameter(String name)345   public String getParameter(String name) {
346     String result = m_parameters.get(name);
347     if (null == result) {
348       result = m_suite.getParameter(name);
349     }
350 
351     return result;
352   }
353 
354   /**
355    * @return the parameters defined in this test tag and the tags above it.
356    */
getAllParameters()357   public Map<String, String> getAllParameters() {
358     Map<String, String> result = Maps.newHashMap();
359     result.putAll(getSuite().getParameters());
360     result.putAll(m_parameters);
361     return result;
362   }
363 
364   /**
365    * @return the parameters defined in this tag, and only this test tag. To retrieve
366    * the inherited parameters as well, call {@code getAllParameters()}.
367    */
getLocalParameters()368   public Map<String, String> getLocalParameters() {
369     return m_parameters;
370   }
371 
372   /**
373    * @deprecated Use {@code getLocalParameters()} or {@code getAllParameters()}
374    */
375   @Deprecated
getParameters()376   public Map<String, String> getParameters() {
377     return getAllParameters();
378   }
379 
380   /**
381    * @return the parameters defined on this <test> tag only
382    */
getTestParameters()383   public Map<String, String> getTestParameters() {
384     return m_parameters;
385   }
386 
setParallel(XmlSuite.ParallelMode parallel)387   public void setParallel(XmlSuite.ParallelMode parallel) {
388     m_parallel = parallel;
389   }
390 
getParallel()391   public XmlSuite.ParallelMode getParallel() {
392     XmlSuite.ParallelMode result;
393     if (null != m_parallel || XmlSuite.DEFAULT_PARALLEL.equals(m_parallel)) {
394       result = m_parallel;
395     }
396     else {
397       result = m_suite.getParallel();
398     }
399 
400     return result;
401   }
402 
getTimeOut()403   public String getTimeOut() {
404     String result = null;
405     if (null != m_timeOut) {
406       result = m_timeOut;
407     }
408     else {
409       result = m_suite.getTimeOut();
410     }
411 
412     return result;
413   }
414 
getTimeOut(long def)415   public long getTimeOut(long def) {
416     long result = def;
417     if (getTimeOut() != null) {
418         result = Long.parseLong(getTimeOut());
419     }
420 
421     return result;
422   }
423 
setTimeOut(long timeOut)424   public void setTimeOut(long timeOut) {
425       m_timeOut = Long.toString(timeOut);
426   }
427 
setTimeOut(String timeOut)428   private void setTimeOut(String timeOut) {
429       m_timeOut = timeOut;
430   }
431 
setExpression(String expression)432   public void setExpression(String expression) {
433     setBeanShellExpression(expression);
434   }
435 
setBeanShellExpression(String expression)436   public void setBeanShellExpression(String expression) {
437     List<XmlMethodSelector> selectors = getMethodSelectors();
438     if (selectors.size() > 0) {
439       selectors.get(0).setExpression(expression);
440     } else if (expression != null) {
441       XmlMethodSelector xms = new XmlMethodSelector();
442       xms.setExpression(expression);
443       xms.setLanguage("BeanShell");
444       getMethodSelectors().add(xms);
445     }
446   }
447 
getExpression()448   public String getExpression() {
449     List<XmlMethodSelector> selectors = getMethodSelectors();
450     if (selectors.size() > 0) {
451       return selectors.get(0).getExpression();
452     } else {
453       return null;
454     }
455   }
456 
toXml(String indent)457   public String toXml(String indent) {
458     XMLStringBuffer xsb = new XMLStringBuffer(indent);
459     Properties p = new Properties();
460     p.setProperty("name", getName());
461     if (m_isJUnit != null) {
462       XmlUtils.setProperty(p, "junit", m_isJUnit.toString(), XmlSuite.DEFAULT_JUNIT.toString());
463     }
464     if (m_parallel != null) {
465       XmlUtils.setProperty(p, "parallel", m_parallel.toString(), XmlSuite.DEFAULT_PARALLEL.toString());
466     }
467     if (m_verbose != null) {
468       XmlUtils.setProperty(p, "verbose", m_verbose.toString(), XmlSuite.DEFAULT_VERBOSE.toString());
469     }
470     if (null != m_timeOut) {
471       p.setProperty("time-out", m_timeOut.toString());
472     }
473     if (m_preserveOrder != null && ! XmlSuite.DEFAULT_PRESERVE_ORDER.equals(m_preserveOrder)) {
474       p.setProperty("preserve-order", m_preserveOrder.toString());
475     }
476     if (m_threadCount != -1) {
477       p.setProperty("thread-count", Integer.toString(m_threadCount));
478     }
479     if (m_groupByInstances != null) {
480       XmlUtils.setProperty(p, "group-by-instances", String.valueOf(getGroupByInstances()),
481           XmlSuite.DEFAULT_GROUP_BY_INSTANCES.toString());
482     }
483 
484     xsb.push("test", p);
485 
486 
487     if (null != getMethodSelectors() && !getMethodSelectors().isEmpty()) {
488       xsb.push("method-selectors");
489       for (XmlMethodSelector selector: getMethodSelectors()) {
490         xsb.getStringBuffer().append(selector.toXml(indent + "    "));
491       }
492 
493       xsb.pop("method-selectors");
494     }
495 
496     XmlUtils.dumpParameters(xsb, m_parameters);
497 
498     // groups
499     if (!m_metaGroups.isEmpty() || !m_includedGroups.isEmpty() || !m_excludedGroups.isEmpty()
500         || !m_xmlDependencyGroups.isEmpty()) {
501       xsb.push("groups");
502 
503       // define
504       for (Map.Entry<String, List<String>> entry: m_metaGroups.entrySet()) {
505         String metaGroupName = entry.getKey();
506         List<String> groupNames = entry.getValue();
507 
508         Properties metaGroupProp= new Properties();
509         metaGroupProp.setProperty("name",  metaGroupName);
510 
511         xsb.push("define", metaGroupProp);
512 
513         for (String groupName: groupNames) {
514           Properties includeProps = new Properties();
515           includeProps.setProperty("name", groupName);
516 
517           xsb.addEmptyElement("include", includeProps);
518         }
519 
520         xsb.pop("define");
521       }
522 
523       // run
524       if (!m_includedGroups.isEmpty() || !m_excludedGroups.isEmpty()) {
525         xsb.push("run");
526 
527         for (String includeGroupName: m_includedGroups) {
528           Properties includeProps = new Properties();
529           includeProps.setProperty("name", includeGroupName);
530 
531           xsb.addEmptyElement("include", includeProps);
532         }
533 
534         for (String excludeGroupName: m_excludedGroups) {
535           Properties excludeProps = new Properties();
536           excludeProps.setProperty("name", excludeGroupName);
537 
538           xsb.addEmptyElement("exclude", excludeProps);
539         }
540 
541         xsb.pop("run");
542       }
543 
544       // group dependencies
545       if (m_xmlDependencyGroups != null && ! m_xmlDependencyGroups.isEmpty()) {
546         xsb.push("dependencies");
547         for (Map.Entry<String, String> entry : m_xmlDependencyGroups.entrySet()) {
548           xsb.addEmptyElement("group", "name", entry.getKey(), "depends-on", entry.getValue());
549         }
550         xsb.pop("dependencies");
551       }
552 
553       xsb.pop("groups");
554     }
555 
556     if (null != m_xmlPackages && !m_xmlPackages.isEmpty()) {
557       xsb.push("packages");
558 
559       for (XmlPackage pack: m_xmlPackages) {
560         xsb.getStringBuffer().append(pack.toXml("      "));
561       }
562 
563       xsb.pop("packages");
564     }
565 
566     // classes
567     if (null != getXmlClasses() && !getXmlClasses().isEmpty()) {
568       xsb.push("classes");
569       for (XmlClass cls : getXmlClasses()) {
570         xsb.getStringBuffer().append(cls.toXml(indent + "    "));
571       }
572       xsb.pop("classes");
573     }
574 
575     xsb.pop("test");
576 
577     return xsb.toXML();
578   }
579 
580   @Override
toString()581   public String toString() {
582 //    return toXml("");
583     StringBuilder result = new StringBuilder("[Test: \"")
584             .append(m_name)
585             .append("\"")
586             .append(" verbose:")
587             .append(m_verbose);
588 
589     result.append("[parameters:");
590     for (Map.Entry<String, String> entry : m_parameters.entrySet()) {
591       result.append(entry.getKey()).append("=>").append(entry.getValue());
592     }
593 
594     result.append("]");
595     result.append("[metagroups:");
596     for (Map.Entry<String, List<String>> entry : m_metaGroups.entrySet()) {
597       result.append(entry.getKey()).append("=");
598       for (String n : entry.getValue()) {
599         result.append(n).append(",");
600       }
601     }
602     result.append("] ");
603 
604     result.append("[included: ");
605     for (String g : m_includedGroups) {
606       result.append(g).append(" ");
607     }
608     result.append("]");
609 
610     result.append("[excluded: ");
611     for (String g : m_excludedGroups) {
612       result.append(g).append(" ");
613     }
614     result.append("] ");
615 
616     result.append(" classes:");
617     for (XmlClass cl : m_xmlClasses) {
618       result.append(cl).append(" ");
619     }
620 
621     result.append(" packages:");
622     for (XmlPackage p : m_xmlPackages) {
623       result.append(p).append(" ");
624     }
625 
626     result.append("] ");
627 
628     return result.toString();
629   }
630 
ppp(String s)631   static void ppp(String s) {
632     System.out.println("[XmlTest] " + s);
633   }
634 
635   /**
636    * Clone the <TT>source</TT> <CODE>XmlTest</CODE> by including:
637    * - test attributes
638    * - groups definitions
639    * - parameters
640    *
641    * The &lt;classes&gt; sub element is ignored for the moment.
642    *
643    * @return a clone of the current XmlTest
644    */
645   @Override
clone()646   public Object clone() {
647     XmlTest result = new XmlTest(getSuite());
648 
649     result.setName(getName());
650     result.setIncludedGroups(getIncludedGroups());
651     result.setExcludedGroups(getExcludedGroups());
652     result.setJUnit(isJUnit());
653     result.setParallel(getParallel());
654     result.setVerbose(getVerbose());
655     result.setParameters(getLocalParameters());
656     result.setXmlPackages(getXmlPackages());
657     result.setTimeOut(getTimeOut());
658 
659     Map<String, List<String>> metagroups = getMetaGroups();
660     for (Map.Entry<String, List<String>> group: metagroups.entrySet()) {
661       result.addMetaGroup(group.getKey(), group.getValue());
662     }
663 
664     return result;
665   }
666 
667   /**
668    * Convenience method to cache the ordering numbers for methods.
669    */
getInvocationNumbers(String method)670   public List<Integer> getInvocationNumbers(String method) {
671     if (m_failedInvocationNumbers == null) {
672       m_failedInvocationNumbers = Maps.newHashMap();
673       for (XmlClass c : getXmlClasses()) {
674         for (XmlInclude xi : c.getIncludedMethods()) {
675           List<Integer> invocationNumbers = xi.getInvocationNumbers();
676           if (invocationNumbers.size() > 0) {
677             String methodName = c.getName() + "." + xi.getName();
678             m_failedInvocationNumbers.put(methodName, invocationNumbers);
679           }
680         }
681       }
682     }
683 
684     List<Integer> result = m_failedInvocationNumbers.get(method);
685     if (result == null) {
686       // Don't use emptyList here since this list might end up receiving values if
687       // the test run fails.
688       return Lists.newArrayList();
689     } else {
690       return result;
691     }
692   }
693 
setPreserveOrder(String preserveOrder)694   public void setPreserveOrder(String preserveOrder) {
695     m_preserveOrder = preserveOrder;
696   }
697 
getPreserveOrder()698   public String getPreserveOrder() {
699     String result = m_preserveOrder;
700     if (result == null || XmlSuite.DEFAULT_PRESERVE_ORDER.equals(m_preserveOrder)) {
701       result = m_suite.getPreserveOrder();
702     }
703 
704     return result;
705   }
706 
setSuite(XmlSuite result)707   public void setSuite(XmlSuite result) {
708     m_suite = result;
709   }
710 
getAllowReturnValues()711   public Boolean getAllowReturnValues() {
712     if (m_allowReturnValues != null) return m_allowReturnValues;
713     else return getSuite().getAllowReturnValues();
714   }
715 
setAllowReturnValues(Boolean allowReturnValues)716   public void setAllowReturnValues(Boolean allowReturnValues) {
717     m_allowReturnValues = allowReturnValues;
718   }
719 
720   /**
721    * Note that this attribute does not come from the XML file, it's calculated
722    * internally and represents the order in which this test tag was found in its
723    * &lt;suite&gt; tag.  It's used to calculate the ordering of the tests
724    * when preserve-test-order is true.
725    */
getIndex()726   public int getIndex() {
727     return m_index;
728   }
729 
730   @Override
hashCode()731   public int hashCode() {
732     final int prime = 31;
733     int result = 1;
734     result = prime * result
735         + ((m_excludedGroups == null) ? 0 : m_excludedGroups.hashCode());
736     result = prime
737         * result
738         + ((m_failedInvocationNumbers == null) ? 0 : m_failedInvocationNumbers
739             .hashCode());
740     result = prime * result
741         + ((m_includedGroups == null) ? 0 : m_includedGroups.hashCode());
742     result = prime * result + ((m_isJUnit == null) ? 0 : m_isJUnit.hashCode());
743     result = prime * result
744         + ((m_metaGroups == null) ? 0 : m_metaGroups.hashCode());
745     result = prime * result
746         + ((m_methodSelectors == null) ? 0 : m_methodSelectors.hashCode());
747     result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
748     result = prime * result
749         + ((m_parallel == null) ? 0 : m_parallel.hashCode());
750     result = prime * result
751         + ((m_parameters == null) ? 0 : m_parameters.hashCode());
752     result = prime * result
753         + ((m_preserveOrder == null) ? 0 : m_preserveOrder.hashCode());
754     result = prime
755         * result
756         + ((m_skipFailedInvocationCounts == null) ? 0
757             : m_skipFailedInvocationCounts.hashCode());
758     result = prime * result + m_threadCount;
759     result = prime * result + ((m_timeOut == null) ? 0 : m_timeOut.hashCode());
760     result = prime * result + ((m_verbose == null) ? 0 : m_verbose.hashCode());
761     result = prime * result
762         + ((m_xmlClasses == null) ? 0 : m_xmlClasses.hashCode());
763     result = prime * result
764         + ((m_xmlPackages == null) ? 0 : m_xmlPackages.hashCode());
765     return result;
766   }
767 
768   @Override
equals(Object obj)769   public boolean equals(Object obj) {
770     if (this == obj) {
771       return true;
772     }
773     if (obj == null)
774       return XmlSuite.f();
775     if (getClass() != obj.getClass())
776       return XmlSuite.f();
777     XmlTest other = (XmlTest) obj;
778     if (m_excludedGroups == null) {
779       if (other.m_excludedGroups != null)
780         return XmlSuite.f();
781     } else if (!m_excludedGroups.equals(other.m_excludedGroups))
782       return XmlSuite.f();
783 //    if (m_expression == null) {
784 //      if (other.m_expression != null)
785 //        return XmlSuite.f();
786 //    } else if (!m_expression.equals(other.m_expression))
787 //      return XmlSuite.f();
788     if (m_failedInvocationNumbers == null) {
789       if (other.m_failedInvocationNumbers != null)
790         return XmlSuite.f();
791     } else if (!m_failedInvocationNumbers
792         .equals(other.m_failedInvocationNumbers))
793       return XmlSuite.f();
794     if (m_includedGroups == null) {
795       if (other.m_includedGroups != null)
796         return XmlSuite.f();
797     } else if (!m_includedGroups.equals(other.m_includedGroups))
798       return XmlSuite.f();
799     if (m_isJUnit == null) {
800       if (other.m_isJUnit != null && ! other.m_isJUnit.equals(XmlSuite.DEFAULT_JUNIT))
801         return XmlSuite.f();
802     } else if (!m_isJUnit.equals(other.m_isJUnit))
803       return XmlSuite.f();
804     if (m_metaGroups == null) {
805       if (other.m_metaGroups != null)
806         return XmlSuite.f();
807     } else if (!m_metaGroups.equals(other.m_metaGroups))
808       return XmlSuite.f();
809     if (m_methodSelectors == null) {
810       if (other.m_methodSelectors != null)
811         return XmlSuite.f();
812     } else if (!m_methodSelectors.equals(other.m_methodSelectors))
813       return XmlSuite.f();
814     if (m_name == null) {
815       if (other.m_name != null)
816         return XmlSuite.f();
817     } else if (!m_name.equals(other.m_name))
818       return XmlSuite.f();
819     if (m_parallel == null) {
820       if (other.m_parallel != null)
821         return XmlSuite.f();
822     } else if (!m_parallel.equals(other.m_parallel))
823       return XmlSuite.f();
824     if (m_parameters == null) {
825       if (other.m_parameters != null)
826         return XmlSuite.f();
827     } else if (!m_parameters.equals(other.m_parameters))
828       return XmlSuite.f();
829     if (m_preserveOrder == null) {
830       if (other.m_preserveOrder != null)
831         return XmlSuite.f();
832     } else if (!m_preserveOrder.equals(other.m_preserveOrder))
833       return XmlSuite.f();
834     if (m_skipFailedInvocationCounts == null) {
835       if (other.m_skipFailedInvocationCounts != null)
836         return XmlSuite.f();
837     } else if (!m_skipFailedInvocationCounts
838         .equals(other.m_skipFailedInvocationCounts))
839       return XmlSuite.f();
840     if (m_threadCount != other.m_threadCount)
841       return XmlSuite.f();
842     if (m_timeOut == null) {
843       if (other.m_timeOut != null)
844         return XmlSuite.f();
845     } else if (!m_timeOut.equals(other.m_timeOut))
846       return XmlSuite.f();
847     if (m_verbose == null) {
848       if (other.m_verbose != null)
849         return XmlSuite.f();
850     } else if (!m_verbose.equals(other.m_verbose))
851       return XmlSuite.f();
852     if (m_xmlClasses == null) {
853       if (other.m_xmlClasses != null)
854         return XmlSuite.f();
855     } else if (!m_xmlClasses.equals(other.m_xmlClasses))
856       return XmlSuite.f();
857     if (m_xmlPackages == null) {
858       if (other.m_xmlPackages != null)
859         return XmlSuite.f();
860     } else if (!m_xmlPackages.equals(other.m_xmlPackages))
861       return XmlSuite.f();
862 
863     return true;
864   }
865 
addXmlDependencyGroup(String group, String dependsOn)866   public void addXmlDependencyGroup(String group, String dependsOn) {
867     if (! m_xmlDependencyGroups.containsKey(group)) {
868       m_xmlDependencyGroups.put(group, dependsOn);
869     } else {
870       throw new TestNGException("Duplicate group dependency found for group \"" + group + "\""
871           + ", use a space-separated list of groups in the \"depends-on\" attribute");
872     }
873   }
874 
getXmlDependencyGroups()875   public Map<String, String> getXmlDependencyGroups() {
876     if (m_xmlGroups != null) {
877       Map<String, String> result = Maps.newHashMap();
878       List<XmlDependencies> deps = m_xmlGroups.getDependencies();
879       for (XmlDependencies d : deps) {
880         result.putAll(d.getDependencies());
881       }
882       return result;
883     } else {
884       // deprecated
885       return m_xmlDependencyGroups;
886     }
887   }
888 
889   @ParentSetter
setXmlSuite(XmlSuite suite)890   public void setXmlSuite(XmlSuite suite) {
891 	  m_suite = suite;
892   }
893 
894   private XmlGroups m_xmlGroups;
895 
setGroups(XmlGroups xmlGroups)896   public void setGroups(XmlGroups xmlGroups) {
897     m_xmlGroups = xmlGroups;
898   }
899 }
900