1 /*
2 * Copyright 2007-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24 import java.io.*;
25 import java.module.*;
26 import java.net.*;
27 import java.util.*;
28 import sun.module.JamUtils;
29 import sun.module.tools.JRepo;
30
31 /**
32 * @test
33 * @summary Test execution of JRepo
34 * @library ..
35 * @compile -XDignore.symbol.file JRepoTest.java ../JamBuilder.java
36 * @run main JRepoTest
37 */
38 public class JRepoTest {
39 private static final boolean debug = Boolean.getBoolean("module.tools.debug");
40
41 static final ByteArrayOutputStream bout = new ByteArrayOutputStream();
42 static final ByteArrayOutputStream berr = new ByteArrayOutputStream();
43
44 public static void realMain(String args[]) throws Throwable {
45 JRepo jr = new JRepo(new PrintStream(bout), new PrintStream(berr), null);
46
47 /*
48 * Check common error reporting.
49 */
50 check(!jr.run(new String[] {" "}) && usageOK(0));
51 check(!jr.run(getArgs("notASubCcommand")) && usageOK(0));
52 check(!jr.run(getArgs("list -+")) && usageOK(1));
53
54 /*
55 * Do many tests on a LocalRepository, then a few on a URLRepository
56 * as a sanity check.
57 */
58
59
60 // Create a temporary directory for JAM files and repositories.
61 File tmp = new File(
62 System.getProperty("test.scratch", "."), "JRepoTestDir").getCanonicalFile();
63 JamUtils.recursiveDelete(tmp);
64 tmp.mkdirs();
65
66 // Create a directory for JAM files
67 File jamDir = new File(tmp, "JRepoTestJamDir");
68 JamUtils.recursiveDelete(jamDir);
69 jamDir.mkdirs();
70
71 /* Check install command */
72
73 check(!jr.run(getArgs("install")) && usageOK(0));
74 check(!jr.run(getArgs("install repo module")) && usageOK(0));
75 check(!jr.run(getArgs("install -r repoDoesNotExist module")) && errorOK(1));
76 check(!jr.run(getArgs("install -p -r repoDoesNotExist module")) && errorOK(9));
77
78 // Create a directory for a local repository.
79 File localRepoDir = new File(tmp, "JRepoTestLocalRepoDir");
80 JamUtils.recursiveDelete(localRepoDir);
81 localRepoDir.mkdirs();
82 String repo = localRepoDir.getCanonicalPath();
83
84 // Verify that you can't install a module which doesn't exist
85 check(!jr.run(getArgs("install -r " + repo + " NoSuchModule")) && errorOK(1));
86
87 // Each install must be of a different module
88
89 // Verify silent output
90 File jamFile = JamBuilder.createJam(
91 "jrepotest", "Example", "JRepoModuleA", "1.0", "platform", "arch", false, jamDir);
92 jamFile.deleteOnExit();
93 String jam = jamFile.getCanonicalPath();
94 check(jr.run(getArgs("install -r " + repo + " " + jam)) && outputOK(0));
95
96 // Verify verbose output
97 jamFile = JamBuilder.createJam(
98 "jrepotest", "Example", "JRepoModuleB", "1.0", "platform", "arch", false, jamDir);
99 jamFile.deleteOnExit();
100 jam = jamFile.getCanonicalPath();
101 check(jr.run(getArgs("ins -v -r " + repo + " " + jam)) && outputOK(1));
102
103 // Verify multiple versions of same named module
104 jamFile = JamBuilder.createJam(
105 "jrepotest", "Example", "JRepoModuleB", "2.0", "platform", "arch", false, jamDir);
106 jamFile.deleteOnExit();
107 jam = jamFile.getCanonicalPath();
108 check(jr.run(getArgs("install -v -r " + repo + " " + jam)) && outputOK(1));
109 jamFile = JamBuilder.createJam(
110 "jrepotest", "Example", "JRepoModuleB", "2.5", "platform", "arch", false, jamDir);
111 jamFile.deleteOnExit();
112 jam = jamFile.getCanonicalPath();
113 check(jr.run(getArgs("install -v -r " + repo + " " + jam)) && outputOK(1));
114
115 // Verify modules are installed
116 check(jr.run(getArgs("list -v -r " + repo)) && outputOK(6));
117
118 // Verify -p is not applicable to install
119 check(!jr.run(getArgs("install -p -r " + repo + " " + jam)) && usageOK(1));
120
121 /* Check list command */
122
123 check(!jr.run(getArgs("list")) && errorOK(0));
124 check(jr.run(getArgs("list -p")) && outputOK(14));
125 check(!jr.run(getArgs("list -v")) && errorOK(1));
126 check(jr.run(getArgs("list -p -v")) && outputOK(14));
127
128 // Common prefixes of "list"
129 check(jr.run(getArgs("lis -r " + repo)) && outputOK(6));
130 check(jr.run(getArgs("li -p -r " + repo)) && outputOK(20));
131 check(jr.run(getArgs("l -v -r " + repo)) && outputOK(6));
132 check(jr.run(getArgs("list -p -v -r " + repo)) && outputOK(20));
133
134 // Nonexist things are not there
135 check(!jr.run(getArgs("list ThisWillNotBeFound")) && outputOK(0));
136 check(!jr.run(getArgs("list -v ThisWillNotBeFound")) && errorOK(1));
137
138 // Bootstrap repository contents are there
139 check(!jr.run(getArgs("list java.se.core")) && errorOK(0));
140 check(jr.run(getArgs("list -p java.se.core")) && outputOK(3));
141 check(!jr.run(getArgs("list -v java.se.core")) && errorOK(1));
142 check(jr.run(getArgs("list -p -v java.se.core")) && outputOK(3));
143
144 // Various options work
145 check(jr.run(getArgs("list -r " + repo + " JRepoModuleA")) && outputOK(3));
146 check(jr.run(getArgs("list -p -r " + repo + " JRepoModuleA")) && outputOK(3));
147 check(jr.run(getArgs("list -v -r " + repo + " JRepoModuleA")) && outputOK(3));
148 check(jr.run(getArgs("list -p -v -r " + repo + " JRepoModuleA")) && outputOK(3));
149
150 // Given module name is treated as substring of full module names
151 check(jr.run(getArgs("list -r " + repo + " JRepoModule")) && outputOK(6));
152 check(jr.run(getArgs("list -p -r " + repo + " JRepoModu")) && outputOK(6));
153 check(jr.run(getArgs("list -v -r " + repo + " JRepo")) && outputOK(6));
154 check(jr.run(getArgs("list -p -v -r " + repo + " JR")) && outputOK(6));
155
156 /* Check uninstall command */
157
158 check(!jr.run(getArgs("uninstall")) && usageOK(0));
159 check(!jr.run(getArgs("uninstall repo MODULE")) && usageOK(0));
160 check(!jr.run(getArgs("uninstall -r repoDoesNotExist module")) && errorOK(1));
161 check(!jr.run(getArgs("uninstall -p -r repoDoesNotExist module")) && errorOK(9));
162
163 check(!jr.run(getArgs("uninstall -r " + repo + " Fred")) && errorOK(0));
164 check(!jr.run(getArgs("uninstall -v -r " + repo + " Fred")) && errorOK(1));
165
166 // Install one more module for tests below
167 jamFile = JamBuilder.createJam(
168 "jrepotest", "Example", "JRepoModuleC", "1.0", "platform", "arch", false, jamDir);
169 jamFile.deleteOnExit();
170 jam = jamFile.getCanonicalPath();
171 check(jr.run(getArgs("ins -v -r " + repo + " " + jam)) && outputOK(1));
172
173 // Verify a straightforward uninstall.
174 check(jr.run(getArgs("unin -v -r " + repo + " JRepoModuleA")) && outputOK(1));
175
176 // Verify we can't uninstall from module name alone when there is more
177 // than one version with that name...
178 check(!jr.run(getArgs("un -r " + repo + " JRepoModuleB")) && outputOK(0));
179
180 // ... and that with -v the JRepo says what ones there are...
181 check(!jr.run(getArgs("un -v -r " + repo + " JRepoModuleB")) && errorOK(4));
182
183 // ... but that by appending the version, uninstall succeeds.
184 check(jr.run(getArgs("un -v -r " + repo + " JRepoModuleB 2.0")) && outputOK(1));
185 check(jr.run(getArgs("list -v -r " + repo)) && outputOK(5));
186
187 // Verify that the -f flag causes the remaining JRepoModuleB versions
188 // to be uninstalled
189 check(jr.run(getArgs("un -v -f -r " + repo + " JRepoModuleB")) && outputOK(2));
190 check(jr.run(getArgs("list -v -r " + repo)) && outputOK(3));
191
192 // Install more modules to verify -i works
193 jamFile = JamBuilder.createJam(
194 "jrepotest", "Interact", "JRepoModuleD", "2.7", "platform", "arch", false, jamDir);
195 jamFile.deleteOnExit();
196 jam = jamFile.getCanonicalPath();
197 check(jr.run(getArgs("install -v -r " + repo + " " + jam)) && outputOK(1));
198 jamFile = JamBuilder.createJam(
199 "jrepotest", "Interact", "JRepoModuleD", "3.1", "platform", "arch", false, jamDir);
200 jamFile.deleteOnExit();
201 jam = jamFile.getCanonicalPath();
202 check(jr.run(getArgs("install -v -r " + repo + " " + jam)) && outputOK(1));
203
204 // This reader will let us delete the module JRepoModuleD version 3.1.
205 class MockReader extends BufferedReader {
206 MockReader() {
207 super(new StringReader("1\n"));
208 }
209 }
210 JRepo jr2 = new JRepo(
211 new PrintStream(bout), new PrintStream(berr), new MockReader());
212 check(jr2.run(getArgs("un -v -i -r " + repo + " JRepoModuleD")) && outputOK(5));
213 check(jr2.run(getArgs("list -v -r " + repo)) && outputOK(4));
214
215 /*
216 * End of checks on LocalRepository, now try a few on URLRepository.
217 */
218
219 // Create a directory for a url repository.
220 File urlRepoDir = new File(tmp, "JRepoTestURLRepoDir");
221 JamUtils.recursiveDelete(urlRepoDir);
222 urlRepoDir.mkdirs();
223
224 File repoDownloadDir = new File(urlRepoDir, "download");
225 Map<String, String> config = new HashMap<String, String>();
226 config.put(
227 "sun.module.repository.URLRepository.cacheDirectory",
228 repoDownloadDir.getAbsolutePath());
229
230 String urlRepoPath = urlRepoDir.getCanonicalPath();
231 if (!urlRepoPath.startsWith("/")) {
232 urlRepoPath = "/" + urlRepoPath;
233 }
234 urlRepoPath = "file://" + urlRepoPath;
235 Repository urlrepo = Modules.newURLRepository("JRepoTestURLRepository",
236 new URL(urlRepoPath), config);
237
238 // Verify multiple versions of same named module
239 jamFile = JamBuilder.createJam(
240 "jrepotest", "Example", "URLModuleX", "7.0", "platform", "arch", false, jamDir);
241 jamFile.deleteOnExit();
242 jam = jamFile.getCanonicalPath();
243 check(jr.run(getArgs("install -v -r " + urlRepoPath + " " + jam)) && outputOK(1));
244
245 jamFile = JamBuilder.createJam(
246 "jrepotest", "Example", "URLModuleX", "13.0", "platform", "arch", false, jamDir);
247 jamFile.deleteOnExit();
248 jam = jamFile.getCanonicalPath();
249 check(jr.run(getArgs("install -v -r " + urlRepoPath + " " + jam)) && outputOK(1));
250
251 // Verify list
252 check(jr.run(getArgs("list -v -r " + urlRepoPath)) && outputOK(4));
253
254 // Verify uninstall
255 check(jr.run(getArgs("un -v -f -r " + urlRepoPath + " URLModuleX 13")) && outputOK(1));
256
257 // Verify uninstall worked
258 check(jr.run(getArgs("list -v -r " + urlRepoPath)) && outputOK(3));
259
260 JRepo jr3 = new JRepo(System.out, System.err, null);
261 jr3.run(getArgs("list -v -r " + urlRepoPath));
262
263 // Cleanup test directories
264 if (failed == 0) {
265 JamUtils.recursiveDelete(jamDir);
266 JamUtils.recursiveDelete(localRepoDir);
267 JamUtils.recursiveDelete(urlRepoDir);
268 }
269 }
270
271 /** Return an array of Strings from the given String. */
272 static String[] getArgs(String s) {
273 List<String> args = new ArrayList<String>();
274 StringTokenizer st = new StringTokenizer(s);
275 while (st.hasMoreTokens()) {
276 String token = st.nextToken();
277 if (debug) System.err.println("adding arg " + token);
278 args.add(token);
279 }
280 if (debug) System.err.println("args length is " + args.size());
281 return args.toArray(new String[0]);
282 }
283
284 /**
285 * If the output is OK, returns true. For now, being OK means only
286 * having {code len} lines.
287 */
288 static boolean checkOutput(int len, ByteArrayOutputStream baos) throws Throwable {
289 String s = baos.toString("ASCII");
290 BufferedReader r = new BufferedReader(new StringReader(s));
291 int count = 0;
292 while (r.readLine() != null) {
293 count++;
294 }
295 if (debug) System.err.println(
296 "Checking expected length " + len
297 + " = given length " + count
298 + " on '" + s + "'");
299 bout.reset();
300 berr.reset();
301 return len == count;
302 }
303
304 /** Check stdout. */
305 static boolean outputOK(int len) throws Throwable {
306 return checkOutput(len, bout);
307 }
308
309 /** Check stderr. */
310 static boolean errorOK(int len) throws Throwable {
311 return checkOutput(len, berr);
312 }
313
314 /** Check that usage is provided as expected. */
315 static boolean usageOK(int len) throws Throwable {
316 // Add number of default lines of usage output to given value.
317 return checkOutput(8 + len, berr);
318 }
319
320 //--------------------- Infrastructure ---------------------------
321 static volatile int passed = 0, failed = 0;
322 static boolean pass() {passed++; return true;}
323 static boolean fail() {failed++; Thread.dumpStack(); return false;}
324 static boolean fail(String msg) {System.err.println(msg); return fail();}
325 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
326 static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
327 static boolean equal(Object x, Object y) {
328 if (x == null ? y == null : x.equals(y)) return pass();
329 else return fail(x + " not equal to " + y);}
330 public static void main(String[] args) throws Throwable {
331 try {realMain(args);} catch (Throwable t) {unexpected(t);}
332 System.out.println("\nPassed = " + passed + " failed = " + failed);
333 if (failed > 0) throw new AssertionError("Some tests failed");}
334 }