summaryrefslogtreecommitdiffstats
path: root/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
diff options
context:
space:
mode:
Diffstat (limited to 'javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java')
-rw-r--r--javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java168
1 files changed, 168 insertions, 0 deletions
diff --git a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
new file mode 100644
index 0000000000..93fc769025
--- /dev/null
+++ b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
@@ -0,0 +1,168 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.acceptance.ssh;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
+
+import com.google.common.base.Splitter;
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.GerritConfig;
+import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.UseSsh;
+import com.google.gerrit.testing.NoteDbMode;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
+import org.eclipse.jgit.transport.PacketLineIn;
+import org.eclipse.jgit.transport.PacketLineOut;
+import org.eclipse.jgit.util.IO;
+import org.junit.Before;
+import org.junit.Test;
+
+@NoHttpd
+@UseSsh
+public class UploadArchiveIT extends AbstractDaemonTest {
+
+ @Before
+ public void setUp() {
+ // There is some Guice request scoping problem preventing this test from
+ // passing in CHECK mode.
+ assume().that(NoteDbMode.get()).isNotEqualTo(NoteDbMode.CHECK);
+ }
+
+ @Test
+ @GerritConfig(name = "download.archive", value = "off")
+ public void archiveFeatureOff() throws Exception {
+ assertArchiveNotPermitted();
+ }
+
+ @Test
+ @GerritConfig(
+ name = "download.archive",
+ values = {"tar", "tbz2", "tgz", "txz"})
+ public void zipFormatDisabled() throws Exception {
+ assertArchiveNotPermitted();
+ }
+
+ @Test
+ public void zipFormat() throws Exception {
+ PushOneCommit.Result r = createChange();
+ String abbreviated = r.getCommit().abbreviate(8).name();
+ String c = command(r, "zip", abbreviated);
+
+ InputStream out =
+ adminSshSession.exec2("git-upload-archive " + project.get(), argumentsToInputStream(c));
+
+ // Wrap with PacketLineIn to read ACK bytes from output stream
+ PacketLineIn in = new PacketLineIn(out);
+ String tmp = in.readString();
+ assertThat(tmp).isEqualTo("ACK");
+ in.readString();
+
+ // Skip length (4 bytes) + 1 byte
+ // to position the output stream to the raw zip stream
+ byte[] buffer = new byte[5];
+ IO.readFully(out, buffer, 0, 5);
+ Set<String> entryNames = new TreeSet<>();
+ try (ZipArchiveInputStream zip = new ZipArchiveInputStream(out)) {
+ ZipArchiveEntry zipEntry = zip.getNextZipEntry();
+ while (zipEntry != null) {
+ String name = zipEntry.getName();
+ entryNames.add(name);
+ zipEntry = zip.getNextZipEntry();
+ }
+ }
+
+ assertThat(entryNames)
+ .containsExactly(
+ String.format("%s/", abbreviated),
+ String.format("%s/%s", abbreviated, PushOneCommit.FILE_NAME))
+ .inOrder();
+ }
+
+ // Make sure we have coverage for the dependency on xz.
+ @Test
+ public void txzFormat() throws Exception {
+ PushOneCommit.Result r = createChange();
+ String abbreviated = r.getCommit().abbreviate(8).name();
+ String c = command(r, "tar.xz", abbreviated);
+
+ try (InputStream out =
+ adminSshSession.exec2("git-upload-archive " + project.get(), argumentsToInputStream(c))) {
+
+ // Wrap with PacketLineIn to read ACK bytes from output stream
+ PacketLineIn in = new PacketLineIn(out);
+ String packet = in.readString();
+ assertThat(packet).isEqualTo("ACK");
+
+ // Discard first bit of data, which should be empty.
+ packet = in.readString();
+ assertThat(packet).isEmpty();
+
+ // Make sure the next one is not on the error channel
+ packet = in.readString();
+
+ // 1 = DATA. It would be nicer to parse the OutputStream with SideBandInputStream from JGit,
+ // but
+ // that is currently not public.
+ char channel = packet.charAt(0);
+ if (channel != 1) {
+ fail("got packet on channel " + (int) channel, packet);
+ }
+ }
+ }
+
+ private String command(PushOneCommit.Result r, String format, String abbreviated) {
+ String c =
+ String.format(
+ "-f=%s --prefix=%s/ %s %s",
+ format, abbreviated, r.getCommit().name(), PushOneCommit.FILE_NAME);
+ return c;
+ }
+
+ private void assertArchiveNotPermitted() throws Exception {
+ PushOneCommit.Result r = createChange();
+ String abbreviated = r.getCommit().abbreviate(8).name();
+ String c = command(r, "zip", abbreviated);
+
+ InputStream out =
+ adminSshSession.exec2("git-upload-archive " + project.get(), argumentsToInputStream(c));
+
+ // Wrap with PacketLineIn to read ACK bytes from output stream
+ PacketLineIn in = new PacketLineIn(out);
+ String tmp = in.readString();
+ assertThat(tmp).isEqualTo("ACK");
+ in.readString();
+ tmp = in.readString();
+ tmp = tmp.substring(1);
+ assertThat(tmp).isEqualTo("fatal: upload-archive not permitted for format zip");
+ }
+
+ private InputStream argumentsToInputStream(String c) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PacketLineOut pctOut = new PacketLineOut(out);
+ for (String arg : Splitter.on(' ').split(c)) {
+ pctOut.writeString("argument " + arg);
+ }
+ pctOut.end();
+ return new ByteArrayInputStream(out.toByteArray());
+ }
+}