diff options
Diffstat (limited to 'javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java')
-rw-r--r-- | javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java | 168 |
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()); + } +} |