001 /*
002 * AbstractTestVersionControl.java
003 * Copyright (c) 1998-2008, The University of Sheffield.
004 *
005 * This code is from the GATE project (http://gate.ac.uk/) and is free
006 * software licenced under the GNU General Public License version 3. It is
007 * distributed without any warranty. For more details see COPYING.txt in the
008 * top level directory (or at http://gatewiki.sf.net/COPYING.txt).
009 *
010 * Hamish Cunningham 8/Sep/2005
011 */
012
013 package gate.versioning.cmdline;
014
015 import java.net.*;
016 import java.io.*;
017 import junit.framework.*;
018 import gate.util.*;
019
020 /**
021 * Tests for version control API.
022 */
023 abstract public class AbstractTestVersionControl extends TestCase {
024
025 protected String testsDirName = "/gate/versioncontrol/tests";
026 protected URL testDirURL = this.getClass().getResource(testsDirName);
027 protected String checkedOutDirName = "test";
028 protected String testFileName = "test.yam";
029 protected String testDirPath;
030 protected File rootDir;
031 protected File workingDir;
032 protected File checkedOutDir;
033 protected File newRootDir;
034 protected boolean DEBUG = false;
035 protected Repository rep;
036
037 /** What type of repository implementation to use. */
038 abstract protected String getRepType();
039
040 /** Basename of the repository directory. */
041 abstract protected String getRootName();
042
043 /** Prefix of the repository directory (e.g. "file:///") or "". */
044 abstract protected String getRootPrefix();
045
046 public AbstractTestVersionControl(String name) { super(name); }
047
048 /** Create new repository object for testing */
049 public void setUp() throws
050 IOException, UnsupportedEncodingException, GateException,
051 ClassNotFoundException, InstantiationException, IllegalAccessException
052 {
053 // repository root and working dir
054 assertNotNull("Couldn't find resource " + testsDirName, testDirURL);
055 testDirPath = URLDecoder.decode(testDirURL.getPath(), "UTF-8");
056 rootDir = new File(testDirPath + File.separator + getRootName());
057 workingDir = new File(testDirPath + File.separator + "checkout");
058 checkedOutDir = new File(testDirPath + "/checkout/" + checkedOutDirName);
059 newRootDir =
060 new File(testDirPath + File.separator + "new-" + getRootName());
061
062 if(DEBUG) {
063 Out.prln("testDirURL: " + testDirURL);
064 Out.prln("testDirPath: " + testDirPath);
065 Out.prln("workingDir: " + workingDir);
066 Out.prln("rootDir: " + rootDir);
067 Out.prln("checkedOutDir: " + checkedOutDir);
068 Out.prln("newRootDir: " + newRootDir);
069 }
070
071 // create a repository
072 rep = (Repository) Class.forName(getRepType()).newInstance();
073 rep.setRoot(getRootPrefix() + rootDir.getCanonicalPath());
074 rep.setWorkingDir(workingDir);
075 rep.init();
076 } // setUp
077
078 /** Test initialisation */
079 public void testInit() {
080 rep.setWorkingDir(new File("/a/directory/which/does not/exist"));
081 try {
082 rep.init();
083 } catch(GateException e) {
084 return;
085 }
086 fail("rep.init() failed to throw exception on non-existent dir");
087 } // testInit()
088
089 public void testCheckout() {
090 // checkout the test directory
091 boolean checkoutResult = rep.checkout(checkedOutDirName);
092 if(DEBUG) Out.prln(rep.getCommandOutput());
093 assertTrue(
094 "test dir not checked out from rep : " + rep.getCommandOutput(),
095 checkoutResult
096 );
097 assertTrue(checkedOutDir.exists() && checkedOutDir.isDirectory());
098 File checkedOutFile = new File(checkedOutDir, testFileName);
099 assertTrue(checkedOutFile.exists() && ! checkedOutFile.isDirectory());
100
101 // try to checkout a nonexistent directory
102 assertFalse("nonexistent dir co'd from rep", rep.checkout("zxczxc"));
103 File notCheckedOutDir = new File(testDirPath + "/checkout/zxczxc");
104 assertFalse(notCheckedOutDir.exists());
105 } // testCheckout()
106
107 public void testDiffAndCheckin() throws Exception {
108 assertFalse(
109 "starting testDiff but checkedOutDir exists: " + checkedOutDir.getPath(),
110 checkedOutDir.exists()
111 );
112
113 // checkout the test directory
114 boolean checkoutResult = rep.checkout(checkedOutDirName);
115 assertTrue(
116 "test dir not checked out: " + rep.getCommandOutput(),
117 checkoutResult
118 );
119 assertTrue(checkedOutDir.exists() && checkedOutDir.isDirectory());
120
121 // append a line to the test file
122 // File checkedOutFile = new File(checkedOutDir, testFileName);
123 // FileOutputStream fileOutStr = new FileOutputStream(checkedOutFile, true);
124 // PrintWriter filePrinter = new PrintWriter(fileOutStr, true);
125 // filePrinter.println("a new line");
126 // filePrinter.flush();
127 // filePrinter.close();
128 // fileOutStr.flush();
129 // fileOutStr.close();
130 // checkedOutFile = null;
131 // fileOutStr = null;
132 // filePrinter = null;
133 // Thread.currentThread().sleep(2000);\
134 File checkedOutFile = appendToTestFile();
135 if(DEBUG) {
136 Out.prln(checkedOutFile.getPath());
137 Out.prln(Files.getString(checkedOutFile));
138 }
139
140 // check that the new line is in the diffs from the repository version
141 // note that cvs may barf on \ in paths here :-(, so the following breaks:
142 // String diff = rep.diff(checkedOutFile.getPath());
143 String diff = rep.diff(checkedOutDirName + "/" + testFileName);
144 assertNotNull("null diff: " + rep.getCommandOutput(), diff);
145 assertTrue(
146 "incorrect difference (no new line): " + diff,
147 // hacky way to cater for both CVS and SVN diff styles
148 diff.indexOf("> a new line") != -1 || diff.indexOf("+a new line") != -1
149 );
150
151 // check in the file
152 boolean checkinResult =
153 rep.checkin(checkedOutDirName + "/" + testFileName);
154 assertTrue("checkin failed: " + rep.getCommandOutput(), checkinResult);
155
156 // check that there's now no difference
157 diff = rep.diff(checkedOutDirName + "/" + testFileName);
158 assertNotNull("null diff: " + rep.getCommandOutput(), diff);
159 assertTrue(
160 "incorrect difference (should be none): " + diff, diff.equals("")
161 );
162 } // testDiffAndCheckin()
163
164 public void testUpdate() {
165 // checkout the test directory
166 boolean checkoutResult = rep.checkout(checkedOutDirName);
167
168 // delete the test file and check it doesn't exist
169 File checkedOutFile = new File(checkedOutDir, testFileName);
170 checkedOutFile.delete();
171 assertFalse(checkedOutFile.exists());
172
173 // update the test file and check it exists
174 boolean updateResult = rep.update(checkedOutDirName + "/" + testFileName);
175 assertTrue(
176 "test file not updated: " + rep.getCommandOutput(), updateResult
177 );
178 checkedOutFile = new File(checkedOutDir, testFileName);
179 assertTrue(
180 "test file doesn't exist or is not a file: " + rep.getCommandOutput(),
181 checkedOutFile.exists() && ! checkedOutFile.isDirectory()
182 );
183 } // testUpdate()
184
185 public void testStatus() {
186 // checkout the test directory
187 boolean checkoutResult = rep.checkout(checkedOutDirName);
188
189 // get status of test file
190 File checkedOutFile = new File(checkedOutDir, testFileName);
191 String status = rep.status(checkedOutDirName + "/" + testFileName);
192 } // testStatus()
193
194 public void testAddAndDelete() {
195 // checkout the test dir
196 boolean result = rep.checkout(checkedOutDirName);
197
198 // move the test file to a new name and delete it
199 File checkedOutFile = new File(checkedOutDir, testFileName);
200 File newTestFile = new File(checkedOutDir, "new-test.yam");
201 checkedOutFile.renameTo(newTestFile);
202 assertFalse(
203 "moved file exists: " + checkedOutFile, checkedOutFile.exists()
204 );
205 result = rep.delete(checkedOutDirName + "/" + testFileName);
206 assertTrue("couldn't delete file: " + rep.getCommandOutput(), result);
207 result = rep.checkin(checkedOutDirName + "/" + testFileName);
208 assertTrue(
209 "couldn't check in deleted file: " + rep.getCommandOutput(), result
210 );
211
212 // add the test file under the new name
213 result = rep.add(checkedOutDirName + "/" + "new-test.yam");
214 assertTrue("couldn't add new file: " + rep.getCommandOutput(), result);
215 result = rep.checkin(checkedOutDirName + "/" + "new-test.yam");
216 assertTrue(
217 "couldn't check in added file: " + rep.getCommandOutput(), result
218 );
219
220 // move it back for other tests to use
221 checkedOutFile = new File(checkedOutDir, testFileName);
222 newTestFile = new File(checkedOutDir, "new-test.yam");
223 newTestFile.renameTo(checkedOutFile);
224 assertFalse("moved file exists: " + newTestFile, newTestFile.exists());
225 result = rep.delete(checkedOutDirName + "/" + "new-test.yam");
226 assertTrue("couldn't delete file: " + rep.getCommandOutput(), result);
227 result = rep.checkin(checkedOutDirName + "/" + "new-test.yam");
228 assertTrue(
229 "couldn't check in deleted file: " + rep.getCommandOutput(), result
230 );
231 result = rep.add(checkedOutDirName + "/" + testFileName);
232 assertTrue("couldn't add new file: " + rep.getCommandOutput(), result);
233 result = rep.checkin(checkedOutDirName + "/" + testFileName);
234 assertTrue(
235 "couldn't check in added file: " + rep.getCommandOutput(), result
236 );
237 } // testAddAndDelete()
238
239 public void testCreate() throws GateException {
240 newRootDir =
241 new File(testDirPath + File.separator + "new-" + getRootName());
242 boolean result = rep.create(newRootDir.getPath());
243 assertTrue(
244 "new repository not created: " + rep.getCommandOutput(), result
245 );
246 assertTrue(newRootDir.exists() && newRootDir.isDirectory());
247 } // testCreate()
248
249 /**
250 *
251 * @throws Exception
252 */
253 public void testStatusIndicators() throws Exception {
254 checkOutTestDir();
255 String checkedOutFileName = checkedOutDirName + "/" + testFileName;
256 assertFalse("test file is modified", rep.isModified(checkedOutFileName));
257 assertFalse("test file out of date", rep.isOutOfDate(checkedOutFileName));
258 assertFalse("test file is unknown", rep.isUnknown(checkedOutFileName));
259
260 File testFile = appendToTestFile();
261 assertTrue("test file not modified", rep.isModified(checkedOutFileName));
262 assertTrue(
263 "non-existent file not unknown",
264 rep.isUnknown("non-existent-------")
265 );
266 assertFalse(
267 "non-existent file modified",
268 rep.isModified("non-existent-------")
269 );
270 assertFalse(
271 "non-existent file out of date",
272 rep.isOutOfDate("non-existent-------")
273 );
274 } // testStatusIndicators
275
276 /**
277 * Test the operation of {@link Repository#importDir(String)}.
278 * @throws GateException
279 */
280 public void testImport() throws Exception {
281 String name = "import-test-" + rep.getCommandName();
282 File homeDir = new File(testDirPath + File.separator + name);
283 if(homeDir.exists()) Files.rmdir(homeDir);
284
285 homeDir = null;
286 // Thread.currentThread().sleep(2000);
287 homeDir = new File(testDirPath + File.separator + name);
288 if(homeDir.exists()) Files.rmdir(homeDir);
289
290 assertFalse(homeDir.getPath() + " still exists", homeDir.exists());
291 homeDir = new File(testDirPath + File.separator + name);
292 if(! homeDir.mkdirs())
293 throw new GateException("couldn't create directory " + homeDir.getPath());
294 assertTrue(
295 homeDir.getPath() + " isn't a dir",
296 homeDir.exists() && homeDir.isDirectory()
297 );
298 boolean status = rep.importDir(homeDir.getPath());
299 if(!status) throw new
300 GateException("import failed: " + rep.getCommandOutput());
301
302 Files.rmdir(homeDir);
303 homeDir = null;
304 // Thread.currentThread().sleep(2000);
305 homeDir = new File(testDirPath + File.separator + name);
306 if(homeDir.exists()) Files.rmdir(homeDir);
307 assertFalse("homeDir still exists", homeDir.exists());
308
309 homeDir = null;
310 // Thread.currentThread().sleep(2000);
311 homeDir = new File(testDirPath + File.separator + name);
312 if(homeDir.exists()) Files.rmdir(homeDir);
313 assertFalse("homeDir still exists", homeDir.exists());
314
315 status = rep.checkout(name);
316 if(!status) throw new
317 GateException("couldn't checkout: " + rep.getCommandOutput());
318 } // testImport()
319
320 /**
321 * Check that testImport can run twice on the same test fixture
322 * without failing.
323 * @throws GateException
324 */
325 public void testImport2() throws Exception {
326 testImport();
327 }
328
329 /**
330 * Check testExists.
331 */
332 public void testExists() throws Exception {
333 checkOutTestDir();
334 assertTrue(
335 "test dir is unknown: " + rep.getCommandOutput(),
336 rep.exists(checkedOutDirName)
337 );
338 assertFalse("unknown dir exists", rep.exists("thing-thing-thing"));
339 }
340
341 /**
342 * Lifecycle test - import, existence, checkout, modify, ...
343 */
344 public void testLifeCycle() throws Exception {
345 // create a new empty directory containing a checkout directory
346 File testDir;
347 testDir = new File("build/test-life-cycle");
348 if(testDir.exists()) Files.rmdir(testDir);
349 testDir = new File("build/test-life-cycle");
350 assertFalse("testDir still exists", testDir.exists());
351 testDir = new File("build/test-life-cycle/checkout");
352 if(! testDir.mkdirs())
353 fail("couldn't create testDir");
354 assertTrue(testDir.exists());
355
356 // create a file in the checkout directory
357 File testFile;
358 testFile = new File(testDir, "test-file.txt");
359 FileOutputStream testFileOS = new FileOutputStream(testFile);
360 PrintWriter testFileBS = new PrintWriter(testFileOS);
361 testFileBS.println("test file line 1");
362 testFileBS.flush();
363 testFileBS.close();
364 testFileOS.flush();
365 testFileOS.close();
366 testFile = null;
367
368 // create a repository root
369 Repository creatorRep =
370 (Repository) Class.forName(getRepType()).newInstance();
371 File rootFile = new File(testDir.getParentFile(), "reproot");
372 creatorRep.create(rootFile.getAbsolutePath());
373 assertTrue("new root doesn't exist", rootFile.exists());
374 rootFile = null;
375 creatorRep = null;
376
377 // create a repository object
378 Repository rep = (Repository) Class.forName(getRepType()).newInstance();
379 rootFile = new File(testDir.getParentFile(), "reproot");
380 rep.setRoot(rootFile.getAbsolutePath());
381 rep.setWorkingDir(testDir);
382 rep.init();
383
384 // check we don't know about non-existent modules
385 assertTrue("non-existent module known by rep", rep.isUnknown("zxczxc"));
386
387 // import the something, check it out....
388
389 } // testLifeCycle()
390
391 /** Delete any checked-out files */
392 public void tearDown() {
393 Files.rmdir(checkedOutDir);
394 assertFalse(
395 "checkedOutDir exists: " + checkedOutDir.getPath(),
396 checkedOutDir.exists()
397 );
398 if(DEBUG) Out.prln("tearDown has deleted " + checkedOutDir.getPath());
399 Files.rmdir(newRootDir);
400 assertFalse(
401 "newRootDir exists: " + newRootDir.getPath(),
402 newRootDir.exists()
403 );
404 } // tearDown()
405
406 /**
407 * Helper function for external users of this class. Check out test dir.
408 * @return Repository the repository.
409 */
410 public Repository checkOutTestDir() throws Exception {
411 boolean checkoutResult = rep.checkout(checkedOutDirName);
412 assertTrue(
413 "test dir not checked out: " + rep.getCommandOutput(),
414 checkoutResult
415 );
416 assertTrue(checkedOutDir.exists() && checkedOutDir.isDirectory());
417
418 return rep;
419 } // checkOutTestDir
420
421 /**
422 * Helper function for external users of this class. Append line to test
423 * file.
424 * @return File the checked out file.
425 */
426 public File appendToTestFile() throws Exception {
427 File checkedOutFile = new File(checkedOutDir, testFileName);
428 long fileSize = checkedOutFile.length();
429 FileOutputStream fileOutStr = new FileOutputStream(checkedOutFile, true);
430 PrintWriter filePrinter = new PrintWriter(fileOutStr, true);
431 filePrinter.println("a new line");
432 filePrinter.flush();
433 filePrinter.close();
434 fileOutStr.flush();
435 fileOutStr.close();
436 if(DEBUG) {
437 Out.prln(checkedOutFile.getPath());
438 Out.prln(Files.getString(checkedOutFile));
439 }
440 assertTrue("File not modified after addition",
441 checkedOutFile.length() > fileSize);
442 return checkedOutFile;
443 } // appendToTestFile
444
445
446 } // AbstractTestVersionControl
|