Index: subversion/bindings/javahl/tests/org/apache/subversion/javahl/RaReadonlyTests.java =================================================================== --- subversion/bindings/javahl/tests/org/apache/subversion/javahl/RaReadonlyTests.java (revision 0) +++ subversion/bindings/javahl/tests/org/apache/subversion/javahl/RaReadonlyTests.java (working copy) @@ -0,0 +1,316 @@ +package org.apache.subversion.javahl; + +import java.util.Collections; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.subversion.javahl.ra.ISVNDirectory; +import org.apache.subversion.javahl.ra.ISVNEditor; +import org.apache.subversion.javahl.ra.ISVNFile; +import org.apache.subversion.javahl.ra.ISVNRa; +import org.apache.subversion.javahl.ra.SVNCommitEditorBuilder; + +/* + * This class contains SVN test and only does initial setup ones + * to avoid creating repository every time when it is not necessary + * as the test in this class do not alter repository state + */ +public class RaReadonlyTests extends TestCase +{ + /** + * Base name of all our tests. + */ + public final static String TEST_NAME = "ra_readonly_test"; + + private SVNTests svnTests; + + public RaReadonlyTests() + { + } + + private SVNTests getSVNTest() + { + /* + * Create svnTests instance on demand, to make sure + * it is done after other tests have run + */ + if(svnTests != null) + { + return svnTests; + } + + svnTests = new SVNTests(); + svnTests.setTestBaseName(TEST_NAME); + + try + { + svnTests.setUp(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + + return svnTests; + } + + private ISVNRa getSession(String url) + { + return RaTests.getSession(url, getSVNTest().getConf().getAbsolutePath()); + } + + public void testEditorAbort() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + assertNotNull(session); + + Map emptyMap = Collections.emptyMap(); + ISVNEditor editor = session.getCommitEditor(emptyMap, null, null, true); + assertNotNull(editor); + + /* + * Test commit abort + */ + editor.abortEdit(); + } + + public void testEditorBadRevProps() throws Exception + { + /* + * Bad client behavior test Bad parameters Editor use after close/abort + * Directory use after close Directory use after parent close Directory + * use before open children are closed File stream use after editor + * close Null revProperties + */ + + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + assertNotNull(session); + + try + { + session.getCommitEditor(null, null, null, true); + fail("RA session should have thrown exception"); + } + catch (JNIError e) + { + } + } + + /* + * Test that opening directories and file and closing Ra session does not + * nuke the JVM + */ + public void testRaObjectsAutoDisposal() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + assertNotNull(session); + + ISVNEditor editor = new SVNCommitEditorBuilder().create(session); + + long baseRevision = 1; + ISVNDirectory dirRoot = editor.openRoot(baseRevision); + ISVNDirectory dirZ = dirRoot.addDirectory("Z"); + dirZ.addDirectory("V"); + ISVNFile fileX = dirZ.addFile("X"); + session.dispose(); + + try + { + dirRoot.addDirectory("Y"); + fail("RA session should have thrown exception when calling methods on disposed directory"); + } + catch (JNIError e) + { + } + + try + { + fileX.changeProperty("A", "B".getBytes()); + fail("RA session should have thrown exception when calling methods on disposed file"); + } + catch (JNIError e) + { + } + + } + + public void testRaDirectoryBadCalls() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + assertNotNull(session); + + Map emptyMap = Collections.emptyMap(); + ISVNEditor editor = session.getCommitEditor(emptyMap, null, null, true); + + long baseRevision = 1; + ISVNDirectory dirRoot = editor.openRoot(baseRevision); + + assertNotNull(dirRoot); + + try + { + dirRoot.addDirectory(null); + fail("RA session should have thrown exception when calling addDirectory with null parameter"); + } catch (NullPointerException e) {} + + try + { + dirRoot.addFile(null); + fail("RA session should have thrown exception when calling addFile with null parameter"); + } catch (NullPointerException e) {} + + try + { + dirRoot.changeProperty(null, null); + fail("RA session should have thrown exception when calling changeProperty with null parameter"); + } catch (NullPointerException e) {} + + try + { + dirRoot.deleteEntry(null, -10); + fail("RA session should have thrown exception when calling DeleteEntry with null parameter"); + } catch (NullPointerException e) {} + + try + { + dirRoot.openDirectory(null, -10); + fail("RA session should have thrown exception when calling openDirectory with null parameter"); + } catch (NullPointerException e) {} + + try + { + dirRoot.openFile(null, -10); + fail("RA session should have thrown exception when calling openFile with null parameter"); + } catch (NullPointerException e) {} + + editor.abortEdit(); + } + + public void testRaFileBadCalls() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + assertNotNull(session); + + Map emptyMap = Collections.emptyMap(); + ISVNEditor editor = session.getCommitEditor(emptyMap, null, null, true); + + long baseRevision = 1; + ISVNDirectory dirRoot = editor.openRoot(baseRevision); + ISVNFile fileX = dirRoot.addFile("X"); + assertNotNull(fileX); + + ISVNFile fileY = dirRoot.addFile("Y"); + assertNotNull(fileY); + + ISVNFile fileZ = dirRoot.addFile("Z"); + assertNotNull(fileZ); + + try + { + fileX.sendDeltaStream(null, null, null); + fail("RA session should have thrown exception when calling sendDeltaStream with null parameter"); + } catch (NullPointerException e) {} + + try + { + fileY.sendStream(null, null); + fail("RA session should have thrown exception when calling addFile with null parameter"); + } catch (NullPointerException e) {} + + try + { + fileZ.changeProperty(null, null); + fail("RA session should have thrown exception when calling changeProperty with null parameter"); + } catch (NullPointerException e) {} + + editor.abortEdit(); + } + + public void testGetRoot() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + + assertEquals(url, session.getRoot()); + } + + public void testGetLatestRevision() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + + assertEquals(1, session.getLatestRevision()); + } + + public void testGetUrl() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + + assertEquals(url, session.getUrl()); + } + + public void testGetUUID() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + /* + * Test UUID + */ + assertNotNull(session.getUUID()); + } + + public void testReparent() throws Exception + { + String url = getSVNTest().getGreeksRepoUrl(); + ISVNRa session = getSession(url); + + /* + * Test null reparent + */ + try + { + session.reparent(null); + fail("RA session should have thrown exception"); + } + catch (JNIError e) + { + } + + /* + * Test bad reparent + */ + + /* + * FIXME: Running this results in assertion java: + * subversion/libsvn_subr/dirent_uri.c:1483: uri_skip_ancestor: + * Assertion `svn_uri_is_canonical(child_uri, ((void *)0))' failed. + * Should be fixed as we never know what the caller might pass and take + * down JVM + */ + // session.reparent("BAD"); + + try + { + session.reparent("file:///dev/null"); + } + catch (Exception e) + { + } + + /* + * Test reparent + */ + session.reparent(url + "/A"); + assertEquals(url + "/A", session.getUrl()); + session.reparent(url); + assertEquals(url, session.getUrl()); + + } +} Index: subversion/bindings/javahl/tests/org/apache/subversion/javahl/RaTests.java =================================================================== --- subversion/bindings/javahl/tests/org/apache/subversion/javahl/RaTests.java (revision 0) +++ subversion/bindings/javahl/tests/org/apache/subversion/javahl/RaTests.java (working copy) @@ -0,0 +1,605 @@ +package org.apache.subversion.javahl; + +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.subversion.javahl.callback.CommitCallback; +import org.apache.subversion.javahl.callback.InfoCallback; +import org.apache.subversion.javahl.callback.LogMessageCallback; +import org.apache.subversion.javahl.callback.ProgressCallback; +import org.apache.subversion.javahl.ra.ISVNDirectory; +import org.apache.subversion.javahl.ra.ISVNEditor; +import org.apache.subversion.javahl.ra.ISVNFile; +import org.apache.subversion.javahl.ra.ISVNRa; +import org.apache.subversion.javahl.ra.SVNCommitEditorBuilder; +import org.apache.subversion.javahl.ra.SVNRaConfigDefault; +import org.apache.subversion.javahl.ra.SVNRaFactory; +import org.apache.subversion.javahl.types.ChangePath; +import org.apache.subversion.javahl.types.Depth; +import org.apache.subversion.javahl.types.Info; +import org.apache.subversion.javahl.types.NodeKind; +import org.apache.subversion.javahl.types.Property; +import org.apache.subversion.javahl.types.Revision; +import org.apache.subversion.javahl.types.RevisionRange; +import org.apache.subversion.javahl.types.Tristate; + +public class RaTests extends SVNTests +{ + /** + * Base name of all our tests. + */ + public final static String TEST_NAME = "ra_test"; + private final static String DIR_PROPERTY_NAME = "dirTest"; + private final static String FILE_PROPERTY_NAME = "fileTest"; + + private final static String DIR_WITH_PROPERTY_CHANGE = "/A/B/E/I"; + private final static String FILE_WITH_PROPERTY_CHANGE = "/A/B/E/epsilon"; + + private final static byte[] PROPERTY_VALUE; + + static + { + try + { + PROPERTY_VALUE = "success".getBytes("UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException(e); + + } + } + + public RaTests() + { + super(); + + if (!TEST_NAME.equals(testBaseName)) + { + testCounter = 0; + testBaseName = TEST_NAME; + } + } + + public static ISVNRa getSession(String url, String configDirectory) + { + SVNRaConfigDefault config = new SVNRaConfigDefault(); + config.setUsername(USERNAME); + config.setPassword(PASSWORD); + config.setPrompt(new DefaultPromptUserPassword()); + config.setConfigDirectory(configDirectory); + + ISVNRa raSession = SVNRaFactory.createRaSession(url, null, config); + + assertNotNull("Null session was returned by factory", raSession); + + return raSession; + } + + private ISVNRa getSession(String url) + { + return getSession(url, super.conf.getAbsolutePath()); + } + + public void testEditorClose() throws Exception + { + OneTest thisTest = new OneTest(false); + + String url = thisTest.getUrl().toString(); + //url = "svn://localhost"; + + ISVNRa session = getSession(url); + + assertNotNull(session); + + /* + * Setup callbacks + */ + final AtomicReference refCommitInfo = new AtomicReference(); + + CommitCallback testCommitCallback = new CommitCallback() + { + @Override + public void commitInfo(CommitInfo info) + { + refCommitInfo.set(info); + } + }; + + final AtomicBoolean progressListenerCalled = new AtomicBoolean(false); + + ProgressCallback progressListener = new ProgressCallback() + { + + @Override + public void onProgress(ProgressEvent event) + { + progressListenerCalled.set(true); + } + }; + session.setProgressCallback(progressListener); + final String logMessage = "RA Editor Test Commit"; + + ISVNEditor editor = new SVNCommitEditorBuilder() + .setCommitCallback(testCommitCallback) + .setCommitMessage(logMessage) + .keepLocks() + .create(session); + + assertNotNull(editor); + + /* + * Test commit editor functions: + * Root open + * Directory add + * Directory open + * Directory delete + * Directory property change + * Directory close + * File Add + * File Open + * File delete + * File (full stream) + * File (delta stream) + * File property change + * File close + */ + final long baseRevision = 1; + final long newRevision = baseRevision + 1; + + /* + * Open root + */ + ISVNDirectory directoryRoot = editor.openRoot(baseRevision); + + assertNotNull(directoryRoot); + + /* + * Open Directories + */ + ISVNDirectory directoryA = directoryRoot.openDirectory("A", baseRevision); + assertNotNull(directoryA); + + ISVNDirectory directoryB = directoryA.openDirectory("A/B", baseRevision); + assertNotNull(directoryB); + + ISVNDirectory directoryE = directoryB.openDirectory("A/B/E", baseRevision); + assertNotNull(directoryE); + + /* + * Add directory + */ + ISVNDirectory directoryI = directoryE.addDirectory(DIR_WITH_PROPERTY_CHANGE, url + "/A/D", + baseRevision); + assertNotNull(directoryI); + + /* + * Change directory property + */ + directoryI.changeProperty(DIR_PROPERTY_NAME, PROPERTY_VALUE); + + /* + * Delete directory + */ + directoryI.deleteEntry("A/B/E/I/G", baseRevision); + directoryI.close(); + + /* + * Copy file + */ + ISVNFile fileDeltaCopy = directoryE.addFile("A/B/E/delta", url + "/A/D/G/pi", + baseRevision); + assertNotNull(fileDeltaCopy); + + //Verify that copy md5 checksum is correct + final String piMd5 = "44d43786ca76767c3b57d5c5bfe93299"; + fileDeltaCopy.close(piMd5); + + /* + * Create new file + */ + { + final byte[] epsilonContent = "This is the file 'epsilon'.".getBytes("UTF-8"); + final String epsilonMd5 = "72cf2e20fb7d113b2ed1a353e53cfc71"; + + ISVNFile fileEpsilonNew = directoryE.addFile(FILE_WITH_PROPERTY_CHANGE); + assertNotNull(fileEpsilonNew); + fileEpsilonNew.changeProperty(FILE_PROPERTY_NAME, PROPERTY_VALUE); + + fileEpsilonNew.sendStream( + new ByteArrayInputStream(epsilonContent), + null); + + fileEpsilonNew.close(epsilonMd5); + } + + /* + * Modify existing file + */ + { + final byte[] alphaContentV1 = "This is the file 'alpha'.".getBytes("UTF-8"); + final String alphaV1Md5 = "440bc1eb6bd3fbeefb383cbaa6b02528"; + + final byte[] alphaContentV2 = "This is the file 'alphaV2'.".getBytes("UTF-8"); + final String alphaV2Md5 = "8a49d51be9c13a06de92d7ff53f27524"; + + ISVNFile fileAlphaMod = directoryE.openFile("A/B/E/alpha", baseRevision); + assertNotNull(fileAlphaMod); + + fileAlphaMod.sendDeltaStream(new ByteArrayInputStream(alphaContentV1), + new ByteArrayInputStream(alphaContentV2), alphaV1Md5); + + fileAlphaMod.close(alphaV2Md5); + } + + /* + * Delete file + */ + directoryE.deleteEntry("A/B/E/beta", baseRevision); + + directoryE.close(); + directoryB.close(); + directoryA.close(); + directoryRoot.close(); + + editor.closeEdit(); + + // ### FIXME: This isn't working over ra_local, because + // ### ra_local is not invoking the progress callback. + if (!url.startsWith("file://")) + { + assertTrue("Progress listener called", progressListenerCalled.get()); + } + + /* + * Verify commit info + */ + CommitInfo commitInfo = refCommitInfo.get(); + + assertNotNull("Sucessfull commit should have resulted in commit callback", commitInfo); + + + assertEquals(USERNAME, commitInfo.author); + assertEquals(newRevision, commitInfo.revision); + + /* + * Check that results of editing are as expected + */ + final Map expectedState = getExpectedEditorResults(url, newRevision, baseRevision); + + final AtomicInteger nodesVisited = new AtomicInteger(0); + Revision objNewRevision = Revision.getInstance(newRevision); + + /* + * Confirm expected repository layout + */ + super.client.info2(url, objNewRevision, objNewRevision, Depth.infinity, null, + new InfoCallback() + { + @Override + public void singleInfo(Info info) + { + nodesVisited.incrementAndGet(); + + final String url = info.getUrl(); + NodeAssertInfo assertInfo = expectedState.get(url); + + assertNotNull(String.format("Expected state for url %s not found", url), assertInfo); + + assertEquals("Kind", assertInfo.getKind(), info.getKind()); + assertEquals("Revision", assertInfo.getRevision(), info.getRev()); + } + } + ); + + assertEquals(expectedState.size(), nodesVisited.get()); + + /* + * Confirm copy from paths and text mods + */ + final Set changedPathsSet = new HashSet(); + final Map revPropsMap = new HashMap(); + + super.client.logMessages(url, objNewRevision, + Collections.singletonList(new RevisionRange(objNewRevision, objNewRevision)), false, true, false, + Collections.singleton(Property.REV_LOG), 1, + new LogMessageCallback() + { + @Override + public void singleMessage(Set changedPaths, long revision, + Map revprops, boolean hasChildren) + { + assertEquals(newRevision, revision); + + changedPathsSet.addAll(changedPaths); + + revPropsMap.putAll(revprops); + } + }); + + assertTrue("Changed paths set had no data", changedPathsSet.size() > 0); + assertTrue("revision properties map had no data", revPropsMap.size() > 0); + + assertEquals(logMessage, new String(revPropsMap.get(Property.REV_LOG), "UTF-8")); + + final Map deletedState = getExpectedEditorDeletions(url, newRevision, baseRevision); + + for (ChangePath changePath : changedPathsSet) + { + final String lookupUrl = url + changePath.getPath(); + NodeAssertInfo assertInfo = expectedState.get(lookupUrl); + + if(assertInfo == null) + { + assertInfo = deletedState.get(lookupUrl); + } + + assertNotNull(String.format("Expected state for url %s not found", lookupUrl), assertInfo); + + if(assertInfo.getTextMods() != null) + { + assertEquals(assertInfo.getTextMods(), changePath.getTextMods()); + } + + if(assertInfo.getAction() != null) + { + assertEquals(assertInfo.getAction(), changePath.getAction()); + } + + assertEquals("Copy From URL", assertInfo.getCopyFromUrl(), changePath.getCopySrcPath()); + assertEquals("Copy From Rev", assertInfo.getCopyFromRev(), changePath.getCopySrcRevision()); + } + + final byte[] filePropertyValue = super.client.propertyGet(url + FILE_WITH_PROPERTY_CHANGE, FILE_PROPERTY_NAME, objNewRevision, objNewRevision); + assertTrue("File property", Arrays.equals(PROPERTY_VALUE, filePropertyValue)); + + final byte[] dirPropertyValue = super.client.propertyGet(url + DIR_WITH_PROPERTY_CHANGE, DIR_PROPERTY_NAME, objNewRevision, objNewRevision); + assertTrue("Dir property", Arrays.equals(PROPERTY_VALUE, dirPropertyValue)); + } + + private Map getExpectedEditorDeletions(String url, long newRevision, long baseRevision) + { + final Map expectedState = new HashMap(); + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I/G", NodeKind.dir, newRevision, ChangePath.Action.delete); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/beta", NodeKind.file, newRevision, ChangePath.Action.delete); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + return expectedState; + } + + private Map getExpectedEditorResults(String url, long newRevision, long baseRevision) + { + final Map expectedState = new HashMap(); + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url, NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/iota", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/mu", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/lambda", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/alpha", NodeKind.file, newRevision, ChangePath.Action.modify); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I", NodeKind.dir, newRevision, "/A/D", baseRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I/gamma", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I/H", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I/H/chi", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I/H/omega", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/I/H/psi", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/delta", NodeKind.file, newRevision, "/A/D/G/pi", baseRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/E/epsilon", NodeKind.file, newRevision, ChangePath.Action.add); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/B/F", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/C", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/gamma", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/G", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/G/pi", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/G/rho", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/G/tau", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/H", NodeKind.dir, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/H/chi", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/H/omega", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + { + final NodeAssertInfo nodeInfo = new NodeAssertInfo(url + "/A/D/H/psi", NodeKind.file, newRevision); + expectedState.put(nodeInfo.getUrl(), nodeInfo); + } + + + return expectedState; + } + + private static class NodeAssertInfo + { + private String url; + private NodeKind kind; + private long revision; + private String copyFromUrl; + private long copyFromRev; + private Tristate textMods; + private ChangePath.Action action; + + public NodeAssertInfo(String path, NodeKind kind, long revision) + { + this(path, kind, revision, null, Revision.SVN_INVALID_REVNUM); + } + + public NodeAssertInfo(String path, NodeKind kind, long revision, ChangePath.Action action) + { + this(path, kind, revision, null, Revision.SVN_INVALID_REVNUM, null, action); + } + + public NodeAssertInfo(String path, NodeKind kind, long revision, String copyFromUrl, long copyFromRev) + { + this(path, kind, revision, copyFromUrl, copyFromRev, null, ChangePath.Action.add); + } + + public NodeAssertInfo(String path, NodeKind kind, long revision, String copyFromUrl, long copyFromRev, + Tristate textMods, ChangePath.Action action) + { + this.url = path; + this.kind = kind; + this.revision = revision; + this.copyFromUrl = copyFromUrl; + this.copyFromRev = copyFromRev; + this.textMods = textMods; + this.action = action; + } + + public String getUrl() + { + return url; + } + + public NodeKind getKind() + { + return kind; + } + + public long getRevision() + { + return revision; + } + + public String getCopyFromUrl() + { + return copyFromUrl; + } + + public long getCopyFromRev() + { + return copyFromRev; + } + + public Tristate getTextMods() + { + return textMods; + } + + public ChangePath.Action getAction() + { + return action; + } + } +} Index: subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java =================================================================== --- subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java (revision 1328758) +++ subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java (working copy) @@ -93,6 +93,8 @@ public class RunTests // Add default test suites. suite.addTestSuite(SVNReposTests.class); suite.addTestSuite(BasicTests.class); + suite.addTestSuite(RaTests.class); + suite.addTestSuite(RaReadonlyTests.class); } else {