|
1 /* |
|
2 * Copyright (c) 2019, 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 package jdk.jpackage.test; |
|
24 |
|
25 import java.io.File; |
|
26 import java.util.ArrayList; |
|
27 import java.util.Arrays; |
|
28 import java.util.HashMap; |
|
29 import java.util.List; |
|
30 import java.util.Map; |
|
31 import java.util.function.BiConsumer; |
|
32 import java.util.function.Consumer; |
|
33 import java.util.function.Supplier; |
|
34 import java.util.stream.Collectors; |
|
35 import java.util.stream.Stream; |
|
36 |
|
37 /** |
|
38 * Instance of PackageTest is for configuring and running a single jpackage |
|
39 * command to produce platform specific package bundle. |
|
40 * |
|
41 * Provides methods hook up custom configuration of jpackage command and |
|
42 * verification of the output bundle. |
|
43 */ |
|
44 public final class PackageTest { |
|
45 |
|
46 /** |
|
47 * Default test configuration for jpackage command. Default jpackage command |
|
48 * initialization includes: |
|
49 * <li>Set --input and --output parameters. |
|
50 * <li>Set --name parameter. Value of the parameter is the name of the first |
|
51 * class with main function found in the callers stack. |
|
52 * Defaults can be |
|
53 * overridden with custom initializers set with subsequent addInitializer() |
|
54 * function calls. |
|
55 */ |
|
56 public PackageTest() { |
|
57 setJPackageExitCode(0); |
|
58 handlers = new HashMap<>(); |
|
59 Arrays.asList(PackageType.values()).stream().forEach( |
|
60 v -> handlers.put(v, new Handler(v))); |
|
61 } |
|
62 |
|
63 public PackageTest setJPackageExitCode(int v) { |
|
64 expectedJPackageExitCode = 0; |
|
65 return this; |
|
66 } |
|
67 |
|
68 public PackageTest addInitializer(Consumer<JPackageCommand> v, |
|
69 PackageType... types) { |
|
70 normailize(types).forEach( |
|
71 type -> handlers.get(type).addInitializer(v)); |
|
72 return this; |
|
73 } |
|
74 |
|
75 public PackageTest addBundleVerifier( |
|
76 BiConsumer<JPackageCommand, Executor.Result> v, PackageType... types) { |
|
77 normailize(types).forEach( |
|
78 type -> handlers.get(type).addBundleVerifier(v)); |
|
79 return this; |
|
80 } |
|
81 |
|
82 public PackageTest addBundleVerifier( |
|
83 Consumer<JPackageCommand> v, PackageType... types) { |
|
84 return addBundleVerifier((cmd, unused) -> v.accept(cmd), types); |
|
85 } |
|
86 |
|
87 public PackageTest addInstallVerifier(Consumer<JPackageCommand> v, |
|
88 PackageType... types) { |
|
89 normailize(types).forEach( |
|
90 type -> handlers.get(type).addInstallVerifier(v)); |
|
91 return this; |
|
92 } |
|
93 |
|
94 public PackageTest addUninstallVerifier(Consumer<JPackageCommand> v, |
|
95 PackageType... types) { |
|
96 normailize(types).forEach( |
|
97 type -> handlers.get(type).addUninstallVerifier(v)); |
|
98 return this; |
|
99 } |
|
100 |
|
101 public PackageTest configureHelloApp(PackageType... types) { |
|
102 addInitializer(cmd -> cmd.setHelloApp(), types); |
|
103 addInstallVerifier(cmd -> JPackageCommand.verifyHelloApp( |
|
104 cmd.launcherInstallationPath()), types); |
|
105 return this; |
|
106 } |
|
107 |
|
108 public void run() { |
|
109 List<Handler> supportedHandlers = handlers.values().stream() |
|
110 .filter(entry -> !entry.isVoid()) |
|
111 .collect(Collectors.toList()); |
|
112 |
|
113 if (supportedHandlers.isEmpty()) { |
|
114 return; |
|
115 } |
|
116 |
|
117 Supplier<JPackageCommand> initializer = new Supplier<>() { |
|
118 @Override |
|
119 public JPackageCommand get() { |
|
120 JPackageCommand cmd = new JPackageCommand().setDefaultInputOutput(); |
|
121 if (bundleOutputDir != null) { |
|
122 cmd.setArgumentValue("--output", bundleOutputDir.toString()); |
|
123 } |
|
124 setDefaultAppName(cmd); |
|
125 return cmd; |
|
126 } |
|
127 }; |
|
128 |
|
129 supportedHandlers.forEach(handler -> handler.accept(initializer.get())); |
|
130 } |
|
131 |
|
132 private class Handler implements Consumer<JPackageCommand> { |
|
133 |
|
134 Handler(PackageType type) { |
|
135 this.type = type; |
|
136 initializers = new ArrayList<>(); |
|
137 bundleVerifiers = new ArrayList<>(); |
|
138 installVerifiers = new ArrayList<>(); |
|
139 uninstallVerifiers = new ArrayList<>(); |
|
140 } |
|
141 |
|
142 boolean isVoid() { |
|
143 return initializers.isEmpty(); |
|
144 } |
|
145 |
|
146 void addInitializer(Consumer<JPackageCommand> v) { |
|
147 if (isSupported()) { |
|
148 initializers.add(v); |
|
149 } |
|
150 } |
|
151 |
|
152 void addBundleVerifier(BiConsumer<JPackageCommand, Executor.Result> v) { |
|
153 if (isSupported()) { |
|
154 bundleVerifiers.add(v); |
|
155 } |
|
156 } |
|
157 |
|
158 void addInstallVerifier(Consumer<JPackageCommand> v) { |
|
159 if (isSupported()) { |
|
160 installVerifiers.add(v); |
|
161 } |
|
162 } |
|
163 |
|
164 void addUninstallVerifier(Consumer<JPackageCommand> v) { |
|
165 if (isSupported()) { |
|
166 uninstallVerifiers.add(v); |
|
167 } |
|
168 } |
|
169 |
|
170 @Override |
|
171 public void accept(JPackageCommand cmd) { |
|
172 type.applyTo(cmd); |
|
173 |
|
174 initializers.stream().forEach(v -> v.accept(cmd)); |
|
175 switch (action) { |
|
176 case CREATE: |
|
177 Executor.Result result = cmd.execute(); |
|
178 result.assertExitCodeIs(expectedJPackageExitCode); |
|
179 final File bundle = cmd.outputBundle().toFile(); |
|
180 if (expectedJPackageExitCode == 0) { |
|
181 Test.assertTrue(bundle.exists(), String.format( |
|
182 "Check file [%s] exists", bundle)); |
|
183 } else { |
|
184 Test.assertFalse(bundle.exists(), String.format( |
|
185 "Check file [%s] doesn't exist", bundle)); |
|
186 } |
|
187 |
|
188 verifyPackageBundle(JPackageCommand.createImmutable(cmd), result); |
|
189 break; |
|
190 |
|
191 case VERIFY_INSTALLED: |
|
192 verifyPackageInstalled(JPackageCommand.createImmutable(cmd)); |
|
193 break; |
|
194 |
|
195 case VERIFY_UNINSTALLED: |
|
196 verifyPackageUninstalled(JPackageCommand.createImmutable(cmd)); |
|
197 break; |
|
198 } |
|
199 } |
|
200 |
|
201 private void verifyPackageBundle(JPackageCommand cmd, Executor.Result result) { |
|
202 bundleVerifiers.stream().forEach(v -> v.accept(cmd, result)); |
|
203 } |
|
204 |
|
205 private void verifyPackageInstalled(JPackageCommand cmd) { |
|
206 verifyInstalledLauncher(cmd.launcherInstallationPath().toFile()); |
|
207 installVerifiers.stream().forEach(v -> v.accept(cmd)); |
|
208 } |
|
209 |
|
210 private void verifyPackageUninstalled(JPackageCommand cmd) { |
|
211 verifyUninstalledLauncher(cmd.launcherInstallationPath().toFile()); |
|
212 uninstallVerifiers.stream().forEach(v -> v.accept(cmd)); |
|
213 } |
|
214 |
|
215 private boolean isSupported() { |
|
216 return type.getName() != null && type.isSupported(); |
|
217 } |
|
218 |
|
219 private final PackageType type; |
|
220 private final List<Consumer<JPackageCommand>> initializers; |
|
221 private final List<BiConsumer<JPackageCommand, Executor.Result>> bundleVerifiers; |
|
222 private final List<Consumer<JPackageCommand>> installVerifiers; |
|
223 private final List<Consumer<JPackageCommand>> uninstallVerifiers; |
|
224 } |
|
225 |
|
226 private void setDefaultAppName(JPackageCommand cmd) { |
|
227 StackTraceElement st[] = Thread.currentThread().getStackTrace(); |
|
228 for (StackTraceElement ste : st) { |
|
229 if ("main".equals(ste.getMethodName())) { |
|
230 String name = ste.getClassName(); |
|
231 name = name.substring(name.lastIndexOf('.') + 1); |
|
232 cmd.addArguments("--name", name); |
|
233 break; |
|
234 } |
|
235 } |
|
236 } |
|
237 |
|
238 private Stream<PackageType> normailize(PackageType[] types) { |
|
239 if (types == null || types.length == 0) { |
|
240 return Arrays.stream(PackageType.values()); |
|
241 } |
|
242 return Arrays.stream(types).distinct(); |
|
243 } |
|
244 |
|
245 private void verifyInstalledLauncher(File launcher) { |
|
246 Test.assertTrue(launcher.isFile(), String.format( |
|
247 "Check application launcher [%s] is a file", launcher)); |
|
248 Test.assertTrue(launcher.canExecute(), String.format( |
|
249 "Check application launcher [%s] can be executed", launcher)); |
|
250 } |
|
251 |
|
252 private void verifyUninstalledLauncher(File launcher) { |
|
253 Test.assertFalse(launcher.exists(), String.format( |
|
254 "Check application launcher [%s] is not installed", launcher)); |
|
255 File installDir = launcher.getParentFile().getParentFile(); |
|
256 Test.assertFalse(installDir.exists(), String.format( |
|
257 "Check application installation directory [%s] is not available", |
|
258 installDir)); |
|
259 } |
|
260 |
|
261 private int expectedJPackageExitCode; |
|
262 private Map<PackageType, Handler> handlers; |
|
263 |
|
264 /** |
|
265 * Test action. |
|
266 */ |
|
267 static private enum Action { |
|
268 /** |
|
269 * Create bundle. |
|
270 */ |
|
271 CREATE, |
|
272 |
|
273 /** |
|
274 * Verify bundle installed. |
|
275 */ |
|
276 VERIFY_INSTALLED, |
|
277 |
|
278 /** |
|
279 * Verify bundle uninstalled. |
|
280 */ |
|
281 VERIFY_UNINSTALLED |
|
282 }; |
|
283 private final static Action action; |
|
284 private final static File bundleOutputDir; |
|
285 |
|
286 static { |
|
287 final String JPACKAGE_TEST_OUTPUT = "jpackage.test.output"; |
|
288 |
|
289 String val = System.getProperty(JPACKAGE_TEST_OUTPUT); |
|
290 if (val == null) { |
|
291 bundleOutputDir = null; |
|
292 } else { |
|
293 bundleOutputDir = new File(val).getAbsoluteFile(); |
|
294 |
|
295 Test.assertTrue(bundleOutputDir.isDirectory(), String.format( |
|
296 "Check value of %s property [%s] references a directory", |
|
297 JPACKAGE_TEST_OUTPUT, bundleOutputDir)); |
|
298 Test.assertTrue(bundleOutputDir.canWrite(), String.format( |
|
299 "Check value of %s property [%s] references writable directory", |
|
300 JPACKAGE_TEST_OUTPUT, bundleOutputDir)); |
|
301 } |
|
302 } |
|
303 |
|
304 static { |
|
305 if (System.getProperty("jpackage.verify.install") != null) { |
|
306 action = Action.VERIFY_INSTALLED; |
|
307 } else if (System.getProperty("jpackage.verify.uninstall") != null) { |
|
308 action = Action.VERIFY_UNINSTALLED; |
|
309 } else { |
|
310 action = Action.CREATE; |
|
311 } |
|
312 } |
|
313 } |