diff options
Diffstat (limited to 'org.eclipse.jgit.test')
44 files changed, 1348 insertions, 500 deletions
diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD index 95fb79b22e..be4fdbdea9 100644 --- a/org.eclipse.jgit.test/BUILD +++ b/org.eclipse.jgit.test/BUILD @@ -19,6 +19,7 @@ HELPERS = glob( "nls/MissingPropertyBundle.java", "nls/NoPropertiesBundle.java", "nls/NonTranslatedBundle.java", + "revwalk/ReachabilityCheckerTestCase.java", "revwalk/RevQueueTestCase.java", "revwalk/RevWalkTestCase.java", "transport/ObjectIdMatcher.java", @@ -68,7 +69,7 @@ java_library( deps = [ "//lib:jsch", "//lib:junit", - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", "//org.eclipse.jgit:jgit", "//org.eclipse.jgit.junit:junit", diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 14eef1351f..73c8de8525 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.test Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.0.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy @@ -12,54 +12,54 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.54,0.2.0)", net.bytebuddy.dynamic.loading;version="[1.7.0,2.0.0)", org.bouncycastle.util.encoders;version="[1.60.0,2.0.0)", - org.eclipse.jgit.annotations;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.attributes;version="[5.3.3,5.4.0)", - org.eclipse.jgit.awtui;version="[5.3.3,5.4.0)", - org.eclipse.jgit.blame;version="[5.3.3,5.4.0)", - org.eclipse.jgit.diff;version="[5.3.3,5.4.0)", - org.eclipse.jgit.dircache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.events;version="[5.3.3,5.4.0)", - org.eclipse.jgit.fnmatch;version="[5.3.3,5.4.0)", - org.eclipse.jgit.gitrepo;version="[5.3.3,5.4.0)", - org.eclipse.jgit.hooks;version="[5.3.3,5.4.0)", - org.eclipse.jgit.ignore;version="[5.3.3,5.4.0)", - org.eclipse.jgit.ignore.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.fsck;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.io;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftree;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.transport.parser;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit.ssh;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.merge;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.notes;version="[5.3.3,5.4.0)", - org.eclipse.jgit.patch;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revplot;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.submodule;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.resolver;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.io;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.sha1;version="[5.3.3,5.4.0)", + org.eclipse.jgit.annotations;version="[5.4.0,5.5.0)", + org.eclipse.jgit.api;version="[5.4.0,5.5.0)", + org.eclipse.jgit.api.errors;version="[5.4.0,5.5.0)", + org.eclipse.jgit.attributes;version="[5.4.0,5.5.0)", + org.eclipse.jgit.awtui;version="[5.4.0,5.5.0)", + org.eclipse.jgit.blame;version="[5.4.0,5.5.0)", + org.eclipse.jgit.diff;version="[5.4.0,5.5.0)", + org.eclipse.jgit.dircache;version="[5.4.0,5.5.0)", + org.eclipse.jgit.errors;version="[5.4.0,5.5.0)", + org.eclipse.jgit.events;version="[5.4.0,5.5.0)", + org.eclipse.jgit.fnmatch;version="[5.4.0,5.5.0)", + org.eclipse.jgit.gitrepo;version="[5.4.0,5.5.0)", + org.eclipse.jgit.hooks;version="[5.4.0,5.5.0)", + org.eclipse.jgit.ignore;version="[5.4.0,5.5.0)", + org.eclipse.jgit.ignore.internal;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.fsck;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.storage.io;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.storage.reftree;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.transport.parser;version="[5.4.0,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.0,5.5.0)", + org.eclipse.jgit.junit.ssh;version="[5.4.0,5.5.0)", + org.eclipse.jgit.lfs;version="[5.4.0,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.0,5.5.0)", + org.eclipse.jgit.merge;version="[5.4.0,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.0,5.5.0)", + org.eclipse.jgit.notes;version="[5.4.0,5.5.0)", + org.eclipse.jgit.patch;version="[5.4.0,5.5.0)", + org.eclipse.jgit.pgm;version="[5.4.0,5.5.0)", + org.eclipse.jgit.pgm.internal;version="[5.4.0,5.5.0)", + org.eclipse.jgit.revplot;version="[5.4.0,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.0,5.5.0)", + org.eclipse.jgit.revwalk.filter;version="[5.4.0,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.0,5.5.0)", + org.eclipse.jgit.storage.pack;version="[5.4.0,5.5.0)", + org.eclipse.jgit.submodule;version="[5.4.0,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.0,5.5.0)", + org.eclipse.jgit.transport.http;version="[5.4.0,5.5.0)", + org.eclipse.jgit.transport.resolver;version="[5.4.0,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.0,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.0,5.5.0)", + org.eclipse.jgit.util;version="[5.4.0,5.5.0)", + org.eclipse.jgit.util.io;version="[5.4.0,5.5.0)", + org.eclipse.jgit.util.sha1;version="[5.4.0,5.5.0)", org.junit;version="[4.12,5.0.0)", org.junit.experimental.theories;version="[4.12,5.0.0)", org.junit.rules;version="[4.12,5.0.0)", @@ -73,4 +73,4 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", org.slf4j;version="[1.7.0,2.0.0)" Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", org.hamcrest.library;bundle-version="[1.1.0,2.0.0)" -Export-Package: org.eclipse.jgit.transport.ssh;version="5.3.3";x-friends:="org.eclipse.jgit.ssh.apache.test" +Export-Package: org.eclipse.jgit.transport.ssh;version="5.4.0";x-friends:="org.eclipse.jgit.ssh.apache.test" diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index 21c06428f2..6248756184 100644 --- a/org.eclipse.jgit.test/pom.xml +++ b/org.eclipse.jgit.test/pom.xml @@ -52,7 +52,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.0-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId> @@ -190,7 +190,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Xmx1024m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> + <argLine>@{argLine} -Xmx768m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> <includes> <include>**/*Test.java</include> <include>**/*Tests.java</include> diff --git a/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass new file mode 100644 index 0000000000..904cf302c2 --- /dev/null +++ b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAsFN8vig +Nw4/Ow6xbb7MAZAAABAAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIEZXZRjuttLufaP8 +wFD/i4lYPnKk01z46Jwv/9U4mPioAAAAkHLErPaXeC179rzXMaSwClstzsKvJ/Gqh2cY8d +cWzymXtKZcivWMKesRHbC+1qRx53ofx15IzT5Fmg6NuNk4sm2s+lH8x8HN3CPWBfjGIelP +iQUR6M6Y91mPigpRC2HUJmJIaFNdrRqFF84a5+qyK//tdy1fv4gNMLi5yPdXiL/Ttw05FS +LkFikjfvSGZSO/MA== +-----END OPENSSH PRIVATE KEY----- diff --git a/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass.pub b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass.pub new file mode 100644 index 0000000000..65038b5f4c --- /dev/null +++ b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEZXZRjuttLufaP8wFD/i4lYPnKk01z46Jwv/9U4mPio test diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java index 5a01eae9b5..e6100e225d 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.lib; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -50,8 +51,7 @@ public class Sets { @SafeVarargs public static <T> Set<T> of(T... elements) { Set<T> ret = new HashSet<>(); - for (T element : elements) - ret.add(element); + ret.addAll(Arrays.asList(elements)); return ret; } } diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java index 2f367ba51f..b8c90b2a40 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java @@ -89,7 +89,9 @@ public abstract class SshTestBase extends SshTestHarness { "id_rsa_4096_testpass", // "id_ecdsa_256_testpass", // "id_ecdsa_384_testpass", // - "id_ecdsa_521_testpass" }; + "id_ecdsa_521_testpass", // + "id_ed25519_testpass", // + "id_ed25519_expensive_testpass" }; protected File defaultCloneDir; diff --git a/org.eclipse.jgit.test/tests.bzl b/org.eclipse.jgit.test/tests.bzl index dc2102964f..6b5c7a1df1 100644 --- a/org.eclipse.jgit.test/tests.bzl +++ b/org.eclipse.jgit.test/tests.bzl @@ -45,7 +45,7 @@ def tests(tests): additional_deps = [ "//lib:jsch", "//lib:jzlib", - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", ":sshd-helpers", ] diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java index 139f199f7a..4eeaf4d6e4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java @@ -128,7 +128,7 @@ public class CleanCommandTest extends RepositoryTestCase { status = git.status().call(); files = status.getUntracked(); - assertTrue(files.size() == 0); + assertTrue(files.isEmpty()); assertTrue(cleanedFiles.contains("File2.txt")); assertTrue(cleanedFiles.contains("File3.txt")); assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt")); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index cd96f41a42..4bfac1505a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -485,7 +485,7 @@ public class CommitCommandTest extends RepositoryTestCase { } private static String reflogComments(List<ReflogEntry> entries) { - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); for (ReflogEntry e : entries) { b.append(e.getComment()).append(";"); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java index 807079eb23..bc3ac7a723 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java @@ -203,7 +203,6 @@ public class DescribeCommandTest extends RepositoryTestCase { assertNotNull(describe(c1, "v1.1*", "v1.0*")); assertNotNull(describe(c2, "v1.0*", "v1.1*")); assertNotNull(describe(c2, "v1.1*", "v1.0*")); - } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index 9461c42500..2fd378842f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java @@ -346,14 +346,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** global rebase config should be respected */ public void testPullWithRebasePreserve1Config() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "preserve"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "preserve"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); } @@ -361,15 +358,12 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should win over the global config */ public void testPullWithRebasePreserveConfig2() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "false"); - config.setString("branch", "master", "rebase", "preserve"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "false"); + config.setString("branch", "master", "rebase", "preserve"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); } @@ -377,14 +371,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should be respected */ public void testPullWithRebasePreserveConfig3() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("branch", "master", "rebase", "preserve"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("branch", "master", "rebase", "preserve"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); } @@ -392,14 +383,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** global rebase config should be respected */ public void testPullWithRebaseConfig1() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "true"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "true"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE); } @@ -407,15 +395,12 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should win over the global config */ public void testPullWithRebaseConfig2() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "preserve"); - config.setString("branch", "master", "rebase", "true"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "preserve"); + config.setString("branch", "master", "rebase", "true"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE); } @@ -423,14 +408,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should be respected */ public void testPullWithRebaseConfig3() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("branch", "master", "rebase", "true"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("branch", "master", "rebase", "true"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE); } @@ -438,27 +420,19 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** without config it should merge */ public void testPullWithoutConfig() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - return target.pull().call(); - } - }; + Callable<PullResult> setup = target.pull()::call; doTestPullWithRebase(setup, TestPullMode.MERGE); } @Test /** the branch local config should win over the global config */ public void testPullWithMergeConfig() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "true"); - config.setString("branch", "master", "rebase", "false"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "true"); + config.setString("branch", "master", "rebase", "false"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.MERGE); } @@ -466,14 +440,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch local config should win over the global config */ public void testPullWithMergeConfig2() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "false"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "false"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.MERGE); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java index 1d9cd78140..d6aead4a52 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java @@ -49,6 +49,7 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -854,8 +855,7 @@ public class TreeWalkAttributeTest extends RepositoryTestCase { static Set<Attribute> asSet(Attribute... attrs) { HashSet<Attribute> result = new HashSet<>(); - for (Attribute attr : attrs) - result.add(attr); + result.addAll(Arrays.asList(attrs)); return result; } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java index 014406eb98..972dc60156 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java @@ -205,8 +205,9 @@ public class DirCacheBasicTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertFalse(dc.hasUnmergedPaths()); @@ -229,8 +230,9 @@ public class DirCacheBasicTest extends RepositoryTestCase { ents[2].setFileMode(FileMode.REGULAR_FILE); final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertTrue(dc.hasUnmergedPaths()); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java index 3598f3a4a1..6020a748aa 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java @@ -71,8 +71,9 @@ public class DirCacheBuilderIteratorTest extends RepositoryTestCase { } { final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java index b6291bfca4..0c1131ba86 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java @@ -210,12 +210,8 @@ public class DirCacheBuilderTest extends RepositoryTestCase { boolean receivedEvent = false; DirCache dc = db.lockDirCache(); - IndexChangedListener listener = new IndexChangedListener() { - - @Override - public void onIndexChanged(IndexChangedEvent event) { - throw new ReceivedEventMarkerException(); - } + IndexChangedListener listener = (IndexChangedEvent event) -> { + throw new ReceivedEventMarkerException(); }; ListenerList l = db.getListenerList(); @@ -238,12 +234,8 @@ public class DirCacheBuilderTest extends RepositoryTestCase { // do the same again, as this doesn't change index compared to first // round we should get no event this time dc = db.lockDirCache(); - listener = new IndexChangedListener() { - - @Override - public void onIndexChanged(IndexChangedEvent event) { - throw new ReceivedEventMarkerException(); - } + listener = (IndexChangedEvent event) -> { + throw new ReceivedEventMarkerException(); }; l = db.getListenerList(); @@ -301,8 +293,9 @@ public class DirCacheBuilderTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertEquals(paths.length, dc.getEntryCount()); @@ -351,8 +344,9 @@ public class DirCacheBuilderTest extends RepositoryTestCase { } { final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); } assertEquals(paths.length, dc.getEntryCount()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java index 3b8c6ee7b4..7fc28018f6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java @@ -66,8 +66,9 @@ public class DirCacheFindTest extends RepositoryTestCase { final int aLast = 3; final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertEquals(paths.length, dc.getEntryCount()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java index 82565fceec..bc99aeef2f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java @@ -94,8 +94,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final DirCacheIterator i = new DirCacheIterator(dc); @@ -121,8 +122,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final DirCacheIterator i = new DirCacheIterator(dc); @@ -154,8 +156,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final String[] expPaths = { "a-", "a", "a0b" }; @@ -200,8 +203,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final DirCacheIterator i = new DirCacheIterator(dc); @@ -236,8 +240,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); try (TreeWalk tw = new TreeWalk(db)) { @@ -271,8 +276,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); DirCacheIterator dci = new DirCacheIterator(dc); @@ -365,8 +371,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); DirCacheIterator dci = new DirCacheIterator(dc); @@ -398,8 +405,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); try (TreeWalk tw = new TreeWalk(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java index f662e2660c..513db75323 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java @@ -102,8 +102,9 @@ public class DirCacheTreeTest extends RepositoryTestCase { final int aLast = 3; final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertNull(dc.getCacheTree(false)); @@ -142,8 +143,9 @@ public class DirCacheTreeTest extends RepositoryTestCase { final int acLast = 3; final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertNull(dc.getCacheTree(false)); @@ -198,8 +200,9 @@ public class DirCacheTreeTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.commit(); DirCache read = db.readDirCache(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java index 3624100671..b6f312dfec 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java @@ -54,12 +54,9 @@ public class ConfigChangeEventTest extends RepositoryTestCase { @Test public void testFileRepository_ChangeEventsOnlyOnSave() throws Exception { final ConfigChangedEvent[] events = new ConfigChangedEvent[1]; - db.getListenerList().addConfigChangedListener( - new ConfigChangedListener() { - @Override - public void onConfigChanged(ConfigChangedEvent event) { - events[0] = event; - } + db.getListenerList() + .addConfigChangedListener((ConfigChangedEvent event) -> { + events[0] = event; }); FileBasedConfig config = db.getConfig(); assertNull(events[0]); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/InMemoryRepositoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/InMemoryRepositoryTest.java new file mode 100644 index 0000000000..bab6110ce6 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/InMemoryRepositoryTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2019, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.internal.storage.dfs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Set; + +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.ObjectIdRef; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Ref.Storage; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTag; +import org.junit.Test; + +public class InMemoryRepositoryTest { + + @Test + public void keepUpdateIndexPeelingTag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.branch("master").commit() + .message("first commit").create(); + RevTag tag = git.tag("v0.1", commit); + git.update("refs/tags/v0.1", tag); + + Ref unpeeledTag = new ObjectIdRef.Unpeeled(Storage.LOOSE, + "refs/tags/v0.1", tag.getId(), 1000); + + Ref peeledTag = repo.getRefDatabase().peel(unpeeledTag); + assertTrue(peeledTag instanceof ObjectIdRef.PeeledTag); + assertEquals(1000, peeledTag.getUpdateIndex()); + } + } + + @Test + public void keepUpdateIndexPeelingNonTag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.branch("master").commit() + .message("first commit").create(); + + Ref unpeeledRef = new ObjectIdRef.Unpeeled(Storage.LOOSE, + "refs/heads/master", commit.getId(), 1000); + Ref peeledRef = repo.getRefDatabase().peel(unpeeledRef); + assertTrue(peeledRef instanceof ObjectIdRef.PeeledNonTag); + assertEquals(1000, peeledRef.getUpdateIndex()); + } + } + + @Test + public void sha1ToTip_ref() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.branch("master").commit() + .message("first commit").create(); + + Set<Ref> tipsWithSha1 = repo.getRefDatabase() + .getTipsWithSha1(commit.getId()); + assertEquals(1, tipsWithSha1.size()); + Ref ref = tipsWithSha1.iterator().next(); + assertEquals(ref.getName(), "refs/heads/master"); + assertEquals(commit.getId(), ref.getObjectId()); + } + } + + @Test + public void sha1ToTip_annotatedTag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.commit() + .message("first commit").create(); + RevTag tagObj = git.tag("v0.1", commit); + git.update("refs/tags/v0.1", tagObj); + Set<Ref> tipsWithSha1 = repo.getRefDatabase() + .getTipsWithSha1(commit.getId()); + assertEquals(1, tipsWithSha1.size()); + Ref ref = tipsWithSha1.iterator().next(); + assertEquals(ref.getName(), "refs/tags/v0.1"); + assertEquals(commit.getId(), ref.getPeeledObjectId()); + } + } + + @Test + public void sha1ToTip_tag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.commit().message("first commit").create(); + git.update("refs/tags/v0.2", commit); + Set<Ref> tipsWithSha1 = repo.getRefDatabase() + .getTipsWithSha1(commit.getId()); + assertEquals(1, tipsWithSha1.size()); + Ref ref = tipsWithSha1.iterator().next(); + assertEquals(ref.getName(), "refs/tags/v0.2"); + assertEquals(commit.getId(), ref.getObjectId()); + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java index 05f7c65fa8..9e7d41a693 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java @@ -239,20 +239,15 @@ public class GcConcurrentTest extends GcTestCase { SampleDataRepositoryTestCase.copyCGitTestPacks(repo); ExecutorService executor = Executors.newSingleThreadExecutor(); final CountDownLatch latch = new CountDownLatch(1); - Future<Collection<PackFile>> result = executor - .submit(new Callable<Collection<PackFile>>() { - - @Override - public Collection<PackFile> call() throws Exception { - long start = System.currentTimeMillis(); - System.out.println("starting gc"); - latch.countDown(); - Collection<PackFile> r = gc.gc(); - System.out.println("gc took " - + (System.currentTimeMillis() - start) + " ms"); - return r; - } - }); + Future<Collection<PackFile>> result = executor.submit(() -> { + long start = System.currentTimeMillis(); + System.out.println("starting gc"); + latch.countDown(); + Collection<PackFile> r = gc.gc(); + System.out.println( + "gc took " + (System.currentTimeMillis() - start) + " ms"); + return r; + }); try { latch.await(); Thread.sleep(5); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java index c43bdbd298..1fa5aa09ad 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java @@ -155,40 +155,32 @@ public class GcPackRefsTest extends GcTestCase { final CyclicBarrier packRefsDone = new CyclicBarrier(2); ExecutorService pool = Executors.newFixedThreadPool(2); try { - Future<Result> result = pool.submit(new Callable<Result>() { - - @Override - public Result call() throws Exception { - RefUpdate update = new RefDirectoryUpdate( - (RefDirectory) repo.getRefDatabase(), - repo.exactRef("refs/tags/t")) { - @Override - public boolean isForceUpdate() { - try { - refUpdateLockedRef.await(); - packRefsDone.await(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (BrokenBarrierException e) { - Thread.currentThread().interrupt(); - } - return super.isForceUpdate(); + Future<Result> result = pool.submit(() -> { + RefUpdate update = new RefDirectoryUpdate( + (RefDirectory) repo.getRefDatabase(), + repo.exactRef("refs/tags/t")) { + @Override + public boolean isForceUpdate() { + try { + refUpdateLockedRef.await(); + packRefsDone.await(); + } catch (InterruptedException + | BrokenBarrierException e) { + Thread.currentThread().interrupt(); } - }; - update.setForceUpdate(true); - update.setNewObjectId(b); - return update.update(); - } + return super.isForceUpdate(); + } + }; + update.setForceUpdate(true); + update.setNewObjectId(b); + return update.update(); }); - pool.submit(new Callable<Void>() { - @Override - public Void call() throws Exception { - refUpdateLockedRef.await(); - gc.packRefs(); - packRefsDone.await(); - return null; - } + pool.submit(() -> { + refUpdateLockedRef.await(); + gc.packRefs(); + packRefsDone.await(); + return null; }); assertSame(result.get(), Result.FORCED); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java index a3a302d81a..a9d0dc20e6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java @@ -47,7 +47,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; -import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintWriter; import java.text.MessageFormat; @@ -167,12 +166,8 @@ public class ObjectDirectoryTest extends RepositoryTestCase { // Bug. To show the bug we sleep for more than 2500ms Thread.sleep(2600); - File[] ret = packsFolder.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".pack"); - } - }); + File[] ret = packsFolder.listFiles( + (File dir, String name) -> name.endsWith(".pack")); assertTrue(ret != null && ret.length == 1); Assume.assumeTrue(tmpFile.lastModified() == ret[0].lastModified()); @@ -220,12 +215,8 @@ public class ObjectDirectoryTest extends RepositoryTestCase { private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir( final ObjectDirectory dir) { - Callable<ObjectId> callable = new Callable<ObjectId>() { - @Override - public ObjectId call() throws Exception { - return dir.newInserter().insert(Constants.OBJ_BLOB, new byte[0]); - } - }; + Callable<ObjectId> callable = () -> dir.newInserter() + .insert(Constants.OBJ_BLOB, new byte[0]); return Collections.nCopies(4, callable); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java index ca4486256b..5d0a7e2a0b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java @@ -60,7 +60,6 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -881,12 +880,8 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { for (MutableEntry me : pack) { entries.add(me.cloneEntry()); } - Collections.sort(entries, new Comparator<PackIndex.MutableEntry>() { - @Override - public int compare(MutableEntry o1, MutableEntry o2) { - return Long.signum(o1.getOffset() - o2.getOffset()); - } - }); + Collections.sort(entries, (MutableEntry o1, MutableEntry o2) -> Long + .signum(o1.getOffset() - o2.getOffset())); int i = 0; for (MutableEntry me : entries) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java index 7b3684c865..bd9572b113 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java @@ -70,7 +70,6 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jgit.errors.LockFailedException; import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.events.RefsChangedEvent; -import org.eclipse.jgit.events.RefsChangedListener; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.AnyObjectId; @@ -570,12 +569,8 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { final int[] count = new int[1]; ListenerHandle listener = Repository.getGlobalListenerList() - .addRefsChangedListener(new RefsChangedListener() { - - @Override - public void onRefsChanged(RefsChangedEvent event) { - count[0]++; - } + .addRefsChangedListener((RefsChangedEvent event) -> { + count[0]++; }); refs = refdir.getRefs(RefDatabase.ALL); @@ -1316,19 +1311,15 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { final AtomicReference<StackOverflowError> error = new AtomicReference<>(); final AtomicReference<IOException> exception = new AtomicReference<>(); final AtomicInteger changeCount = new AtomicInteger(); - newRepo.getListenerList().addRefsChangedListener( - new RefsChangedListener() { - - @Override - public void onRefsChanged(RefsChangedEvent event) { - try { - refDb.getRefsByPrefix("ref"); - changeCount.incrementAndGet(); - } catch (StackOverflowError soe) { - error.set(soe); - } catch (IOException ioe) { - exception.set(ioe); - } + newRepo.getListenerList() + .addRefsChangedListener((RefsChangedEvent event) -> { + try { + refDb.getRefsByPrefix("ref"); + changeCount.incrementAndGet(); + } catch (StackOverflowError soe) { + error.set(soe); + } catch (IOException ioe) { + exception.set(ioe); } }); refDb.getRefsByPrefix("ref"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java index 8ef21e6da7..c3f5baa67b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java @@ -633,35 +633,23 @@ public class RefTreeDatabaseTest { private void symref(String name, String dst) throws IOException { - commit(new Function() { - @Override - public boolean apply(ObjectReader reader, RefTree tree) - throws IOException { - Ref old = tree.exactRef(reader, name); - Command n = new Command( - old, - new SymbolicRef( - name, - new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null))); - return tree.apply(Collections.singleton(n)); - } + commit((ObjectReader reader, RefTree tree) -> { + Ref old = tree.exactRef(reader, name); + Command n = new Command(old, new SymbolicRef(name, + new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null))); + return tree.apply(Collections.singleton(n)); }); } private void update(String name, ObjectId id) throws IOException { - commit(new Function() { - @Override - public boolean apply(ObjectReader reader, RefTree tree) - throws IOException { - Ref old = tree.exactRef(reader, name); - Command n; - try (RevWalk rw = new RevWalk(repo)) { - n = new Command(old, - Command.toRef(rw, id, null, name, true)); - } - return tree.apply(Collections.singleton(n)); + commit((ObjectReader reader, RefTree tree) -> { + Ref old = tree.exactRef(reader, name); + Command n; + try (RevWalk rw = new RevWalk(repo)) { + n = new Command(old, Command.toRef(rw, id, null, name, true)); } + return tree.apply(Collections.singleton(n)); }); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 21d8d66adf..5a4bd886ab 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -1450,6 +1450,13 @@ public class ConfigTest { assertEquals("xt", parseEscapedSubsection("\"x\\t\"")); } + @Test + public void testInvalidGroupHeader() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage(JGitText.get().badGroupHeader); + parse("[foo \"bar\" ]\nfoo=bar\n"); + } + private static void assertValueRoundTrip(String value) throws ConfigInvalidException { assertValueRoundTrip(value, value); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java index 531c918e9b..e7a5b286dd 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java @@ -1678,7 +1678,6 @@ public class ObjectCheckerTest { rejectName('>'); rejectName(':'); rejectName('"'); - rejectName('/'); rejectName('\\'); rejectName('|'); rejectName('?'); @@ -1693,7 +1692,8 @@ public class ObjectCheckerTest { checkOneName("te" + c + "st"); fail("incorrectly accepted with " + c); } catch (CorruptObjectException e) { - assertEquals("name contains '" + c + "'", e.getMessage()); + + assertEquals("char '" + c + "' not allowed in Windows filename", e.getMessage()); } } @@ -1703,7 +1703,19 @@ public class ObjectCheckerTest { checkOneName("te" + ((char) c) + "st"); fail("incorrectly accepted with 0x" + h); } catch (CorruptObjectException e) { - assertEquals("name contains byte 0x" + h, e.getMessage()); + assertEquals("byte 0x" + h + " not allowed in Windows filename", e.getMessage()); + } + } + + + @Test + public void testRejectInvalidCharacter() { + try { + checkOneName("te/st"); + fail("incorrectly accepted with /"); + } catch (CorruptObjectException e) { + + assertEquals("name contains '/'", e.getMessage()); } } @@ -1763,16 +1775,13 @@ public class ObjectCheckerTest { } private static ObjectIdSet set(ObjectId... ids) { - return new ObjectIdSet() { - @Override - public boolean contains(AnyObjectId objectId) { - for (ObjectId id : ids) { - if (id.equals(objectId)) { - return true; - } + return (AnyObjectId objectId) -> { + for (ObjectId id : ids) { + if (id.equals(objectId)) { + return true; } - return false; } + return false; }; } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java index 7d2c4a2784..b53d5b9448 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java @@ -58,8 +58,10 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.TreeSet; import org.eclipse.jgit.lib.Ref.Storage; @@ -313,7 +315,7 @@ public class RefTest extends SampleDataRepositoryTestCase { assertEquals(dst.isPeeled(), ref.isPeeled()); } - private static void checkContainsRef(List<Ref> haystack, Ref needle) { + private static void checkContainsRef(Collection<Ref> haystack, Ref needle) { for (Ref ref : haystack) { if (ref.getName().equals(needle.getName()) && ref.getObjectId().equals(needle.getObjectId())) { @@ -347,4 +349,17 @@ public class RefTest extends SampleDataRepositoryTestCase { checkContainsRef(refs, db.exactRef("refs/heads/prefix/a")); checkContainsRef(refs, db.exactRef("refs/tags/A")); } + + @Test + public void testResolveTipSha1() throws IOException { + ObjectId masterId = db.resolve("refs/heads/master"); + Set<Ref> resolved = db.getRefDatabase().getTipsWithSha1(masterId); + + assertEquals(2, resolved.size()); + checkContainsRef(resolved, db.exactRef("refs/heads/master")); + checkContainsRef(resolved, db.exactRef("HEAD")); + + assertEquals(db.getRefDatabase() + .getTipsWithSha1(ObjectId.zeroId()).size(), 0); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java index df1a52dc09..f2f277c6ea 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java @@ -45,7 +45,6 @@ package org.eclipse.jgit.lib; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -63,7 +62,8 @@ public class ReflogConfigTest extends RepositoryTestCase { // check that there are no entries in the reflog and turn off writing // reflogs - assertEquals(0, db.getReflogReader(Constants.HEAD).getReverseEntries().size()); + assertTrue(db.getReflogReader(Constants.HEAD).getReverseEntries() + .isEmpty()); final FileBasedConfig cfg = db.getConfig(); cfg.setBoolean("core", null, "logallrefupdates", false); cfg.save(); @@ -72,9 +72,8 @@ public class ReflogConfigTest extends RepositoryTestCase { // written commit("A Commit\n", commitTime, tz); commitTime += 60 * 1000; - assertTrue( - "Reflog for HEAD still contain no entry", - db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 0); + assertTrue("Reflog for HEAD still contain no entry", db + .getReflogReader(Constants.HEAD).getReverseEntries().isEmpty()); // set the logAllRefUpdates parameter to true and check it cfg.setBoolean("core", null, "logallrefupdates", true); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java index 545a188a98..682982226e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java @@ -61,29 +61,26 @@ public class ThreadSafeProgressMonitorTest { final MockProgressMonitor mock = new MockProgressMonitor(); final ThreadSafeProgressMonitor pm = new ThreadSafeProgressMonitor(mock); - runOnThread(new Runnable() { - @Override - public void run() { - try { - pm.start(1); - fail("start did not fail on background thread"); - } catch (IllegalStateException notMainThread) { - // Expected result - } - - try { - pm.beginTask("title", 1); - fail("beginTask did not fail on background thread"); - } catch (IllegalStateException notMainThread) { - // Expected result - } - - try { - pm.endTask(); - fail("endTask did not fail on background thread"); - } catch (IllegalStateException notMainThread) { - // Expected result - } + runOnThread(() -> { + try { + pm.start(1); + fail("start did not fail on background thread"); + } catch (IllegalStateException notMainThread) { + // Expected result + } + + try { + pm.beginTask("title", 1); + fail("beginTask did not fail on background thread"); + } catch (IllegalStateException notMainThread) { + // Expected result + } + + try { + pm.endTask(); + fail("endTask did not fail on background thread"); + } catch (IllegalStateException notMainThread) { + // Expected result } }); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java new file mode 100644 index 0000000000..3a78e1e623 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java @@ -0,0 +1,139 @@ +package org.eclipse.jgit.revwalk; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.internal.storage.file.GC; +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ProgressMonitor; +import org.junit.Before; +import org.junit.Test; + +public class BitmapCalculatorTest extends LocalDiskRepositoryTestCase { + TestRepository<FileRepository> repo; + + /** {@inheritDoc} */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + FileRepository db = createWorkRepository(); + repo = new TestRepository<>(db); + } + + @Test + public void addOnlyCommits() throws Exception { + RevBlob abBlob = repo.blob("a_b_content"); + RevCommit root = repo.commit().add("a/b", abBlob).create(); + repo.update("refs/heads/master", root); + + // GC creates bitmap index with ALL objects + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + // These objects are not in the bitmap index. + RevBlob acBlob = repo.blob("a_c_content"); + RevCommit head = repo.commit().parent(root).add("a/c", acBlob).create(); + repo.update("refs/heads/master", head); + + BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); + BitmapBuilder bitmap = bitmapWalker + .getBitmap(head, NullProgressMonitor.INSTANCE); + + assertTrue(bitmap.contains(root.getId())); + assertTrue(bitmap.contains(root.getTree().getId())); + assertTrue(bitmap.contains(abBlob.getId())); + + // BitmapCalculator added only the commit, no other objects. + assertTrue(bitmap.contains(head.getId())); + assertFalse(bitmap.contains(head.getTree().getId())); + assertFalse(bitmap.contains(acBlob.getId())); + } + + @Test + public void walkUntilBitmap() throws Exception { + RevCommit root = repo.commit().create(); + repo.update("refs/heads/master", root); + + // GC creates bitmap index with ALL objects + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + // These objects are not in the bitmap index. + RevCommit commit1 = repo.commit(root); + RevCommit commit2 = repo.commit(commit1); + repo.update("refs/heads/master", commit2); + + CounterProgressMonitor monitor = new CounterProgressMonitor(); + BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); + BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor); + + assertTrue(bitmap.contains(root)); + assertTrue(bitmap.contains(commit1)); + assertTrue(bitmap.contains(commit2)); + assertEquals(2, monitor.getUpdates()); + } + + @Test + public void noNeedToWalk() throws Exception { + RevCommit root = repo.commit().create(); + RevCommit commit1 = repo.commit(root); + RevCommit commit2 = repo.commit(commit1); + repo.update("refs/heads/master", commit2); + + // GC creates bitmap index with ALL objects + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + CounterProgressMonitor monitor = new CounterProgressMonitor(); + BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); + BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor); + + assertTrue(bitmap.contains(root)); + assertTrue(bitmap.contains(commit1)); + assertTrue(bitmap.contains(commit2)); + assertEquals(0, monitor.getUpdates()); + } + + private static class CounterProgressMonitor implements ProgressMonitor { + + private int counter; + + @Override + public void start(int totalTasks) { + // Nothing to do in tests + } + + @Override + public void beginTask(String title, int totalWork) { + // Nothing to to in tests + } + + @Override + public void update(int completed) { + counter += 1; + } + + @Override + public void endTask() { + // Nothing to do in tests + } + + @Override + public boolean isCancelled() { + return false; + } + + int getUpdates() { + return counter; + } + } +}
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java new file mode 100644 index 0000000000..5d3adf5eab --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019, Google LLC + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.revwalk; + +import static org.junit.Assert.assertNotNull; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.internal.storage.file.GC; +import org.eclipse.jgit.junit.TestRepository; + +public class BitmappedReachabilityCheckerTest + extends ReachabilityCheckerTestCase { + + @Override + protected ReachabilityChecker getChecker( + TestRepository<FileRepository> repository) throws Exception { + // GC generates the bitmaps + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + // This is null when the test didn't create any branch + assertNotNull("Probably the test didn't define any ref", + repo.getRevWalk().getObjectReader().getBitmapIndex()); + + return new BitmappedReachabilityChecker(repository.getRevWalk()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java new file mode 100644 index 0000000000..8d3e78c1fe --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.revwalk; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.junit.TestRepository; + +public class PedestrianReachabilityCheckerTest + extends ReachabilityCheckerTestCase { + + @Override + protected ReachabilityChecker getChecker( + TestRepository<FileRepository> repository) { + return new PedestrianReachabilityChecker(true, repository.getRevWalk()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java new file mode 100644 index 0000000000..dd73e35727 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2019, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.revwalk; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Optional; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.junit.Before; +import org.junit.Test; + +public abstract class ReachabilityCheckerTestCase + extends LocalDiskRepositoryTestCase { + + protected abstract ReachabilityChecker getChecker( + TestRepository<FileRepository> repository) throws Exception; + + TestRepository<FileRepository> repo; + + /** {@inheritDoc} */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + FileRepository db = createWorkRepository(); + repo = new TestRepository<>(db); + } + + @Test + public void reachable() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + RevCommit c1 = repo.commit(a); + RevCommit c2 = repo.commit(c1); + repo.update("refs/heads/checker", b2); + + ReachabilityChecker checker = getChecker(repo); + + assertReachable("reachable from one tip", + checker.areAllReachable(Arrays.asList(a), Arrays.asList(c2))); + assertReachable("reachable from another tip", + checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2))); + assertReachable("reachable from itself", + checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2))); + } + + @Test + public void reachable_merge() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + RevCommit c1 = repo.commit(a); + RevCommit c2 = repo.commit(c1); + RevCommit merge = repo.commit(c2, b2); + repo.update("refs/heads/checker", merge); + + ReachabilityChecker checker = getChecker(repo); + + assertReachable("reachable through one branch", + checker.areAllReachable(Arrays.asList(b1), + Arrays.asList(merge))); + assertReachable("reachable through another branch", + checker.areAllReachable(Arrays.asList(c1), + Arrays.asList(merge))); + assertReachable("reachable, before the branching", + checker.areAllReachable(Arrays.asList(a), + Arrays.asList(merge))); + } + + @Test + public void unreachable_isLaterCommit() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + repo.update("refs/heads/checker", b2); + + ReachabilityChecker checker = getChecker(repo); + + assertUnreachable("unreachable from the future", + checker.areAllReachable(Arrays.asList(b2), Arrays.asList(b1))); + } + + @Test + public void unreachable_differentBranch() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + RevCommit c1 = repo.commit(a); + repo.update("refs/heads/checker", b2); + + ReachabilityChecker checker = getChecker(repo); + + assertUnreachable("unreachable from different branch", + checker.areAllReachable(Arrays.asList(c1), Arrays.asList(b2))); + } + + @Test + public void reachable_longChain() throws Exception { + RevCommit root = repo.commit().create(); + RevCommit head = root; + for (int i = 0; i < 10000; i++) { + head = repo.commit(head); + } + repo.update("refs/heads/master", head); + + ReachabilityChecker checker = getChecker(repo); + + assertReachable("reachable with long chain in the middle", checker + .areAllReachable(Arrays.asList(root), Arrays.asList(head))); + } + + private static void assertReachable(String msg, + Optional<RevCommit> result) { + assertFalse(msg, result.isPresent()); + } + + private static void assertUnreachable(String msg, + Optional<RevCommit> result) { + assertTrue(msg, result.isPresent()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java index 2c98c84ae5..28a9c03ecc 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java @@ -193,7 +193,8 @@ public class ProtocolV0ParserTest { assertThat(request.getWantIds(), hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e", "f900c8326a43303685c46b279b9f70411bff1a4b")); - assertEquals(13000, request.getFilterBlobLimit()); + assertEquals(13000, request.getFilterSpec().getBlobLimit()); + assertEquals(-1, request.getFilterSpec().getTreeDepthLimit()); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java index dafa81ecd0..740d92ef4d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java @@ -232,7 +232,8 @@ public class ProtocolV2ParserTest { ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); - assertEquals(0, request.getFilterBlobLimit()); + assertEquals(0, request.getFilterSpec().getBlobLimit()); + assertEquals(-1, request.getFilterSpec().getTreeDepthLimit()); } @Test @@ -243,7 +244,20 @@ public class ProtocolV2ParserTest { ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); - assertEquals(15, request.getFilterBlobLimit()); + assertEquals(15, request.getFilterSpec().getBlobLimit()); + assertEquals(-1, request.getFilterSpec().getTreeDepthLimit()); + } + + @Test + public void testFetchWithTreeDepthFilter() throws IOException { + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "filter tree:3", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowFilter().done()); + FetchV2Request request = parser.parseFetchRequest(pckIn); + assertEquals(-1, request.getFilterSpec().getBlobLimit()); + assertEquals(3, request.getFilterSpec().getTreeDepthLimit()); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java index cea432e34c..89d02d7527 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java @@ -67,9 +67,6 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.transport.resolver.ReceivePackFactory; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -91,27 +88,16 @@ public class PushConnectionTest { server = newRepo("server"); client = newRepo("client"); processedRefs = new ArrayList<>(); - testProtocol = new TestProtocol<>( - null, - new ReceivePackFactory<Object>() { - @Override - public ReceivePack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - ReceivePack rp = new ReceivePack(db); - rp.setPreReceiveHook( - new PreReceiveHook() { - @Override - public void onPreReceive(ReceivePack receivePack, - Collection<ReceiveCommand> cmds) { - for (ReceiveCommand cmd : cmds) { - processedRefs.add(cmd.getRefName()); - } - } - }); - return rp; - } - }); + testProtocol = new TestProtocol<>(null, (Object req, Repository db) -> { + ReceivePack rp = new ReceivePack(db); + rp.setPreReceiveHook((ReceivePack receivePack, + Collection<ReceiveCommand> cmds) -> { + for (ReceiveCommand cmd : cmds) { + processedRefs.add(cmd.getRefName()); + } + }); + return rp; + }); uri = testProtocol.register(ctx, server); try (ObjectInserter ins = server.newObjectInserter()) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java index f26201d56d..fd1c3bf8b8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java @@ -69,9 +69,6 @@ import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.transport.resolver.ReceivePackFactory; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -95,16 +92,11 @@ public class PushOptionsTest extends RepositoryTestCase { client = newRepo("client"); testProtocol = new TestProtocol<>(null, - new ReceivePackFactory<Object>() { - @Override - public ReceivePack create(Object req, Repository git) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - receivePack = new ReceivePack(git); - receivePack.setAllowPushOptions(true); - receivePack.setAtomic(true); - return receivePack; - } + (Object req, Repository git) -> { + receivePack = new ReceivePack(git); + receivePack.setAllowPushOptions(true); + receivePack.setAtomic(true); + return receivePack; }); uri = testProtocol.register(ctx, server); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java index 1c4d0cfe24..f4c55aa50a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java @@ -92,11 +92,8 @@ public class TestProtocolTest { @Override public UploadPack create(User req, Repository db) { UploadPack up = new UploadPack(db); - up.setPostUploadHook(new PostUploadHook() { - @Override - public void onPostUpload(PackStatistics stats) { - havesCount = stats.getHaves(); - } + up.setPostUploadHook((PackStatistics stats) -> { + havesCount = stats.getHaves(); }); return up; } @@ -217,16 +214,12 @@ public class TestProtocolTest { ObjectId master = remote.branch("master").commit().create(); final AtomicInteger rejected = new AtomicInteger(); - TestProtocol<User> proto = registerProto(new UploadPackFactory<User>() { - @Override - public UploadPack create(User req, Repository db) - throws ServiceNotAuthorizedException { - if (!"user2".equals(req.name)) { - rejected.incrementAndGet(); - throw new ServiceNotAuthorizedException(); - } - return new UploadPack(db); + TestProtocol<User> proto = registerProto((User req, Repository db) -> { + if (!"user2".equals(req.name)) { + rejected.incrementAndGet(); + throw new ServiceNotAuthorizedException(); } + return new UploadPack(db); }, new DefaultReceive()); // Same repository, different users. @@ -262,16 +255,12 @@ public class TestProtocolTest { final AtomicInteger rejected = new AtomicInteger(); TestProtocol<User> proto = registerProto(new DefaultUpload(), - new ReceivePackFactory<User>() { - @Override - public ReceivePack create(User req, Repository db) - throws ServiceNotAuthorizedException { - if (!"user2".equals(req.name)) { - rejected.incrementAndGet(); - throw new ServiceNotAuthorizedException(); - } - return new ReceivePack(db); + (User req, Repository db) -> { + if (!"user2".equals(req.name)) { + rejected.incrementAndGet(); + throw new ServiceNotAuthorizedException(); } + return new ReceivePack(db); }); // Same repository, different users. diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index 1cbe8a4312..9ffcbccc8f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java @@ -16,11 +16,16 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector; @@ -28,6 +33,8 @@ import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; @@ -38,10 +45,8 @@ import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.storage.pack.PackStatistics; import org.eclipse.jgit.transport.UploadPack.RequestPolicy; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; -import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.eclipse.jgit.util.io.NullOutputStream; import org.hamcrest.Matchers; import org.junit.After; @@ -69,6 +74,8 @@ public class UploadPackTest { private TestRepository<InMemoryRepository> remote; + private PackStatistics stats; + @Before public void setUp() throws Exception { server = newRepo("server"); @@ -92,17 +99,11 @@ public class UploadPackTest { } private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() { - return new TestProtocol<>( - new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); - return up; - } - }, null); + return new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); + return up; + }, null); } @Test @@ -112,20 +113,14 @@ public class UploadPackTest { RevCommit tip = remote.commit().message("2").parent(commit1).create(); remote.update("master", tip); - testProtocol = new TestProtocol<>( - new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); - // assume client has a shallow commit - up.getRevWalk().assumeShallow( - Collections.singleton(commit1.getId())); - return up; - } - }, null); + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); + // assume client has a shallow commit + up.getRevWalk() + .assumeShallow(Collections.singleton(commit1.getId())); + return up; + }, null); uri = testProtocol.register(ctx, server); assertFalse(client.getObjectDatabase().has(commit0.toObjectId())); @@ -212,19 +207,14 @@ public class UploadPackTest { server2.getConfig().setBoolean("uploadpack", null, "allowfilter", true); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(0); + tn.setFilterSpec(FilterSpec.withBlobLimit(0)); tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(commit.name()))); assertTrue(client.getObjectDatabase().has(tree.toObjectId())); @@ -250,19 +240,14 @@ public class UploadPackTest { server2.getConfig().setBoolean("uploadpack", null, "allowfilter", true); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(0); + tn.setFilterSpec(FilterSpec.withBlobLimit(0)); tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList( new RefSpec(commit.name()), new RefSpec(blob1.name()))); assertTrue(client.getObjectDatabase().has(tree.toObjectId())); @@ -287,19 +272,14 @@ public class UploadPackTest { server2.getConfig().setBoolean("uploadpack", null, "allowfilter", true); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(5); + tn.setFilterSpec(FilterSpec.withBlobLimit(5)); tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(commit.name()))); assertFalse( @@ -330,19 +310,14 @@ public class UploadPackTest { new DfsGarbageCollector(server2).pack(null); server2.scanForRepoChanges(); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(0); + tn.setFilterSpec(FilterSpec.withBlobLimit(0)); tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList( new RefSpec(commit.name()), new RefSpec(blob1.name()))); assertTrue(client.getObjectDatabase().has(blob1.toObjectId())); @@ -370,19 +345,14 @@ public class UploadPackTest { new DfsGarbageCollector(server2).pack(null); server2.scanForRepoChanges(); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(5); + tn.setFilterSpec(FilterSpec.withBlobLimit(5)); tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(commit.name()))); assertFalse( @@ -406,19 +376,14 @@ public class UploadPackTest { server2.getConfig().setBoolean("uploadpack", null, "allowfilter", false); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(0); + tn.setFilterSpec(FilterSpec.withBlobLimit(0)); thrown.expect(TransportException.class); thrown.expectMessage( @@ -453,6 +418,7 @@ public class UploadPackTest { ByteArrayOutputStream recv = new ByteArrayOutputStream(); up.upload(send, recv, null); + stats = up.getStatistics(); return new ByteArrayInputStream(recv.toByteArray()); } @@ -1551,6 +1517,324 @@ public class UploadPackTest { assertTrue(client.getObjectDatabase().has(small.toObjectId())); } + abstract class TreeBuilder { + abstract void addElements(DirCacheBuilder dcBuilder) throws Exception; + + RevTree build() throws Exception { + DirCache dc = DirCache.newInCore(); + DirCacheBuilder dcBuilder = dc.builder(); + addElements(dcBuilder); + dcBuilder.finish(); + ObjectId id; + try (ObjectInserter ins = + remote.getRepository().newObjectInserter()) { + id = dc.writeTree(ins); + ins.flush(); + } + return remote.getRevWalk().parseTree(id); + } + } + + class DeepTreePreparator { + RevBlob blobLowDepth = remote.blob("lo"); + RevBlob blobHighDepth = remote.blob("hi"); + + RevTree subtree = remote.tree(remote.file("1", blobHighDepth)); + RevTree rootTree = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.add(remote.file("1", blobLowDepth)); + dcBuilder.addTree(new byte[] {'2'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree); + } + }).build(); + RevCommit commit = remote.commit(rootTree); + + DeepTreePreparator() throws Exception {} + } + + private void uploadV2WithTreeDepthFilter( + long depth, ObjectId... wants) throws Exception { + server.getConfig().setBoolean("uploadpack", null, "allowfilter", true); + + List<String> input = new ArrayList(); + input.add("command=fetch\n"); + input.add(PacketLineIn.DELIM); + for (ObjectId want : wants) { + input.add("want " + want.getName() + "\n"); + } + input.add("filter tree:" + depth + "\n"); + input.add("done\n"); + input.add(PacketLineIn.END); + ByteArrayInputStream recvStream = + uploadPackV2(RequestPolicy.ANY, /*refFilter=*/null, + /*hook=*/null, input.toArray(new String[0])); + PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + } + + @Test + public void testV2FetchFilterTreeDepth0() throws Exception { + DeepTreePreparator preparator = new DeepTreePreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(0, preparator.commit.toObjectId()); + + assertFalse(client.getObjectDatabase() + .has(preparator.rootTree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.subtree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobLowDepth.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobHighDepth.toObjectId())); + assertEquals(1, stats.getTreesTraversed()); + } + + @Test + public void testV2FetchFilterTreeDepth1_serverHasBitmap() throws Exception { + DeepTreePreparator preparator = new DeepTreePreparator(); + remote.update("master", preparator.commit); + + // The bitmap should be ignored since we need to track the depth while + // traversing the trees. + generateBitmaps(server); + + uploadV2WithTreeDepthFilter(1, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.rootTree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.subtree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobLowDepth.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobHighDepth.toObjectId())); + assertEquals(1, stats.getTreesTraversed()); + } + + @Test + public void testV2FetchFilterTreeDepth2() throws Exception { + DeepTreePreparator preparator = new DeepTreePreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(2, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.rootTree.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.subtree.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.blobLowDepth.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobHighDepth.toObjectId())); + assertEquals(2, stats.getTreesTraversed()); + } + + /** + * Creates a commit with the following files: + * <pre> + * a/x/b/foo + * x/b/foo + * </pre> + * which has an identical tree in two locations: once at / and once at /a + */ + class RepeatedSubtreePreparator { + RevBlob foo = remote.blob("foo"); + RevTree subtree3 = remote.tree(remote.file("foo", foo)); + RevTree subtree2 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree3); + } + }).build(); + RevTree subtree1 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree2); + } + }).build(); + RevTree rootTree = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'a'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree1); + dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree2); + } + }).build(); + RevCommit commit = remote.commit(rootTree); + + RepeatedSubtreePreparator() throws Exception {} + } + + @Test + public void testV2FetchFilterTreeDepth_iterateOverTreeAtTwoLevels() + throws Exception { + // Test tree:<depth> where a tree is iterated to twice - once where a + // subentry is too deep to be included, and again where the blob inside + // it is shallow enough to be included. + RepeatedSubtreePreparator preparator = new RepeatedSubtreePreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(4, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + } + + /** + * Creates a commit with the following files: + * <pre> + * a/x/b/foo + * b/u/c/baz + * y/x/b/foo + * z/v/c/baz + * </pre> + * which has two pairs of identical trees: + * <ul> + * <li>one at /a and /y + * <li>one at /b/u and /z/v + * </ul> + * Note that this class defines unique 8 trees (rootTree and subtree1-7) + * which means PackStatistics should report having visited 8 trees. + */ + class RepeatedSubtreeAtSameLevelPreparator { + RevBlob foo = remote.blob("foo"); + + /** foo */ + RevTree subtree1 = remote.tree(remote.file("foo", foo)); + + /** b/foo */ + RevTree subtree2 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree1); + } + }).build(); + + /** x/b/foo */ + RevTree subtree3 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree2); + } + }).build(); + + RevBlob baz = remote.blob("baz"); + + /** baz */ + RevTree subtree4 = remote.tree(remote.file("baz", baz)); + + /** c/baz */ + RevTree subtree5 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'c'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree4); + } + }).build(); + + /** u/c/baz */ + RevTree subtree6 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'u'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree5); + } + }).build(); + + /** v/c/baz */ + RevTree subtree7 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'v'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree5); + } + }).build(); + + RevTree rootTree = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'a'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree3); + dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree6); + dcBuilder.addTree(new byte[] {'y'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree3); + dcBuilder.addTree(new byte[] {'z'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree7); + } + }).build(); + RevCommit commit = remote.commit(rootTree); + + RepeatedSubtreeAtSameLevelPreparator() throws Exception {} + } + + @Test + public void testV2FetchFilterTreeDepth_repeatTreeAtSameLevelIncludeFile() + throws Exception { + RepeatedSubtreeAtSameLevelPreparator preparator = + new RepeatedSubtreeAtSameLevelPreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(5, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.baz.toObjectId())); + assertEquals(8, stats.getTreesTraversed()); + } + + @Test + public void testV2FetchFilterTreeDepth_repeatTreeAtSameLevelExcludeFile() + throws Exception { + RepeatedSubtreeAtSameLevelPreparator preparator = + new RepeatedSubtreeAtSameLevelPreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(4, preparator.commit.toObjectId()); + + assertFalse(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.baz.toObjectId())); + assertEquals(8, stats.getTreesTraversed()); + } + + @Test + public void testWantFilteredObject() throws Exception { + RepeatedSubtreePreparator preparator = new RepeatedSubtreePreparator(); + remote.update("master", preparator.commit); + + // Specify wanted blob objects that are deep enough to be filtered. We + // should still upload them. + uploadV2WithTreeDepthFilter( + 3, + preparator.commit.toObjectId(), + preparator.foo.toObjectId()); + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + + client = newRepo("client"); + // Specify a wanted tree object that is deep enough to be filtered. We + // should still upload it. + uploadV2WithTreeDepthFilter( + 2, + preparator.commit.toObjectId(), + preparator.subtree3.toObjectId()); + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.subtree3.toObjectId())); + } + @Test public void testV2FetchFilterWhenNotAllowed() throws Exception { RevCommit commit = remote.commit().message("0").create(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java index 6f61912f2b..0303ea2404 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java @@ -582,26 +582,23 @@ public class FileTreeIteratorTest extends RepositoryTestCase { } } - private final FileTreeIterator.FileModeStrategy NO_GITLINKS_STRATEGY = - new FileTreeIterator.FileModeStrategy() { - @Override - public FileMode getMode(File f, FS.Attributes attributes) { - if (attributes.isSymbolicLink()) { - return FileMode.SYMLINK; - } else if (attributes.isDirectory()) { - // NOTE: in the production DefaultFileModeStrategy, there is - // a check here for a subdirectory called '.git', and if it - // exists, we create a GITLINK instead of recursing into the - // tree. In this custom strategy, we ignore nested git dirs - // and treat all directories the same. - return FileMode.TREE; - } else if (attributes.isExecutable()) { - return FileMode.EXECUTABLE_FILE; - } else { - return FileMode.REGULAR_FILE; - } - } - }; + private final FileTreeIterator.FileModeStrategy NO_GITLINKS_STRATEGY = ( + File f, FS.Attributes attributes) -> { + if (attributes.isSymbolicLink()) { + return FileMode.SYMLINK; + } else if (attributes.isDirectory()) { + // NOTE: in the production DefaultFileModeStrategy, there is + // a check here for a subdirectory called '.git', and if it + // exists, we create a GITLINK instead of recursing into the + // tree. In this custom strategy, we ignore nested git dirs + // and treat all directories the same. + return FileMode.TREE; + } else if (attributes.isExecutable()) { + return FileMode.EXECUTABLE_FILE; + } else { + return FileMode.REGULAR_FILE; + } + }; private Repository createNestedRepo() throws IOException { File gitdir = createUniqueTestGitDir(false); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java index d124d7365c..9981bd6514 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java @@ -128,6 +128,41 @@ public class RefListTest { } @Test + public void testBuilder_AddThenDedupe() { + RefList.Builder<Ref> builder = new RefList.Builder<>(1); + builder.add(REF_B); + builder.add(REF_A); + builder.add(REF_A); + builder.add(REF_B); + builder.add(REF_c); + + builder.sort(); + builder.dedupe((a, b) -> b); + RefList<Ref> list = builder.toRefList(); + + assertEquals(3, list.size()); + assertSame(REF_A, list.get(0)); + assertSame(REF_B, list.get(1)); + assertSame(REF_c, list.get(2)); + } + + @Test + public void testBuilder_AddThenDedupe_Border() { + RefList.Builder<Ref> builder = new RefList.Builder<>(1); + builder.sort(); + builder.dedupe((a, b) -> b); + RefList<Ref> list = builder.toRefList(); + assertTrue(list.isEmpty()); + + builder = new RefList.Builder<>(1); + builder.add(REF_A); + builder.sort(); + builder.dedupe((a, b) -> b); + list = builder.toRefList(); + assertEquals(1, list.size()); + } + + @Test public void testBuilder_AddAll() { RefList.Builder<Ref> builder = new RefList.Builder<>(1); Ref[] src = { REF_A, REF_B, REF_c, REF_A }; |