package org.tmatesoft.svn.test;
import java.io.File;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.db.SVNSqlJetDb;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb;
import org.tmatesoft.svn.core.internal.wc17.db.SVNWCDb;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
public class WorkingCopyRootDetectionTest {
@Before
public void setup() {
Assume.assumeTrue(TestUtil.isNewWorkingCopyTest());
}
@Test
public void testBasics() throws Exception {
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testBasics", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.addDirectory("directory/subdirectory/subsubdirectory");
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final SVNWCDb db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, workingCopyDirectory);
assertRootIsCorrect(workingCopyDirectory, db, new File(workingCopyDirectory, "directory"));
assertRootIsCorrect(workingCopyDirectory, db, new File(workingCopyDirectory, "directory/subdirectory"));
assertRootIsCorrect(workingCopyDirectory, db, new File(workingCopyDirectory, "directory/subdirectory/subsubdirectory"));
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
@Test
public void testVersionedSymlinkToWorkingCopyInsideWorkingCopy() throws Exception {
Assume.assumeTrue(SVNFileUtil.symlinksSupported());
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testVersionedSymlinkToWorkingCopyInsideWorkingCopy", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.addFile("symlink", "link symlinkTarget".getBytes());
commitBuilder.setFileProperty("symlink", SVNProperty.SPECIAL, SVNPropertyValue.create("*"));
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final File symlink = new File(workingCopyDirectory, "symlink");
final File symlinkTarget = new File(workingCopyDirectory, "symlinkTarget");
SVNWCDb db;
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, symlink);
assertRootIsCorrect(workingCopyDirectory, db, symlinkTarget);
} finally {
db.close();
}
final WorkingCopy symlinkTargetWorkingCopy = new WorkingCopy(options, symlinkTarget);
symlinkTargetWorkingCopy.checkoutLatestRevision(url);
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, symlink); //symlink still belongs to the parent repository
assertRootIsCorrect(symlinkTarget, db, symlinkTarget);
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
@Test
public void testUnversionedSymlinkToWorkingCopyInsideWorkingCopy() throws Exception {
Assume.assumeTrue(SVNFileUtil.symlinksSupported());
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testUnversionedSymlinkToWorkingCopyInsideWorkingCopy", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final File symlink = new File(workingCopyDirectory, "symlink");
final File symlinkTarget = new File(workingCopyDirectory, "symlinkTarget");
SVNFileUtil.createSymlink(symlink, symlinkTarget.getAbsolutePath());
SVNWCDb db;
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, symlink);
assertRootIsCorrect(workingCopyDirectory, db, symlinkTarget);
} finally {
db.close();
}
final WorkingCopy symlinkTargetWorkingCopy = new WorkingCopy(options, symlinkTarget);
symlinkTargetWorkingCopy.checkoutLatestRevision(url);
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(symlink, db, symlink); //symlink is the working copy root itself now
assertRootIsCorrect(symlinkTarget, db, symlinkTarget);
} finally {
db.close();
}
//here we check that cached roots have no influence on working copy root detection
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, workingCopyDirectory); //spoil the cache
assertRootIsCorrect(symlink, db, symlink); //symlink is the working copy root itself now
assertRootIsCorrect(symlinkTarget, db, symlinkTarget);
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
@Test
public void testUnversionedSymlinkInsideWorkingCopyToUnversionedDirectory() throws Exception {
Assume.assumeTrue(SVNFileUtil.symlinksSupported());
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testUnversionedSymlinkInsideWorkingCopyToUnversionedDirectory", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final File symlink = new File(workingCopyDirectory, "symlink");
final File symlinkTarget = sandbox.createDirectory("unversionedDirectory");
SVNFileUtil.createSymlink(symlink, symlinkTarget.getAbsolutePath());
SVNWCDb db;
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, symlink);
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
@Test
public void testUnversionedSymlinkInsideWorkingCopyToUnversionedDirectoryInsideWorkingCopy() throws Exception {
Assume.assumeTrue(SVNFileUtil.symlinksSupported());
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testUnversionedSymlinkInsideWorkingCopyToUnversionedDirectoryInsideWorkingCopy", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final WorkingCopy anotherWorkingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File unversionedDirectory = new File(anotherWorkingCopy.getWorkingCopyDirectory(), "unversionedDirectory");
SVNFileUtil.ensureDirectoryExists(unversionedDirectory);
final File symlink = new File(workingCopyDirectory, "symlink");
final File symlinkTarget = unversionedDirectory;
SVNFileUtil.createSymlink(symlink, symlinkTarget.getAbsolutePath());
SVNWCDb db;
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, symlink);
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
@Test
public void testUnversionedSymlinkInsideWorkingCopyToVersionedDirectoryInsideWorkingCopy() throws Exception {
Assume.assumeTrue(SVNFileUtil.symlinksSupported());
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testUnversionedSymlinkInsideWorkingCopyToVersionedDirectoryInsideWorkingCopy", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.addDirectory("versionedDirectory");
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final WorkingCopy anotherWorkingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File versionedDirectory = new File(anotherWorkingCopy.getWorkingCopyDirectory(), "versionedDirectory");
final File symlink = new File(workingCopyDirectory, "symlink");
final File symlinkTarget = versionedDirectory;
SVNFileUtil.createSymlink(symlink, symlinkTarget.getAbsolutePath());
SVNWCDb db;
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(workingCopyDirectory, db, symlink);
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
@Test
public void testSymlinkToWorkingCopyBeyondWorkingCopy() throws Exception {
Assume.assumeTrue(SVNFileUtil.symlinksSupported());
final TestOptions options = TestOptions.getInstance();
final SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
final Sandbox sandbox = Sandbox.createWithCleanup(getTestName() + ".testSymlinkToWorkingCopyBeyondWorkingCopy", options);
try {
final SVNURL url = sandbox.createSvnRepository();
final CommitBuilder commitBuilder = new CommitBuilder(url);
commitBuilder.addDirectory("versionedDirectory");
commitBuilder.commit();
final WorkingCopy workingCopy = sandbox.checkoutNewWorkingCopy(url, SVNRevision.HEAD.getNumber());
final File workingCopyDirectory = workingCopy.getWorkingCopyDirectory();
final File symlink = new File(sandbox.createDirectory("directory"), "symlink");
SVNFileUtil.createSymlink(symlink, workingCopyDirectory.getAbsolutePath());
SVNWCDb db;
db = createSVNWCDb();
db.open(ISVNWCDb.SVNWCDbOpenMode.ReadOnly, SVNWCUtil.createDefaultOptions(true), false, true);
try {
assertRootIsCorrect(symlink, db, symlink);
assertRootIsCorrect(symlink, db, new File(symlink, "versionedDirectory"));
} finally {
db.close();
}
} finally {
svnOperationFactory.dispose();
sandbox.dispose();
}
}
private void assertRootIsCorrect(File expectedRoot, SVNWCDb db, File path) throws SVNException {
expectedRoot = new File(expectedRoot.getAbsolutePath().replace(File.separatorChar, '/'));
path = new File(path.getAbsolutePath().replace(File.separatorChar, '/'));
final SVNWCDb.DirParsedInfo dirParsedInfo = db.parseDir(path, SVNSqlJetDb.Mode.ReadOnly);
final File actualRoot = dirParsedInfo.wcDbDir.getWCRoot().getAbsPath();
Assert.assertEquals(expectedRoot, actualRoot);
}
private SVNWCDb createSVNWCDb() {
return new SVNWCDb();
}
private String getTestName() {
return "WorkingCopyRootDetectionTest";
}
}