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(1));
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(0));
73 check(!jr.run(getArgs("install repo module")) && usageOK(0));
74 check(!jr.run(getArgs("install -r repoDoesNotExist module")) && errorOK(1));
75 check(!jr.run(getArgs("install -p -r repoDoesNotExist module")) && errorOK(13));
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", "platform", "arch", 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", "platform", "arch", 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", "platform", "arch", 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", "platform", "arch", 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(1));
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 // Nonexist things are not there
134 check(!jr.run(getArgs("list ThisWillNotBeFound")) && outputOK(0));
135 check(!jr.run(getArgs("list -v ThisWillNotBeFound")) && errorOK(1));
136
137 // Bootstrap repository contents are there
138 check(!jr.run(getArgs("list java.se.core")) && errorOK(0));
139 check(jr.run(getArgs("list -p java.se.core")) && outputOK(3));
140 check(!jr.run(getArgs("list -v java.se.core")) && errorOK(1));
141 check(jr.run(getArgs("list -p -v java.se.core")) && outputOK(11));
142
143 // Various options work
144 check(jr.run(getArgs("list -r " + repo + " JRepoModuleA")) && outputOK(3));
145 check(jr.run(getArgs("list -p -r " + repo + " JRepoModuleA")) && outputOK(3));
146 check(jr.run(getArgs("list -v -r " + repo + " JRepoModuleA")) && outputOK(3));
147 check(jr.run(getArgs("list -p -v -r " + repo + " JRepoModuleA")) && outputOK(11));
148
149 // Given module name is treated as substring of full module names
150 check(jr.run(getArgs("list -r " + repo + " JRepoModule")) && outputOK(6));
151 check(jr.run(getArgs("list -p -r " + repo + " JRepoModu")) && outputOK(6));
152 check(jr.run(getArgs("list -v -r " + repo + " JRepo")) && outputOK(6));
153 check(jr.run(getArgs("list -p -v -r " + repo + " JR")) && outputOK(14));
154
155 /* Check uninstall command */
156
157 check(!jr.run(getArgs("uninstall")) && usageOK(0));
158 check(!jr.run(getArgs("uninstall repo MODULE")) && usageOK(0));
159 check(!jr.run(getArgs("uninstall -r repoDoesNotExist module")) && errorOK(1));
160 check(!jr.run(getArgs("uninstall -p -r repoDoesNotExist module")) && errorOK(13));
161
162 check(!jr.run(getArgs("uninstall -r " + repo + " Fred")) && errorOK(0));
163 check(!jr.run(getArgs("uninstall -v -r " + repo + " Fred")) && errorOK(1));
164
165 // Install one more module for tests below
166 jamFile = JamBuilder.createJam(
167 "jrepotest", "Example", "JRepoModuleC", "1.0", "platform", "arch", false, jamDir);
168 jamFile.deleteOnExit();
169 jam = jamFile.getCanonicalPath();
170 check(jr.run(getArgs("ins -v -r " + repo + " " + jam)) && outputOK(1));
171
172 // Verify a straightforward uninstall.
173 check(jr.run(getArgs("unin -v -r " + repo + " JRepoModuleA")) && outputOK(1));
174
175 // Verify we can't uninstall from module name alone when there is more
176 // than one version with that name...
177 check(!jr.run(getArgs("un -r " + repo + " JRepoModuleB")) && outputOK(0));
178
179 // ... and that with -v the JRepo says what ones there are...
180 check(!jr.run(getArgs("un -v -r " + repo + " JRepoModuleB")) && errorOK(4));
181
182 // ... but that by appending the version, uninstall succeeds.
183 check(jr.run(getArgs("un -v -r " + repo + " JRepoModuleB 2.0")) && outputOK(1));
184 check(jr.run(getArgs("list -v -r " + repo)) && outputOK(5));
185
186 // Verify that the -f flag causes the remaining JRepoModuleB versions
187 // to be uninstalled
188 check(jr.run(getArgs("un -v -f -r " + repo + " JRepoModuleB")) && outputOK(2));
189 check(jr.run(getArgs("list -v -r " + repo)) && outputOK(3));
190
191 // Install more modules to verify -i works
192 jamFile = JamBuilder.createJam(
193 "jrepotest", "Interact", "JRepoModuleD", "2.7", "platform", "arch", false, jamDir);
194 jamFile.deleteOnExit();
195 jam = jamFile.getCanonicalPath();
196 check(jr.run(getArgs("install -v -r " + repo + " " + jam)) && outputOK(1));
197 jamFile = JamBuilder.createJam(
198 "jrepotest", "Interact", "JRepoModuleD", "3.1", "platform", "arch", false, jamDir);
199 jamFile.deleteOnExit();
200 jam = jamFile.getCanonicalPath();
201 check(jr.run(getArgs("install -v -r " + repo + " " + jam)) && outputOK(1));
202
203 // This reader will let us delete the module JRepoModuleD version 3.1.
204 class MockReader extends BufferedReader {
205 MockReader() {
206 super(new StringReader("1\n"));
207 }
208 }
209 JRepo jr2 = new JRepo(
210 new PrintStream(bout), new PrintStream(berr), new MockReader());
211 check(jr2.run(getArgs("un -v -i -r " + repo + " JRepoModuleD")) && outputOK(5));
212 check(jr2.run(getArgs("list -v -r " + repo)) && outputOK(4));
213
214 /*
215 * End of checks on LocalRepository, now try a few on URLRepository.
216 */
217
218 // Create a directory for a url repository.
219 File urlRepoDir = new File(tmp, "JRepoTestURLRepoDir");
220 JamUtils.recursiveDelete(urlRepoDir);
221 urlRepoDir.mkdirs();
222
223 File repoDownloadDir = new File(urlRepoDir, "download");
224 Map<String, String> config = new HashMap<String, String>();
225 config.put(
226 "sun.module.repository.URLRepository.cacheDirectory",
227 repoDownloadDir.getAbsolutePath());
228
229 String urlRepoPath = urlRepoDir.getCanonicalPath();
230 if (!urlRepoPath.startsWith("/")) {
231 urlRepoPath = "/" + urlRepoPath;
232 }
233 urlRepoPath = "file://" + urlRepoPath;
234 Repository urlrepo = Modules.newURLRepository("JRepoTestURLRepository",
235 new URL(urlRepoPath), config);
236
237 // Verify multiple versions of same named module
238 jamFile = JamBuilder.createJam(
239 "jrepotest", "Example", "URLModuleX", "7.0", "platform", "arch", false, jamDir);
240 jamFile.deleteOnExit();
241 jam = jamFile.getCanonicalPath();
242 check(jr.run(getArgs("install -v -r " + urlRepoPath + " " + jam)) && outputOK(1));
243
244 jamFile = JamBuilder.createJam(
245 "jrepotest", "Example", "URLModuleX", "13.0", "platform", "arch", false, jamDir);
246 jamFile.deleteOnExit();
247 jam = jamFile.getCanonicalPath();
248 check(jr.run(getArgs("install -v -r " + urlRepoPath + " " + jam)) && outputOK(1));
249
250 // Verify list
251 check(jr.run(getArgs("list -v -r " + urlRepoPath)) && outputOK(4));
252
253 // Verify uninstall
254 check(jr.run(getArgs("un -v -f -r " + urlRepoPath + " URLModuleX 13")) && outputOK(1));
255
256 // Verify uninstall worked
257 check(jr.run(getArgs("list -v -r " + urlRepoPath)) && outputOK(3));
258
259 JRepo jr3 = new JRepo(System.out, System.err, null);
260 jr3.run(getArgs("list -v -r " + urlRepoPath));
261
262 // Cleanup test directories
263 if (failed == 0) {
264 JamUtils.recursiveDelete(jamDir);
265 JamUtils.recursiveDelete(localRepoDir);
266 JamUtils.recursiveDelete(urlRepoDir);
267 }
268 }
269
270 /** Return an array of Strings from the given String. */
271 static String[] getArgs(String s) {
272 List<String> args = new ArrayList<String>();
273 StringTokenizer st = new StringTokenizer(s);
274 while (st.hasMoreTokens()) {
275 String token = st.nextToken();
276 if (debug) System.err.println("adding arg " + token);
277 args.add(token);
278 }
279 if (debug) System.err.println("args length is " + args.size());
280 return args.toArray(new String[0]);
281 }
282
283 /**
284 * If the output is OK, returns true. For now, being OK means only
285 * having {code len} lines.
286 */
287 static boolean checkOutput(int len, ByteArrayOutputStream baos) throws Throwable {
288 String s = baos.toString("ASCII");
289 BufferedReader r = new BufferedReader(new StringReader(s));
290 int count = 0;
291 while (r.readLine() != null) {
292 count++;
293 }
294 if (debug) System.err.println(
295 "Checking expected length " + len
296 + " = given length " + count
297 + " on '" + s + "'");
298 bout.reset();
299 berr.reset();
300 return len == count;
301 }
302
303 /** Check stdout. */
304 static boolean outputOK(int len) throws Throwable {
305 return checkOutput(len, bout);
306 }
307
308 /** Check stderr. */
309 static boolean errorOK(int len) throws Throwable {
310 return checkOutput(len, berr);
311 }
312
313 /** Check that usage is provided as expected. */
314 static boolean usageOK(int len) throws Throwable {
315 // Add number of default lines of usage output to given value.
316 return checkOutput(12 + len, berr);
317 }
318
319 //--------------------- Infrastructure ---------------------------
320 static volatile int passed = 0, failed = 0;
321 static boolean pass() {passed++; return true;}
322 static boolean fail() {failed++; Thread.dumpStack(); return false;}
323 static boolean fail(String msg) {System.err.println(msg); return fail();}
324 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
325 static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
326 static boolean equal(Object x, Object y) {
327 if (x == null ? y == null : x.equals(y)) return pass();
328 else return fail(x + " not equal to " + y);}
329 public static void main(String[] args) throws Throwable {
330 try {realMain(args);} catch (Throwable t) {unexpected(t);}
331 System.out.println("\nPassed = " + passed + " failed = " + failed);
332 if (failed > 0) throw new AssertionError("Some tests failed");}
333 }