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