1 /*
2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.io.StringWriter;
27 import java.lang.reflect.Field;
28 import java.lang.reflect.Method;
29 import java.net.URL;
30 import java.net.URLClassLoader;
31 import java.nio.file.FileVisitResult;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.nio.file.SimpleFileVisitor;
36 import java.nio.file.attribute.BasicFileAttributes;
37 import java.util.Objects;
38 import java.util.spi.ToolProvider;
39
40 import static org.testng.Assert.assertEquals;
41 import static org.testng.Assert.assertNotEquals;
42 import static org.testng.Assert.assertNotNull;
43 import static org.testng.Assert.assertTrue;
44 import static org.testng.Assert.fail;
45
46 public class JextractToolRunner {
47 private static final ToolProvider JEXTRACT_TOOL = ToolProvider.findFirst("jextract")
48 .orElseThrow(() ->
49 new RuntimeException("jextract tool not found")
50 );
51
52 private final Path inputDir;
53 private final Path outputDir;
54
55 protected JextractToolRunner() {
56 this(null, null);
57 }
58
59 protected JextractToolRunner(Path input, Path output) {
60 inputDir = (input != null) ? input :
61 Paths.get(System.getProperty("test.src", "."));
62 outputDir = (output != null) ? output :
63 Paths.get(System.getProperty("test.classes", "."));
64 }
65
66 protected Path getInputFilePath(String fileName) {
67 return inputDir.resolve(fileName).toAbsolutePath();
68 }
69
70 protected Path getOutputFilePath(String fileName) {
71 return outputDir.resolve(fileName).toAbsolutePath();
72 }
73
74 protected static class JextractResult {
75 private int exitCode;
76 private String output;
77
78 JextractResult(int exitCode, String output) {
79 this.exitCode = exitCode;
80 this.output = output;
81 }
82
83 protected JextractResult checkSuccess() {
84 assertEquals(exitCode, 0, "Sucess excepted, failed: " + exitCode);
85 return this;
86 }
87
88 protected JextractResult checkFailure() {
89 assertNotEquals(exitCode, 0, "Failure excepted, succeeded!");
90 return this;
91 }
92
93 protected JextractResult checkContainsOutput(String expected) {
94 Objects.requireNonNull(expected);
95 assertTrue(output.contains(expected), "Output does not contain string: " + expected);
96 return this;
97 }
98
99 protected JextractResult checkMatchesOutput(String regex) {
100 Objects.requireNonNull(regex);
101 assertTrue(output.trim().matches(regex), "Output does not match regex: " + regex);
102 return this;
103 }
104 }
105
106 protected static JextractResult run(String... options) {
107 StringWriter writer = new StringWriter();
108 PrintWriter pw = new PrintWriter(writer);
109 String[] args = new String[options.length + 1];
110 System.arraycopy(options, 0, args, 1, options.length);
111 args[0] = "-C-nostdinc";
112 int result = JEXTRACT_TOOL.run(pw, pw, options);
113 String output = writer.toString();
114 System.err.println(output);
115 return new JextractResult(result, output);
116 }
117
118 protected static void deleteFile(Path path) {
119 try {
120 Files.deleteIfExists(path);
121 } catch (IOException ioExp) {
122 throw new RuntimeException(ioExp);
123 }
124 }
125
126 protected static void deleteDir(Path path) {
127 try {
128 Files.walkFileTree(path, new SimpleFileVisitor<>() {
129 @Override
130 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
131 deleteFile(file);
132 return FileVisitResult.CONTINUE;
133 }
134
135 @Override
136 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
137 deleteFile(dir);
138 return FileVisitResult.CONTINUE;
139 }
140 });
141 } catch (IOException ioExp) {
142 throw new RuntimeException(ioExp);
143 }
144 }
145
146 protected static Loader classLoader(Path... paths) {
147 try {
148 URL[] urls = new URL[paths.length];
149 for (int i = 0; i < paths.length; i++) {
150 urls[i] = paths[i].toUri().toURL();
151 }
152 URLClassLoader ucl = new URLClassLoader(urls, null);
153 return new Loader(ucl);
154 } catch (RuntimeException re) {
155 throw re;
156 } catch (Exception e) {
157 throw new RuntimeException(e);
158 }
159 }
160
161 protected static Field findField(Class<?> cls, String name) {
162 try {
163 return cls.getField(name);
164 } catch (Exception e) {
165 System.err.println(e);
166 return null;
167 }
168 }
169
170 protected static Method findMethod(Class<?> cls, String name, Class<?>... argTypes) {
171 try {
172 return cls.getMethod(name, argTypes);
173 } catch (Exception e) {
174 System.err.println(e);
175 return null;
176 }
177 }
178
179 protected static Method findStructFieldGet(Class<?> cls, String name) {
180 return findMethod(cls, name + "$get");
181 }
182
183 protected static Method findGlobalVariableGet(Class<?> cls, String name) {
184 return findMethod(cls, name + "$get");
185 }
186
187 protected static Method findEnumConstGet(Class<?> cls, String name) {
188 return findMethod(cls, name);
189 }
190
191 protected static Method findFirstMethod(Class<?> cls, String name) {
192 try {
193 for (Method m : cls.getMethods()) {
194 if (name.equals(m.getName())) {
195 return m;
196 }
197 }
198 return null;
199 } catch (Exception e) {
200 System.err.println(e);
201 return null;
202 }
203 }
204
205 protected Field checkIntField(Class<?> cls, String name, int value) {
206 Field field = findField(cls, name);
207 assertNotNull(field);
208 assertEquals(field.getType(), int.class);
209 try {
210 assertEquals((int)field.get(null), value);
211 } catch (Exception exp) {
212 System.err.println(exp);
213 assertTrue(false, "should not reach here");
214 }
215 return field;
216 }
217
218 protected Class<?> findClass(Class<?>[] clz, String name) {
219 for (Class<?> cls: clz) {
220 if (cls.getSimpleName().equals(name)) {
221 return cls;
222 }
223 }
224 return null;
225 }
226
227 protected Method checkMethod(Class<?> cls, String name, Class<?> returnType, Class<?>... args) {
228 try {
229 Method m = cls.getDeclaredMethod(name, args);
230 assertTrue(m.getReturnType() == returnType);
231 return m;
232 } catch (NoSuchMethodException nsme) {
233 fail("Expect method " + name);
234 }
235 return null;
236 }
237
238 protected static class Loader implements AutoCloseable {
239
240 private final URLClassLoader loader;
241
242 public Loader(URLClassLoader loader) {
243 this.loader = loader;
244 }
245
246 public Class<?> loadClass(String className) {
247 try {
248 return Class.forName(className, false, loader);
249 } catch (ClassNotFoundException e) {
250 // return null so caller can check if class loading
251 // was successful with assertNotNull/assertNull
252 return null;
253 }
254 }
255
256 @Override
257 public void close() {
258 try {
259 loader.close();
260 } catch (IOException e) {
261 throw new RuntimeException(e);
262 }
263 }
264 }
265 }
--- EOF ---