001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.util;
038:
039: import junit.framework.*;
040: import java.io.*;
041:
042: import java.util.Arrays;
043: import java.util.ArrayList;
044: import java.util.LinkedList;
045: import java.util.List;
046: import java.util.Set;
047: import java.util.TreeSet;
048:
049: import edu.rice.cs.drjava.config.FileOption;
050: import edu.rice.cs.drjava.DrJavaTestCase;
051: import edu.rice.cs.util.newjvm.ExecJVM;
052: import edu.rice.cs.util.FileOps;
053:
054: /** Test cases for {@link FileOps}.
055: * @version $Id: FileOpsTest.java 4255 2007-08-28 19:17:37Z mgricken $
056: */
057: @SuppressWarnings("deprecation")
058: public class FileOpsTest extends DrJavaTestCase {
059: private static final Log _log = new Log("FileOpsTest.txt", false);
060: public static final String TEXT = "hi, dude.";
061: public static final String PREFIX = "prefix";
062: public static final String SUFFIX = ".suffix";
063:
064: public void testCreateTempDirectory() throws IOException {
065: File dir = FileOps.createTempDirectory(PREFIX);
066: try {
067: assertTrue("createTempDirectory result is a directory", dir
068: .isDirectory());
069: assertTrue("temp directory has correct prefix", dir
070: .getName().startsWith(PREFIX));
071: } finally {
072: assertTrue("delete directory", dir.delete());
073: }
074: }
075:
076: public void testReadAndWriteTempFile() throws IOException {
077: File file = FileOps.writeStringToNewTempFile(PREFIX, SUFFIX,
078: TEXT);
079: try {
080: assertTrue("temp file has correct prefix", file.getName()
081: .startsWith(PREFIX));
082: assertTrue("temp file has correct suffix", file.getName()
083: .endsWith(SUFFIX));
084:
085: String read = FileOps.readFileAsString(file);
086: assertEquals("contents after read", TEXT, read);
087: } finally {
088: assertTrue("delete file", file.delete());
089: }
090: }
091:
092: public void testRecursiveDirectoryDelete() throws IOException {
093: final File baseDir = FileOps.createTempDirectory(PREFIX);
094:
095: File parentDir = baseDir;
096: boolean ret;
097:
098: // create a bunch of subdirs and some files.
099: for (int i = 0; i < 5; i++) {
100: File subdir = new File(parentDir, "subdir" + i);
101: ret = subdir.mkdir();
102: assertTrue("create directory " + subdir, ret);
103:
104: for (int j = 0; j < 2; j++) {
105: File file = new File(parentDir, "file" + i + "-" + j);
106: FileOps.writeStringToFile(file, "Some text for file "
107: + file.getAbsolutePath());
108: assertTrue(file + " exists", file.exists());
109: }
110:
111: parentDir = subdir;
112: }
113:
114: // OK, now try to delete base.
115: ret = FileOps.deleteDirectory(baseDir);
116: assertTrue("delete directory result", ret);
117: assertEquals("directory exists after deleting it", false,
118: baseDir.exists());
119: }
120:
121: /**
122: * This method checks that backups are made correctly, that when a save fails,
123: * no data is lost, and that when a save is attempted on a write-protected file,
124: * the save fails (bug #782963).
125: */
126: public void testSaveFile() throws IOException {
127: File writeTo = File.createTempFile("fileops", ".test")
128: .getCanonicalFile();
129: writeTo.deleteOnExit();
130: File backup = new File(writeTo.getPath() + "~");
131:
132: FileOps.saveFile(new FileOps.DefaultFileSaver(writeTo) {
133: public void saveTo(OutputStream os) throws IOException {
134: String output = "version 1";
135: os.write(output.getBytes());
136: }
137:
138: public boolean shouldBackup() {
139: return false;
140: }
141: });
142: assertEquals("save w/o backup", "version 1", FileOps
143: .readFileAsString(writeTo));
144: assertEquals("save w/o backup did not backup", false, backup
145: .exists());
146:
147: FileOps.saveFile(new FileOps.DefaultFileSaver(writeTo) {
148: public void saveTo(OutputStream os) throws IOException {
149: String output = "version 2";
150: os.write(output.getBytes());
151: }
152: });
153: assertEquals("save2 w backup", "version 2", FileOps
154: .readFileAsString(writeTo));
155: assertEquals("save2 w backup did backup", "version 1", FileOps
156: .readFileAsString(backup));
157:
158: FileOps.saveFile(new FileOps.DefaultFileSaver(writeTo) {
159: public void saveTo(OutputStream os) throws IOException {
160: String output = "version 3";
161: os.write(output.getBytes());
162: }
163: });
164: assertEquals("save3 w backup on", "version 3", FileOps
165: .readFileAsString(writeTo));
166: assertEquals("save3 w backup on did not backup", "version 1",
167: FileOps.readFileAsString(backup));
168:
169: /* Now see what happens when saving fails and we were not making a backup. Nothing should change. */
170: try {
171: FileOps.saveFile(new FileOps.DefaultFileSaver(writeTo) {
172: public void saveTo(OutputStream os) throws IOException {
173: String output = "version 4";
174: os.write(output.getBytes());
175: throw new IOException();
176: }
177: });
178: fail("IOException not propagated");
179: } catch (IOException ioe) {
180: }//do nothing, this is expected
181: assertEquals("failed save4 w/o backup", "version 3", FileOps
182: .readFileAsString(writeTo));
183: assertEquals("failed save4 w/o backup check original backup",
184: "version 1", FileOps.readFileAsString(backup));
185:
186: /* Now see what happens when saving fails and we were making a backup */
187: try {
188: FileOps.saveFile(new FileOps.DefaultFileSaver(writeTo) {
189: public boolean shouldBackup() {
190: return true;
191: }
192:
193: public void saveTo(OutputStream os) throws IOException {
194: String output = "version 5";
195: os.write(output.getBytes());
196: throw new IOException();
197: }
198: });
199: fail("IOException not propagated spot 2");
200: } catch (IOException ioe) {
201: } //do nothing, we expected this
202: assertEquals("failed save5 w backup", "version 3", FileOps
203: .readFileAsString(writeTo));
204:
205: // Make sure that the backup file no longer exists since it was copied over the original
206: try {
207: FileOps.readFileAsString(backup);
208: fail("The backup file should no longer exist.");
209: } catch (FileNotFoundException e) {
210: } //do nothing, we expected this
211:
212: // Test that save fails if the file is write-protected.
213: writeTo.setReadOnly();
214: try {
215: FileOps.saveFile(new FileOps.DefaultFileSaver(writeTo) {
216: public boolean shouldBackup() {
217: return true;
218: }
219:
220: public void saveTo(OutputStream os) throws IOException {
221: String output = "version 6";
222: os.write(output.getBytes());
223: }
224: });
225: fail("The file to be saved was read-only!");
226: } catch (IOException ioe) {
227: } //do nothing, we expected this
228: assertEquals("failed save6 w backup", "version 3", FileOps
229: .readFileAsString(writeTo));
230:
231: // Make sure that the backup file still doesn't exist since the file
232: // was read-only.
233: try {
234: FileOps.readFileAsString(backup);
235: fail("The backup file should no longer exist.");
236: } catch (FileNotFoundException e) {
237: } //do nothing, we expected this
238: }
239:
240: /**
241: * This tests that packageExplore correctly runs through and returns
242: * non-empty packages
243: */
244: public void testPackageExplore() throws IOException {
245: File rootDir = FileOps.createTempDirectory("fileOpsTest");
246: File subDir0 = new File(rootDir, "sub0");
247: subDir0.mkdir();
248: File subDir1 = new File(rootDir, "sub1");
249: subDir1.mkdir();
250: File subsubDir0 = new File(subDir0, "subsub0");
251: subsubDir0.mkdir();
252: File javasubsub = new File(subsubDir0, "aclass.java");
253: FileOps.writeStringToFile(javasubsub,
254: "contents of this file are unimportant");
255: File javasub1 = new File(subDir1, "myclass.java");
256: FileOps.writeStringToFile(javasub1,
257: "this file is pretty much empty");
258: File javaroot = new File(rootDir, "someclass.java");
259: FileOps.writeStringToFile(javaroot,
260: "i can write anything i want here");
261:
262: LinkedList packages = FileOps.packageExplore("hello", rootDir);
263: assertEquals("package count a", 3, packages.size());
264: assertTrue("packages contents a0", packages
265: .contains("hello.sub0.subsub0"));
266: assertTrue("packages contents a1", packages
267: .contains("hello.sub1"));
268: assertTrue("packages contents a2", packages.contains("hello"));
269:
270: //Now add a .java file to the root directory and check that the default directory
271: //is not added
272: packages = FileOps.packageExplore("", rootDir);
273: assertEquals("package count b", 2, packages.size());
274: assertTrue("packages contents b0", packages
275: .contains("sub0.subsub0"));
276: assertTrue("packages contents b1", packages.contains("sub1"));
277:
278: assertTrue("deleting temp directory", FileOps
279: .deleteDirectory(rootDir));
280: }
281:
282: /** Tests that non-empty directories can be deleted on exit. */
283: public void xtestDeleteDirectoryOnExit() throws IOException,
284: InterruptedException {
285:
286: File tempDir = FileOps.createTempDirectory("DrJavaTestTempDir");
287: assertTrue("tempDir exists", tempDir.exists());
288: File dir1 = new File(tempDir, "dir1");
289: dir1.mkdir();
290: assertTrue("dir1 exists", dir1.exists());
291: assertTrue("dir1 is directory", dir1.isDirectory());
292: File file1 = new File(dir1, "file1");
293: file1.createNewFile(); // Should always succeed because dir1 was just created
294: assertTrue("file1 exists", file1.exists());
295: File dir2 = new File(dir1, "dir2");
296: dir2.mkdir();
297: assertTrue("dir2 exists", dir2.exists());
298: assertTrue("dir2 is directory", dir1.isDirectory());
299: File file2 = new File(dir2, "file2");
300: file2.createNewFile();
301: assertTrue("file2 exists", file2.exists());
302:
303: String className = "edu.rice.cs.util.FileOpsTest";
304: String[] args = new String[] { dir1.getAbsolutePath() }; // args = {<Fully qualified name of dir1>}
305:
306: Process process = ExecJVM.runJVMPropagateClassPath(className,
307: args, FileOption.NULL_FILE);
308: int status = process.waitFor();
309: assertEquals("Delete on exit test exited with an error!", 0,
310: status);
311:
312: assertTrue("dir1 should be deleted", !dir1.exists());
313: assertTrue("file1 should be deleted", !file1.exists());
314: assertTrue("dir2 should be deleted", !dir2.exists());
315: assertTrue("file2 should be deleted", !file2.exists());
316: /* If this test passes, tempDir should be deleted when the this JVM exits. */
317: }
318:
319: public void testSplitFile() {
320: String[] parts = new String[] { "", "home", "username", "dir" };
321: String path1 = "";
322: for (String s : parts) {
323: path1 += s + File.separator;
324: }
325:
326: File f = new File(path1);
327: String[] res = FileOps.splitFile(f);
328:
329: assertTrue("Inconsitent results. Expected "
330: + java.util.Arrays.asList(parts).toString()
331: + ", but found "
332: + java.util.Arrays.asList(res).toString(),
333: java.util.Arrays.equals(parts, res));
334: }
335:
336: private String fixPathFormat(String s) {
337: return s.replace('\\', '/');
338: }
339:
340: public void testMakeRelativeTo() throws IOException,
341: SecurityException {
342: File base, abs;
343:
344: base = new File("src/test1/test2/file.txt");
345: abs = new File("built/test1/test2/file.txt");
346: assertEquals("Wrong Relative Path 1",
347: "../../../built/test1/test2/file.txt",
348: fixPathFormat(FileOps.makeRelativeTo(abs, base)
349: .getPath()));
350: base = new File("file.txt");
351: abs = new File("built/test1/test2/file.txt");
352: assertEquals("Wrong Relative Path 2",
353: "built/test1/test2/file.txt", fixPathFormat(FileOps
354: .makeRelativeTo(abs, base).getPath()));
355: base = new File("built/test1/test2test/file.txt");
356: abs = new File("built/test1/test2/file.txt");
357: assertEquals("Wrong Relative Path 3", "../test2/file.txt",
358: fixPathFormat(FileOps.makeRelativeTo(abs, base)
359: .getPath()));
360: base = new File("file.txt");
361: abs = new File("test.txt");
362: assertEquals("Wrong Relative Path 4", "test.txt",
363: fixPathFormat(FileOps.makeRelativeTo(abs, base)
364: .getPath()));
365: }
366:
367: /** Main method to be called by testDeleteDirectoryOnExit. Runs in a new JVM so the files can be deleted.
368: * Exits with status 1 if wrong number of arguments. Exits with status 2 if file doesn't exist
369: * @param args should contain the file name of the directory to delete on exit
370: */
371: public static void main(String[] args) {
372: if (args.length != 1)
373: System.exit(1);
374:
375: File dir = new File(args[0]);
376: if (!dir.exists())
377: System.exit(2);
378: FileOps.deleteDirectoryOnExit(dir);
379:
380: // OK, exit cleanly
381: System.exit(0);
382: }
383:
384: public void testConvertToAbsolutePathEntries() {
385: String ud = System.getProperty("user.dir");
386: String f = System.getProperty("file.separator");
387: String p = System.getProperty("path.separator");
388: String expected, actual, input;
389:
390: input = "." + p + "drjava" + p + p + f + "home" + f + "foo" + f
391: + "junit.jar";
392: expected = ud
393: + f
394: + "."
395: + p
396: + ud
397: + f
398: + "drjava"
399: + p
400: + ud
401: + p
402: + (new File(f + "home" + f + "foo" + f + "junit.jar"))
403: .getAbsolutePath();
404: actual = FileOps.convertToAbsolutePathEntries(input);
405: assertEquals(
406: "testConvertToAbsolutePathEntries for several paths failed, input = '"
407: + input + "', expected = '" + expected
408: + "', actual = '" + actual + "'", expected,
409: actual);
410: input = "";
411: expected = ud;
412: actual = FileOps.convertToAbsolutePathEntries(input);
413: assertEquals(
414: "testConvertToAbsolutePathEntries for empty path failed, input = '"
415: + input + "', expected = '" + expected
416: + "', actual = '" + actual + "'", expected,
417: actual);
418: input = p + p + p + ".";
419: expected = ud + p + ud + p + ud + p + ud + f + ".";
420: actual = FileOps.convertToAbsolutePathEntries(input);
421: assertEquals(
422: "testConvertToAbsolutePathEntries for several empty paths failed, input = '"
423: + input + "', expected = '" + expected
424: + "', actual = '" + actual + "'", expected,
425: actual);
426: input = p + p;
427: expected = ud + p + ud + p + ud;
428: actual = FileOps.convertToAbsolutePathEntries(input);
429: assertEquals(
430: "testConvertToAbsolutePathEntries for trailing empty paths failed, input = '"
431: + input + "', expected = '" + expected
432: + "', actual = '" + actual + "'", expected,
433: actual);
434: }
435:
436: /** Tests getFilesInDir. */
437: public void testGetFiles() throws IOException {
438: File dir1 = FileOps.createTempDirectory("DrJavaTestTempDir");
439: assertTrue("dir1 exists", dir1.exists());
440: File file1a = File.createTempFile("DrJavaTest-", ".temp", dir1)
441: .getCanonicalFile();
442: assertTrue("file1a exists", file1a.exists());
443: File file1b = File.createTempFile("DrJava-", ".temp", dir1)
444: .getCanonicalFile();
445: assertTrue("file1b exists", file1b.exists());
446: File dir2 = FileOps.createTempDirectory("DrJavaTestDir-", dir1)
447: .getCanonicalFile();
448: assertTrue("dir2 exists", dir2.exists());
449: File file2 = File.createTempFile("DrJavaTest-", ".temp", dir2)
450: .getCanonicalFile();
451: assertTrue("file2 exists", file2.exists());
452:
453: FileFilter ff = new FileFilter() {
454: public boolean accept(File f) {
455: if (f.isDirectory())
456: return true;
457: String name = f.getName();
458: return name.startsWith("DrJavaTest");
459: }
460: };
461:
462: Set<File> res1 = new TreeSet<File>(Arrays
463: .asList(new File[] { file1a }));
464: Set<File> res2 = new TreeSet<File>(Arrays.asList(new File[] {
465: file1a, file2 }));
466:
467: Set<File> nrfiles = new TreeSet<File>();
468: for (File f : FileOps.getFilesInDir(dir1, false, ff)) {
469: nrfiles.add(f.getCanonicalFile());
470: }
471:
472: Set<File> rfiles = new TreeSet<File>();
473: for (File f : FileOps.getFilesInDir(dir1, true, ff)) {
474: rfiles.add(f.getCanonicalFile());
475: }
476:
477: assertEquals("non-recursive FilesInDir test", res1, nrfiles);
478: assertEquals("recursive FileInDir test", res2, rfiles);
479: }
480: }
|