summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2018-07-24 08:41:17 -0700
committerJonathan Nieder <jrn@google.com>2018-08-10 18:44:49 -0400
commitc477b0ddcb68ac0b1c26270187d82fccc70802c6 (patch)
tree7609991fe05b4fd48b0b14709dc58d2ec1811ead /org.eclipse.jgit.test
parentbd1a82502680b5de5bf86f6c4470185fd1602386 (diff)
downloadjgit-c477b0ddcb68ac0b1c26270187d82fccc70802c6.tar.gz
jgit-c477b0ddcb68ac0b1c26270187d82fccc70802c6.zip
Support protocol v2 want-ref in UploadPack
UploadPack already allows the client to send wanted OIDs as "want" lines. Extend UploadPack to also allow the client to send wanted ref names as "want-ref" lines when the fetch is done using protocol v2. The corresponding Git commit is 516e2b76bd ("upload-pack: implement ref-in-want", 2018-06-28). To support a two-stage rollout, two configuration variables are provided: uploadpack.allowrefinwant (default "false") allows clients to specify "want-ref" in their requests, and uploadpack.advertiserefinwant (default "true") makes UploadPack advertise this capability. If uploadpack.allowrefinwant is true but uploadpack.advertiserefinwant is false, UploadPack will not advertise that it supports "want-ref", but it will support it. Change-Id: I3c24077949640d453af90d81a7f48ce4b8ac9833 Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java219
1 files changed, 219 insertions, 0 deletions
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 9f49073eae..7ef713bf45 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
@@ -1,11 +1,13 @@
package org.eclipse.jgit.transport;
+import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.theInstance;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.Collections;
@@ -505,6 +507,51 @@ public class UploadPackTest {
}
@Test
+ public void testV2CapabilitiesRefInWant() throws Exception {
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+ ByteArrayInputStream recvStream =
+ uploadPackV2Setup(null, null, PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ assertThat(pckIn.readString(), is("version 2"));
+ assertThat(
+ Arrays.asList(pckIn.readString(), pckIn.readString()),
+ // TODO(jonathantanmy) This check overspecifies the
+ // order of the capabilities of "fetch".
+ hasItems("ls-refs", "fetch=ref-in-want shallow"));
+ assertTrue(pckIn.readString() == PacketLineIn.END);
+ }
+
+ @Test
+ public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception {
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", false);
+ ByteArrayInputStream recvStream =
+ uploadPackV2Setup(null, null, PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ assertThat(pckIn.readString(), is("version 2"));
+ assertThat(
+ Arrays.asList(pckIn.readString(), pckIn.readString()),
+ hasItems("ls-refs", "fetch=shallow"));
+ assertTrue(pckIn.readString() == PacketLineIn.END);
+ }
+
+ @Test
+ public void testV2CapabilitiesRefInWantNotAdvertisedIfAdvertisingForbidden() throws Exception {
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+ server.getConfig().setBoolean("uploadpack", null, "advertiserefinwant", false);
+ ByteArrayInputStream recvStream =
+ uploadPackV2Setup(null, null, PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ assertThat(pckIn.readString(), is("version 2"));
+ assertThat(
+ Arrays.asList(pckIn.readString(), pckIn.readString()),
+ hasItems("ls-refs", "fetch=shallow"));
+ assertTrue(pckIn.readString() == PacketLineIn.END);
+ }
+
+ @Test
@SuppressWarnings("boxing")
public void testV2EmptyRequest() throws Exception {
ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.END);
@@ -1161,6 +1208,178 @@ public class UploadPackTest {
PacketLineIn.END);
}
+ @Test
+ public void testV2FetchWantRefIfNotAllowed() throws Exception {
+ RevCommit one = remote.commit().message("1").create();
+ remote.update("one", one);
+
+ try {
+ uploadPackV2(
+ "command=fetch\n",
+ PacketLineIn.DELIM,
+ "want-ref refs/heads/one\n",
+ "done\n",
+ PacketLineIn.END);
+ } catch (PackProtocolException e) {
+ assertThat(
+ e.getMessage(),
+ containsString("unexpected want-ref refs/heads/one"));
+ return;
+ }
+ fail("expected PackProtocolException");
+ }
+
+ @Test
+ public void testV2FetchWantRef() throws Exception {
+ RevCommit one = remote.commit().message("1").create();
+ RevCommit two = remote.commit().message("2").create();
+ RevCommit three = remote.commit().message("3").create();
+ remote.update("one", one);
+ remote.update("two", two);
+ remote.update("three", three);
+
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+
+ ByteArrayInputStream recvStream = uploadPackV2(
+ "command=fetch\n",
+ PacketLineIn.DELIM,
+ "want-ref refs/heads/one\n",
+ "want-ref refs/heads/two\n",
+ "done\n",
+ PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+ assertThat(pckIn.readString(), is("wanted-refs"));
+ assertThat(
+ Arrays.asList(pckIn.readString(), pckIn.readString()),
+ hasItems(
+ one.toObjectId().getName() + " refs/heads/one",
+ two.toObjectId().getName() + " refs/heads/two"));
+ assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM));
+ assertThat(pckIn.readString(), is("packfile"));
+ parsePack(recvStream);
+
+ assertTrue(client.hasObject(one.toObjectId()));
+ assertTrue(client.hasObject(two.toObjectId()));
+ assertFalse(client.hasObject(three.toObjectId()));
+ }
+
+ @Test
+ public void testV2FetchBadWantRef() throws Exception {
+ RevCommit one = remote.commit().message("1").create();
+ remote.update("one", one);
+
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+
+ try {
+ uploadPackV2(
+ "command=fetch\n",
+ PacketLineIn.DELIM,
+ "want-ref refs/heads/one\n",
+ "want-ref refs/heads/nonExistentRef\n",
+ "done\n",
+ PacketLineIn.END);
+ } catch (PackProtocolException e) {
+ assertThat(
+ e.getMessage(),
+ containsString("Invalid ref name: refs/heads/nonExistentRef"));
+ return;
+ }
+ fail("expected PackProtocolException");
+ }
+
+ @Test
+ public void testV2FetchMixedWantRef() throws Exception {
+ RevCommit one = remote.commit().message("1").create();
+ RevCommit two = remote.commit().message("2").create();
+ RevCommit three = remote.commit().message("3").create();
+ remote.update("one", one);
+ remote.update("two", two);
+ remote.update("three", three);
+
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+
+ ByteArrayInputStream recvStream = uploadPackV2(
+ "command=fetch\n",
+ PacketLineIn.DELIM,
+ "want-ref refs/heads/one\n",
+ "want " + two.toObjectId().getName() + "\n",
+ "done\n",
+ PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+ assertThat(pckIn.readString(), is("wanted-refs"));
+ assertThat(
+ pckIn.readString(),
+ is(one.toObjectId().getName() + " refs/heads/one"));
+ assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM));
+ assertThat(pckIn.readString(), is("packfile"));
+ parsePack(recvStream);
+
+ assertTrue(client.hasObject(one.toObjectId()));
+ assertTrue(client.hasObject(two.toObjectId()));
+ assertFalse(client.hasObject(three.toObjectId()));
+ }
+
+ @Test
+ public void testV2FetchWantRefWeAlreadyHave() throws Exception {
+ RevCommit one = remote.commit().message("1").create();
+ remote.update("one", one);
+
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+
+ ByteArrayInputStream recvStream = uploadPackV2(
+ "command=fetch\n",
+ PacketLineIn.DELIM,
+ "want-ref refs/heads/one\n",
+ "have " + one.toObjectId().getName(),
+ "done\n",
+ PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ // The client still needs to know the hash of the object that
+ // refs/heads/one points to, even though it already has the
+ // object ...
+ assertThat(pckIn.readString(), is("wanted-refs"));
+ assertThat(
+ pckIn.readString(),
+ is(one.toObjectId().getName() + " refs/heads/one"));
+ assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM));
+
+ // ... but the client does not need the object itself.
+ assertThat(pckIn.readString(), is("packfile"));
+ parsePack(recvStream);
+ assertFalse(client.hasObject(one.toObjectId()));
+ }
+
+ @Test
+ public void testV2FetchWantRefAndDeepen() throws Exception {
+ RevCommit parent = remote.commit().message("parent").create();
+ RevCommit child = remote.commit().message("x").parent(parent).create();
+ remote.update("branch1", child);
+
+ server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+
+ ByteArrayInputStream recvStream = uploadPackV2(
+ "command=fetch\n",
+ PacketLineIn.DELIM,
+ "want-ref refs/heads/branch1\n",
+ "deepen 1\n",
+ "done\n",
+ PacketLineIn.END);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ // wanted-refs appears first, then shallow-info.
+ assertThat(pckIn.readString(), is("wanted-refs"));
+ assertThat(pckIn.readString(), is(child.toObjectId().getName() + " refs/heads/branch1"));
+ assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM));
+ assertThat(pckIn.readString(), is("shallow-info"));
+ assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName()));
+ assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM));
+ assertThat(pckIn.readString(), is("packfile"));
+ parsePack(recvStream);
+ assertTrue(client.hasObject(child.toObjectId()));
+ assertFalse(client.hasObject(parent.toObjectId()));
+ }
+
private static class RejectAllRefFilter implements RefFilter {
@Override
public Map<String, Ref> filter(Map<String, Ref> refs) {