1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.testng.conf;
20
21 import java.lang.reflect.Method;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.apache.maven.surefire.api.testset.TestSetFailedException;
27 import org.testng.TestNG;
28 import org.testng.xml.XmlSuite;
29
30 import static org.apache.maven.surefire.api.booter.ProviderParameterNames.PARALLEL_PROP;
31 import static org.apache.maven.surefire.api.booter.ProviderParameterNames.THREADCOUNT_PROP;
32 import static org.apache.maven.surefire.testng.conf.AbstractDirectConfigurator.loadListenerClasses;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class TestNGMapConfigurator implements Configurator {
48 @Override
49 public void configure(TestNG testng, Map<String, String> options) throws TestSetFailedException {
50 Map convertedOptions = getConvertedOptions(options);
51 testng.configure(convertedOptions);
52 }
53
54 @Override
55 public void configure(XmlSuite suite, Map<String, String> options) throws TestSetFailedException {
56 configureThreadCount(suite, options);
57 configureParallel(suite, options);
58 }
59
60 protected void configureThreadCount(XmlSuite suite, Map<String, String> options) throws TestSetFailedException {
61 String threadCount = options.get(THREADCOUNT_PROP);
62 if (threadCount != null) {
63 try {
64 suite.setThreadCount(Integer.parseInt(threadCount));
65 } catch (NumberFormatException e) {
66 throw new TestSetFailedException("Non-integer TestNG [threadcount] setting: " + threadCount, e);
67 }
68 }
69 }
70
71 protected void configureParallel(XmlSuite suite, Map<String, String> options) throws TestSetFailedException {
72 String parallel = options.get(PARALLEL_PROP);
73 if (parallel != null) {
74 suite.setParallel(parallel);
75 }
76 }
77
78 Map<String, Object> getConvertedOptions(Map<String, String> options) throws TestSetFailedException {
79 Map<String, Object> convertedOptions = new HashMap<>();
80 convertedOptions.put("-mixed", false);
81 for (Map.Entry<String, String> entry : options.entrySet()) {
82 String key = entry.getKey();
83 Object val = entry.getValue();
84 switch (key) {
85 case "listener":
86 val = convertListeners(entry.getValue());
87 break;
88 case "objectfactory":
89 case "testrunfactory":
90 val = AbstractDirectConfigurator.loadClass(entry.getValue());
91 break;
92 case "reporter":
93
94
95 val = convertReporterConfig(val);
96 key = "reporterslist";
97 break;
98 case "junit":
99 case "skipfailedinvocationcounts":
100 case "mixed":
101 case "group-by-instances":
102 val = convert(val, Boolean.class);
103 break;
104 case "configfailurepolicy":
105 case THREADCOUNT_PROP:
106 val = convert(val, String.class);
107 break;
108
109 case "suitethreadpoolsize":
110
111 case "dataproviderthreadcount":
112 val = convert(val, Integer.class);
113 break;
114 default:
115 break;
116 }
117
118 if (key.startsWith("-")) {
119 convertedOptions.put(key, val);
120 } else {
121 convertedOptions.put("-" + key, val);
122 }
123 }
124 return convertedOptions;
125 }
126
127
128 protected Object convertReporterConfig(Object val) {
129 try {
130 Class<?> reporterConfig = Class.forName("org.testng.ReporterConfig");
131 Method deserialize = reporterConfig.getMethod("deserialize", String.class);
132 Object rc = deserialize.invoke(null, val);
133 ArrayList<Object> reportersList = new ArrayList<>();
134 reportersList.add(rc);
135 return reportersList;
136 } catch (Exception e) {
137 return val;
138 }
139 }
140
141 protected Object convertListeners(String listenerClasses) throws TestSetFailedException {
142 return loadListenerClasses(listenerClasses);
143 }
144
145 protected Object convert(Object val, Class<?> type) {
146 if (val == null) {
147 return null;
148 } else if (type.isAssignableFrom(val.getClass())) {
149 return val;
150 } else if ((type == Boolean.class || type == boolean.class) && val.getClass() == String.class) {
151 return Boolean.valueOf((String) val);
152 } else if ((type == Integer.class || type == int.class) && val.getClass() == String.class) {
153 return Integer.valueOf((String) val);
154 } else if (type == String.class) {
155 return val.toString();
156 } else {
157 return val;
158 }
159 }
160 }