1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.grinder.testutility;
23
24 import static java.util.Arrays.asList;
25
26 import java.net.MalformedURLException;
27 import java.net.URL;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Set;
34
35 import net.grinder.util.BlockingClassLoader;
36
37 import org.junit.runner.Description;
38 import org.junit.runner.Runner;
39 import org.junit.runner.notification.RunNotifier;
40 import org.junit.runners.BlockJUnit4ClassRunner;
41 import org.junit.runners.Suite;
42 import org.junit.runners.model.FrameworkMethod;
43 import org.junit.runners.model.InitializationError;
44
45
46
47
48
49
50
51
52 public abstract class JythonVersionRunner extends Suite {
53
54 protected static List<String> getHomes(String... homesProperties) {
55 final List<String> homes = new ArrayList<String>();
56
57 for (String property : homesProperties) {
58 final String pythonHome = System.getProperty(property);
59
60 if (pythonHome == null) {
61 System.err.println("***** " + property +
62 " not set, skipping tests for Jython version.");
63 }
64 else {
65 homes.add(pythonHome);
66 }
67 }
68
69 return homes;
70 }
71
72 private static final Set<String> ISOLATED_CLASSES =
73 new HashSet<String>(asList("net.grinder.*",
74 "org.python.*",
75 "grinder.test.*",
76 "org.mockito.*"));
77
78 private static final Set<String> SHARED_CLASSES =
79 new HashSet<String>(asList("net.grinder.util.weave.agent.*"));
80
81 public JythonVersionRunner(Class<?> testClass,
82 List<String> pythonHomes)
83 throws ClassNotFoundException, InitializationError, MalformedURLException{
84
85 super(testClass, createRunners(testClass, pythonHomes));
86 }
87
88 private static List<Runner> createRunners(Class<?> testClass,
89 List<String> pythonHomes)
90 throws ClassNotFoundException, InitializationError, MalformedURLException {
91
92 final List<Runner> runners = new ArrayList<Runner>();
93
94 for (String pythonHome : pythonHomes) {
95 final URL jythonJarURL =
96 new URL("file://" + pythonHome + "/jython.jar");
97
98 final ClassLoader loader =
99 new BlockingClassLoader(Arrays.asList(jythonJarURL),
100 Collections.<String>emptySet(),
101 ISOLATED_CLASSES,
102 SHARED_CLASSES,
103 true);
104
105 final Class<?> isolatedClass = loader.loadClass(testClass.getName());
106
107 runners.add(new PythonHomeRunner(isolatedClass, pythonHome));
108 }
109
110 if (runners.size() == 0) {
111 throw new InitializationError("No python home properties set");
112 }
113
114 return runners;
115 }
116
117 private static class PythonHomeRunner extends BlockJUnit4ClassRunner {
118
119 private final String m_pythonHome;
120
121 public PythonHomeRunner(Class<?> klass, String pythonHome)
122 throws InitializationError {
123 super(klass);
124
125 m_pythonHome = pythonHome;
126 }
127
128 @Override public Description getDescription() {
129 final Class<?> javaClass = getTestClass().getJavaClass();
130
131 final Description result =
132 Description.createSuiteDescription(
133 javaClass.getSimpleName() + " [" + m_pythonHome + "]",
134 javaClass.getAnnotations());
135
136 for (Description child : super.getDescription().getChildren()) {
137 result.addChild(child);
138 }
139
140 return result;
141 }
142
143 @Override protected String testName(FrameworkMethod method) {
144 return super.testName(method) + " [" + m_pythonHome + "]";
145 }
146
147 @Override protected void runChild(FrameworkMethod method,
148 RunNotifier notifier) {
149 final String oldPythonHome = System.getProperty("python.home");
150
151 System.setProperty("python.home", m_pythonHome);
152
153 try {
154 super.runChild(method, notifier);
155 }
156 finally {
157 if (oldPythonHome != null) {
158 System.setProperty("python.home", oldPythonHome);
159 }
160 else {
161 System.clearProperty("python.home");
162 }
163 }
164 }
165 }
166 }