aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs')
-rw-r--r--org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java132
-rw-r--r--org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java252
-rw-r--r--org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java101
3 files changed, 485 insertions, 0 deletions
diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java
new file mode 100644
index 0000000000..6c4f3cbb99
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/DownloadTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+
+import org.apache.http.client.ClientProtocolException;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.Test;
+
+public class DownloadTest extends LfsServerTest {
+
+ @Test
+ public void testDownload() throws Exception {
+ String TEXT = "test";
+ AnyLongObjectId id = putContent(TEXT);
+ Path f = Paths.get(getTempDirectory().toString(), "download");
+ long len = getContent(id, f);
+ assertEquals(TEXT.length(), len);
+ FileUtils.delete(f.toFile(), FileUtils.RETRY);
+ }
+
+ @Test
+ public void testDownloadInvalidPathInfo()
+ throws ClientProtocolException, IOException {
+ String TEXT = "test";
+ AnyLongObjectId id = putContent(TEXT);
+ Path f = Paths.get(getTempDirectory().toString(), "download");
+ try {
+ getContent(id.name().substring(0, 60), f);
+ fail("expected RuntimeException");
+ } catch (RuntimeException e) {
+ assertEquals("Status: 400 Bad Request",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDownloadInvalidId()
+ throws ClientProtocolException, IOException {
+ String TEXT = "test";
+ AnyLongObjectId id = putContent(TEXT);
+ Path f = Paths.get(getTempDirectory().toString(), "download");
+ try {
+ getContent(id.name().replace('f', 'z'), f);
+ fail("expected RuntimeException");
+ } catch (RuntimeException e) {
+ assertEquals("Status: 400 Bad Request",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testDownloadNotFound()
+ throws ClientProtocolException, IOException {
+ String TEXT = "test";
+ AnyLongObjectId id = LongObjectIdTestUtils.hash(TEXT);
+ Path f = Paths.get(getTempDirectory().toString(), "download");
+ try {
+ getContent(id, f);
+ fail("expected RuntimeException");
+ } catch (RuntimeException e) {
+ assertEquals("Status: 404 Not Found",
+ e.getMessage());
+ }
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testLargeFileDownload() throws Exception {
+ Path f = Paths.get(getTempDirectory().toString(), "largeRandomFile");
+ long expectedLen = createPseudoRandomContentFile(f, 5 * MiB);
+ AnyLongObjectId id = putContent(f);
+ Path f2 = Paths.get(getTempDirectory().toString(), "download");
+ long start = System.nanoTime();
+ long len = getContent(id, f2);
+ System.out.println(
+ MessageFormat.format("dowloaded 10 MiB random data in {0}ms",
+ (System.nanoTime() - start) / 1e6));
+ assertEquals(expectedLen, len);
+ FileUtils.delete(f.toFile(), FileUtils.RETRY);
+
+ }
+}
diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java
new file mode 100644
index 0000000000..8c266d4830
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.security.DigestInputStream;
+import java.security.SecureRandom;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jgit.junit.http.AppServer;
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+
+@SuppressWarnings("restriction")
+public abstract class LfsServerTest {
+
+ private static final long timeout = /* 10 sec */ 10 * 1000;
+
+ protected static final int MiB = 1024 * 1024;
+
+ /** In-memory application server; subclass must start. */
+ protected AppServer server;
+
+ private Path tmp;
+
+ private Path dir;
+
+ protected FileLfsRepository repository;
+
+ protected FileLfsServlet servlet;
+
+ public LfsServerTest() {
+ super();
+ }
+
+ public Path getTempDirectory() {
+ return tmp;
+ }
+
+ public Path getDir() {
+ return dir;
+ }
+
+ @Before
+ public void setup() throws Exception {
+ tmp = Files.createTempDirectory("jgit_test_");
+ server = new AppServer();
+ ServletContextHandler app = server.addContext("/lfs");
+ dir = Paths.get(tmp.toString(), "lfs");
+ this.repository = new FileLfsRepository(null, dir);
+ servlet = new FileLfsServlet(repository, timeout);
+ app.addServlet(new ServletHolder(servlet), "/objects/*");
+ server.setUp();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ server.tearDown();
+ FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY);
+ }
+
+ protected AnyLongObjectId putContent(String s)
+ throws IOException, ClientProtocolException {
+ AnyLongObjectId id = LongObjectIdTestUtils.hash(s);
+ return putContent(id, s);
+ }
+
+ protected AnyLongObjectId putContent(AnyLongObjectId id, String s)
+ throws ClientProtocolException, IOException {
+ try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+ HttpEntity entity = new StringEntity(s,
+ ContentType.APPLICATION_OCTET_STREAM);
+ String hexId = id.name();
+ HttpPut request = new HttpPut(
+ server.getURI() + "/lfs/objects/" + hexId);
+ request.setEntity(entity);
+ try (CloseableHttpResponse response = client.execute(request)) {
+ StatusLine statusLine = response.getStatusLine();
+ int status = statusLine.getStatusCode();
+ if (status >= 400) {
+ throw new RuntimeException("Status: " + status + ". "
+ + statusLine.getReasonPhrase());
+ }
+ }
+ return id;
+ }
+ }
+
+ protected LongObjectId putContent(Path f)
+ throws FileNotFoundException, IOException {
+ try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+ LongObjectId id1, id2;
+ String hexId1, hexId2;
+ try (DigestInputStream in = new DigestInputStream(
+ new BufferedInputStream(Files.newInputStream(f)),
+ Constants.newMessageDigest())) {
+ InputStreamEntity entity = new InputStreamEntity(in,
+ Files.size(f), ContentType.APPLICATION_OCTET_STREAM);
+ id1 = LongObjectIdTestUtils.hash(f);
+ hexId1 = id1.name();
+ HttpPut request = new HttpPut(
+ server.getURI() + "/lfs/objects/" + hexId1);
+ request.setEntity(entity);
+ HttpResponse response = client.execute(request);
+ checkResponseStatus(response);
+ id2 = LongObjectId.fromRaw(in.getMessageDigest().digest());
+ hexId2 = id2.name();
+ assertEquals(hexId1, hexId2);
+ }
+ return id1;
+ }
+ }
+
+ private void checkResponseStatus(HttpResponse response) {
+ StatusLine statusLine = response.getStatusLine();
+ int status = statusLine.getStatusCode();
+ if (statusLine.getStatusCode() >= 400) {
+ throw new RuntimeException("Status: " + status + " "
+ + statusLine.getReasonPhrase());
+ }
+ assertEquals(200, status);
+ }
+
+ protected long getContent(AnyLongObjectId id, Path f) throws IOException {
+ String hexId = id.name();
+ return getContent(hexId, f);
+ }
+
+ protected long getContent(String hexId, Path f) throws IOException {
+ try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
+ HttpGet request = new HttpGet(
+ server.getURI() + "/lfs/objects/" + hexId);
+ HttpResponse response = client.execute(request);
+ checkResponseStatus(response);
+ HttpEntity entity = response.getEntity();
+ long pos = 0;
+ try (InputStream in = entity.getContent();
+ ReadableByteChannel inChannel = Channels.newChannel(in);
+ FileChannel outChannel = FileChannel.open(f,
+ StandardOpenOption.CREATE_NEW,
+ StandardOpenOption.WRITE)) {
+ long transferred;
+ do {
+ transferred = outChannel.transferFrom(inChannel, pos, MiB);
+ pos += transferred;
+ } while (transferred > 0);
+ }
+ return pos;
+ }
+ }
+
+ /**
+ * Creates a file with random content, repeatedly writing a random string of
+ * 4k length to the file until the file has at least the specified length.
+ *
+ * @param f
+ * file to fill
+ * @param size
+ * size of the file to generate
+ * @return length of the generated file in bytes
+ * @throws IOException
+ */
+ protected long createPseudoRandomContentFile(Path f, long size)
+ throws IOException {
+ SecureRandom rnd = new SecureRandom();
+ byte[] buf = new byte[4096];
+ rnd.nextBytes(buf);
+ ByteBuffer bytebuf = ByteBuffer.wrap(buf);
+ try (FileChannel outChannel = FileChannel.open(f,
+ StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) {
+ long len = 0;
+ do {
+ len += outChannel.write(bytebuf);
+ if (bytebuf.position() == 4096) {
+ bytebuf.rewind();
+ }
+ } while (len < size);
+ }
+ return Files.size(f);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java
new file mode 100644
index 0000000000..35bf09b0c1
--- /dev/null
+++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015, Matthias Sohn <matthias.sohnk@sap.com>
+ * 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.lfs.server.fs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
+import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils;
+import org.junit.Test;
+
+public class UploadTest extends LfsServerTest {
+
+ @Test
+ public void testUpload() throws Exception {
+ String TEXT = "test";
+ AnyLongObjectId id = putContent(TEXT);
+ assertTrue("expect object " + id.name() + " to exist",
+ repository.getSize(id) >= 0);
+ assertEquals("expected object length " + TEXT.length(), TEXT.length(),
+ repository.getSize(id));
+ }
+
+ @Test
+ public void testCorruptUpload() throws Exception {
+ String TEXT = "test";
+ AnyLongObjectId id = LongObjectIdTestUtils.hash("wrongHash");
+ try {
+ putContent(id, TEXT);
+ fail("expected RuntimeException(\"Status 400\")");
+ } catch (RuntimeException e) {
+ assertEquals("Status: 400. Bad Request", e.getMessage());
+ }
+ assertFalse("expect object " + id.name() + " not to exist",
+ repository.getSize(id) >= 0);
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testLargeFileUpload() throws Exception {
+ Path f = Paths.get(getTempDirectory().toString(), "largeRandomFile");
+ createPseudoRandomContentFile(f, 5 * MiB);
+ long start = System.nanoTime();
+ LongObjectId id = putContent(f);
+ System.out.println(
+ MessageFormat.format("uploaded 10 MiB random data in {0}ms",
+ (System.nanoTime() - start) / 1e6));
+ assertTrue("expect object " + id.name() + " to exist",
+ repository.getSize(id) >= 0);
+ assertEquals("expected object length " + Files.size(f), Files.size(f),
+ repository.getSize(id));
+ }
+}