/**
* This file is part of git-as-svn. It is subject to the license terms
* in the LICENSE file found in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn,
* including this file, may be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
package svnserver.server;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import svnserver.SvnTestServer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static svnserver.SvnTestHelper.modifyFile;
import static svnserver.SvnTestHelper.sendDeltaAndClose;
/**
* Check file properties.
*
* @author Artem V. Navrotskiy <bozaro@users.noreply.github.com>
*/
public class SvnGetLocationsTest {
@Test
public void segmentsSimple() throws Exception {
try (SvnTestServer server = SvnTestServer.createEmpty()) {
final SVNRepository repo = server.openSvnRepository();
initRepo(repo);
final long last = repo.getLatestRevision();
checkGetSegments(repo, "/baz/test.txt", last, 5, 3,
"/baz/test.txt@4:5",
"/bar/test.txt@3:3"
);
checkGetSegments(repo, "/baz/test.txt", last, 5, 0,
"/baz/test.txt@4:5",
"/bar/test.txt@2:3",
"/foo/test.txt@1:1"
);
checkGetSegments(repo, "/baz/test.txt", last, 2, 0,
"/bar/test.txt@2:2",
"/foo/test.txt@1:1"
);
checkGetSegments(repo, "/bar/test.txt", 3, 2, 1,
"/bar/test.txt@2:2",
"/foo/test.txt@1:1"
);
checkGetSegments(repo, "/foo/test.txt", 1, 1, 1,
"/foo/test.txt@1:1"
);
}
}
@Test
public void segmentsInvalidRange() throws Exception {
try (SvnTestServer server = SvnTestServer.createEmpty()) {
final SVNRepository repo = server.openSvnRepository();
initRepo(repo);
final long last = repo.getLatestRevision();
try {
checkGetSegments(repo, "/baz/test.txt", last, 2, 5);
Assert.fail();
} catch (SVNException e) {
Assert.assertEquals(e.getErrorMessage().getErrorCode().getCode(), 204900);
}
}
}
@Test
public void segmentsNotFound() throws Exception {
try (SvnTestServer server = SvnTestServer.createEmpty()) {
final SVNRepository repo = server.openSvnRepository();
initRepo(repo);
final long last = repo.getLatestRevision();
try {
checkGetSegments(repo, "/baz/test.xml", last, 5, 2);
Assert.fail();
} catch (SVNException e) {
Assert.assertEquals(e.getErrorMessage().getErrorCode(), SVNErrorCode.FS_NOT_FOUND);
}
}
}
@Test
public void locationsSimple() throws Exception {
try (SvnTestServer server = SvnTestServer.createEmpty()) {
final SVNRepository repo = server.openSvnRepository();
initRepo(repo);
final long last = repo.getLatestRevision();
checkGetLocations(repo, "/baz/test.txt", last, 5, "/baz/test.txt");
checkGetLocations(repo, "/baz/test.txt", last, 4, "/baz/test.txt");
checkGetLocations(repo, "/baz/test.txt", last, 3, "/bar/test.txt");
checkGetLocations(repo, "/baz/test.txt", last, 2, "/bar/test.txt");
checkGetLocations(repo, "/baz/test.txt", last, 1, "/foo/test.txt");
checkGetLocations(repo, "/baz/test.txt", last, 0, null);
checkGetLocations(repo, "/bar/test.txt", 3, 3, "/bar/test.txt");
checkGetLocations(repo, "/bar/test.txt", 3, 2, "/bar/test.txt");
checkGetLocations(repo, "/bar/test.txt", 3, 1, "/foo/test.txt");
checkGetLocations(repo, "/bar/test.txt", 3, 0, null);
checkGetLocations(repo, "/bar/test.txt", 2, 2, "/bar/test.txt");
checkGetLocations(repo, "/bar/test.txt", 2, 1, "/foo/test.txt");
checkGetLocations(repo, "/bar/test.txt", 2, 0, null);
checkGetLocations(repo, "/foo/test.txt", 1, 1, "/foo/test.txt");
checkGetLocations(repo, "/foo/test.txt", 1, 0, null);
}
}
@Test
public void locationsNotFound() throws Exception {
try (SvnTestServer server = SvnTestServer.createEmpty()) {
final SVNRepository repo = server.openSvnRepository();
initRepo(repo);
try {
checkGetLocations(repo, "/bar/test.xml", 3, 3, null);
Assert.fail();
} catch (SVNException e) {
Assert.assertEquals(e.getErrorMessage().getErrorCode(), SVNErrorCode.FS_NOT_FOUND);
}
try {
checkGetLocations(repo, "/bar/test.txt", 3, 4, null);
Assert.fail();
} catch (SVNException e) {
Assert.assertEquals(e.getErrorMessage().getErrorCode(), SVNErrorCode.FS_NOT_FOUND);
}
}
}
private void initRepo(@NotNull SVNRepository repo) throws SVNException, IOException {
// r1 - add single file.
{
final ISVNEditor editor = repo.getCommitEditor("Create directory: /foo", null, false, null);
editor.openRoot(-1);
editor.addDir("/foo", null, -1);
// Some file.
editor.addFile("/foo/test.txt", null, -1);
editor.changeFileProperty("/foo/test.txt", SVNProperty.EOL_STYLE, SVNPropertyValue.create(SVNProperty.EOL_STYLE_NATIVE));
sendDeltaAndClose(editor, "/foo/test.txt", null, "Foo content");
// Close dir
editor.closeDir();
editor.closeDir();
editor.closeEdit();
}
// r2 - rename dir
{
final long revision = repo.getLatestRevision();
final ISVNEditor editor = repo.getCommitEditor("Rename: /foo to /bar", null, false, null);
editor.openRoot(-1);
// Move dir.
editor.addDir("/bar", "/foo", revision);
editor.closeDir();
editor.deleteEntry("/foo", revision);
// Close dir
editor.closeDir();
editor.closeEdit();
}
// r3 - modify file.
modifyFile(repo, "/bar/test.txt", "Bar content", repo.getLatestRevision());
// r4 - rename dir
{
final long revision = repo.getLatestRevision();
final ISVNEditor editor = repo.getCommitEditor("Rename: /bar to /baz", null, false, null);
editor.openRoot(-1);
// Move dir.
editor.addDir("/baz", "/bar", revision);
editor.closeDir();
editor.deleteEntry("/bar", revision);
// Close dir
editor.closeDir();
editor.closeEdit();
}
// r5 - modify file.
modifyFile(repo, "/baz/test.txt", "Baz content", repo.getLatestRevision());
}
private void checkGetLocations(@NotNull SVNRepository repo, @NotNull String path, long pegRev, long targetRev, @Nullable String expectedPath) throws SVNException {
final List<String> paths = new ArrayList<>();
repo.getLocations(path, pegRev, new long[]{targetRev}, locationEntry -> {
Assert.assertEquals(locationEntry.getRevision(), targetRev);
paths.add(locationEntry.getPath());
});
if (expectedPath == null) {
Assert.assertTrue(paths.isEmpty());
} else {
Assert.assertEquals(paths.size(), 1);
Assert.assertEquals(paths.get(0), expectedPath);
}
}
private void checkGetSegments(@NotNull SVNRepository repo, @NotNull String path, long pegRev, long startRev, long endRev, @NotNull String... expected) throws SVNException {
final List<String> actual = new ArrayList<>();
repo.getLocationSegments(path, pegRev, startRev, endRev, locationEntry -> {
actual.add(locationEntry.getPath() + "@" + locationEntry.getStartRevision() + ":" + locationEntry.getEndRevision());
});
Assert.assertEquals(actual.toArray(new String[actual.size()]), expected);
}
}