From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001
From: Paul Martin <paul@paulsputer.com>
Date: Sat, 30 Apr 2016 04:19:14 -0400
Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates

---
 src/test/java/com/gitblit/tests/FilestoreServletTest.java |  355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 355 insertions(+), 0 deletions(-)

diff --git a/src/test/java/com/gitblit/tests/FilestoreServletTest.java b/src/test/java/com/gitblit/tests/FilestoreServletTest.java
new file mode 100644
index 0000000..4e4b056
--- /dev/null
+++ b/src/test/java/com/gitblit/tests/FilestoreServletTest.java
@@ -0,0 +1,355 @@
+package com.gitblit.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.gitblit.Keys;
+import com.gitblit.manager.FilestoreManager;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.UserModel;
+import com.gitblit.models.FilestoreModel.Status;
+import com.gitblit.servlet.FilestoreServlet;
+import com.gitblit.utils.FileUtils;
+
+public class FilestoreServletTest extends GitblitUnitTest {
+	
+	private static final AtomicBoolean started = new AtomicBoolean(false);
+	
+	private static final String SHA256_EG = "9a712c5d4037503a2d5ee1d07ad191eb99d051e84cbb020c171a5ae19bbe3cbd";
+	
+	private static final String repoName = "helloworld.git";
+	
+    private static final String repoLfs = "/r/" + repoName + "/info/lfs/objects/";
+	
+	@BeforeClass
+	public static void startGitblit() throws Exception {
+		started.set(GitBlitSuite.startGitblit());
+	}
+
+	@AfterClass
+	public static void stopGitblit() throws Exception {
+		if (started.get()) {
+			GitBlitSuite.stopGitblit();
+		}
+	}
+	
+	
+	@Test
+	public void testRegexGroups() throws Exception {
+		
+		Pattern p = Pattern.compile(FilestoreServlet.REGEX_PATH);
+		
+		String basicUrl = "https://localhost:8080/r/test.git/info/lfs/objects/";
+		String batchUrl = basicUrl + "batch";
+		String oidUrl = basicUrl + SHA256_EG; 
+		
+        Matcher m = p.matcher(batchUrl);
+        assertTrue(m.find());
+        assertEquals("https://localhost:8080", m.group(FilestoreServlet.REGEX_GROUP_BASE_URI));
+        assertEquals("r", m.group(FilestoreServlet.REGEX_GROUP_PREFIX));
+        assertEquals("test.git", m.group(FilestoreServlet.REGEX_GROUP_REPOSITORY));
+        assertEquals("batch", m.group(FilestoreServlet.REGEX_GROUP_ENDPOINT));
+        
+        m = p.matcher(oidUrl);
+        assertTrue(m.find());
+        assertEquals("https://localhost:8080", m.group(FilestoreServlet.REGEX_GROUP_BASE_URI));
+        assertEquals("r", m.group(FilestoreServlet.REGEX_GROUP_PREFIX));
+        assertEquals("test.git", m.group(FilestoreServlet.REGEX_GROUP_REPOSITORY));
+        assertEquals(SHA256_EG, m.group(FilestoreServlet.REGEX_GROUP_ENDPOINT));
+	}
+	
+	@Test
+	public void testRegexGroupsNestedRepo() throws Exception {
+		
+		Pattern p = Pattern.compile(FilestoreServlet.REGEX_PATH);
+		
+		String basicUrl = "https://localhost:8080/r/nested/test.git/info/lfs/objects/";
+		String batchUrl = basicUrl + "batch";
+		String oidUrl = basicUrl + SHA256_EG; 
+		
+        Matcher m = p.matcher(batchUrl);
+        assertTrue(m.find());
+        assertEquals("https://localhost:8080", m.group(FilestoreServlet.REGEX_GROUP_BASE_URI));
+        assertEquals("r", m.group(FilestoreServlet.REGEX_GROUP_PREFIX));
+        assertEquals("nested/test.git", m.group(FilestoreServlet.REGEX_GROUP_REPOSITORY));
+        assertEquals("batch", m.group(FilestoreServlet.REGEX_GROUP_ENDPOINT));
+        
+        m = p.matcher(oidUrl);
+        assertTrue(m.find());
+        assertEquals("https://localhost:8080", m.group(FilestoreServlet.REGEX_GROUP_BASE_URI));
+        assertEquals("r", m.group(FilestoreServlet.REGEX_GROUP_PREFIX));
+        assertEquals("nested/test.git", m.group(FilestoreServlet.REGEX_GROUP_REPOSITORY));
+        assertEquals(SHA256_EG, m.group(FilestoreServlet.REGEX_GROUP_ENDPOINT));
+	}
+	
+	@Test
+	public void testDownload() throws Exception {
+		
+		FileUtils.delete(filestore().getStorageFolder());
+		filestore().clearFilestoreCache();
+		
+		RepositoryModel r =  gitblit().getRepositoryModel(repoName);
+		
+		UserModel u = new UserModel("admin");
+		u.canAdmin = true;
+
+		//No upload limit
+		settings().overrideSetting(Keys.filestore.maxUploadSize, FilestoreManager.UNDEFINED_SIZE);
+
+		final BlobInfo blob = new BlobInfo(512*FileUtils.KB);
+		
+		//Emulate a pre-existing Git-LFS repository by using using internal pre-tested methods
+		assertEquals(Status.Available, filestore().uploadBlob(blob.hash, blob.length, u, r, new ByteArrayInputStream(blob.blob)));
+		
+        final String downloadURL = GitBlitSuite.url + repoLfs + blob.hash;
+        
+        HttpClient client = HttpClientBuilder.create().build();
+    	HttpGet request = new HttpGet(downloadURL);
+
+    	// add request header
+    	request.addHeader(HttpHeaders.ACCEPT, FilestoreServlet.GIT_LFS_META_MIME);
+    	HttpResponse response = client.execute(request);
+    	
+		assertEquals(200, response.getStatusLine().getStatusCode());
+
+		String content = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+		
+		String expectedContent = String.format("{%s:%s,%s:%d,%s:{%s:{%s:%s}}}",
+				"\"oid\"", "\"" + blob.hash + "\"",
+				"\"size\"", blob.length,
+				"\"actions\"",
+				"\"download\"",
+				"\"href\"", "\"" + downloadURL + "\"");
+		
+		assertEquals(expectedContent, content);
+		
+		
+		//Now try the binary download
+		request.removeHeaders(HttpHeaders.ACCEPT);
+		response = client.execute(request);
+		
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		
+		byte[] dlData = IOUtils.toByteArray(response.getEntity().getContent());
+				
+		assertArrayEquals(blob.blob,  dlData);
+		
+	}
+	
+	@Test
+	public void testDownloadMultiple() throws Exception {
+		
+		FileUtils.delete(filestore().getStorageFolder());
+		filestore().clearFilestoreCache();
+		
+		RepositoryModel r =  gitblit().getRepositoryModel(repoName);
+		
+		UserModel u = new UserModel("admin");
+		u.canAdmin = true;
+
+		//No upload limit
+		settings().overrideSetting(Keys.filestore.maxUploadSize, FilestoreManager.UNDEFINED_SIZE);
+
+		final BlobInfo blob = new BlobInfo(512*FileUtils.KB);
+		
+		//Emulate a pre-existing Git-LFS repository by using using internal pre-tested methods
+		assertEquals(Status.Available, filestore().uploadBlob(blob.hash, blob.length, u, r, new ByteArrayInputStream(blob.blob)));
+		
+        final String batchURL = GitBlitSuite.url + repoLfs + "batch";
+		final String downloadURL = GitBlitSuite.url + repoLfs + blob.hash;
+        
+        HttpClient client = HttpClientBuilder.create().build();
+    	HttpPost request = new HttpPost(batchURL);
+
+    	// add request header
+    	request.addHeader(HttpHeaders.ACCEPT, FilestoreServlet.GIT_LFS_META_MIME);
+    	request.addHeader(HttpHeaders.CONTENT_ENCODING, FilestoreServlet.GIT_LFS_META_MIME);
+    	
+    	String content = String.format("{%s:%s,%s:[{%s:%s,%s:%d},{%s:%s,%s:%d}]}",
+    			"\"operation\"", "\"download\"",
+    			"\"objects\"",
+    			"\"oid\"", "\"" + blob.hash + "\"",
+    			"\"size\"", blob.length,
+    			"\"oid\"", "\"" + SHA256_EG + "\"",
+    			"\"size\"", 0);
+    	
+    	HttpEntity entity = new ByteArrayEntity(content.getBytes("UTF-8"));
+    	request.setEntity(entity);
+
+    	HttpResponse response = client.execute(request);
+    	
+    	String responseMessage = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+		assertEquals(200, response.getStatusLine().getStatusCode());
+
+		String expectedContent = String.format("{%s:[{%s:%s,%s:%d,%s:{%s:{%s:%s}}},{%s:%s,%s:%d,%s:{%s:%s,%s:%d}}]}",
+				"\"objects\"",
+				"\"oid\"", "\"" + blob.hash + "\"",
+				"\"size\"", blob.length,
+				"\"actions\"",
+				"\"download\"",
+				"\"href\"", "\"" + downloadURL + "\"",
+				"\"oid\"", "\"" + SHA256_EG + "\"",
+				"\"size\"", 0,
+				"\"error\"",
+				"\"message\"", "\"Object not available\"",
+				"\"code\"", 404
+				);
+		
+		assertEquals(expectedContent, responseMessage);
+	}
+	
+	@Test
+	public void testDownloadUnavailable() throws Exception {
+		
+		FileUtils.delete(filestore().getStorageFolder());
+		filestore().clearFilestoreCache();
+		
+		//No upload limit
+		settings().overrideSetting(Keys.filestore.maxUploadSize, FilestoreManager.UNDEFINED_SIZE);
+
+		final BlobInfo blob = new BlobInfo(512*FileUtils.KB);
+		
+        final String downloadURL = GitBlitSuite.url + repoLfs + blob.hash;
+        
+        HttpClient client = HttpClientBuilder.create().build();
+    	HttpGet request = new HttpGet(downloadURL);
+
+    	// add request header
+    	request.addHeader(HttpHeaders.ACCEPT, FilestoreServlet.GIT_LFS_META_MIME);
+    	HttpResponse response = client.execute(request);
+    	
+		assertEquals(404, response.getStatusLine().getStatusCode());
+
+		String content = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+		
+		String expectedError = String.format("{%s:%s,%s:%d}",
+				"\"message\"", "\"Object not available\"",
+				"\"code\"", 404);
+		
+		assertEquals(expectedError, content);
+	}
+	
+	@Test
+	public void testUpload() throws Exception {
+		
+		FileUtils.delete(filestore().getStorageFolder());
+		filestore().clearFilestoreCache();
+		
+		RepositoryModel r =  gitblit().getRepositoryModel(repoName);
+		
+		UserModel u = new UserModel("admin");
+		u.canAdmin = true;
+
+		//No upload limit
+		settings().overrideSetting(Keys.filestore.maxUploadSize, FilestoreManager.UNDEFINED_SIZE);
+
+		final BlobInfo blob = new BlobInfo(512*FileUtils.KB);
+        
+        final String expectedUploadURL = GitBlitSuite.url + repoLfs + blob.hash;
+        final String initialUploadURL = GitBlitSuite.url + repoLfs + "batch";
+        
+        HttpClient client = HttpClientBuilder.create().build();
+    	HttpPost request = new HttpPost(initialUploadURL);
+
+    	// add request header
+    	request.addHeader(HttpHeaders.ACCEPT, FilestoreServlet.GIT_LFS_META_MIME);
+    	request.addHeader(HttpHeaders.CONTENT_ENCODING, FilestoreServlet.GIT_LFS_META_MIME);
+    	
+    	String content = String.format("{%s:%s,%s:[{%s:%s,%s:%d}]}",
+    			"\"operation\"", "\"upload\"",
+    			"\"objects\"",
+    			"\"oid\"", "\"" + blob.hash + "\"",
+    			"\"size\"", blob.length);
+    	
+    	HttpEntity entity = new ByteArrayEntity(content.getBytes("UTF-8"));
+    	request.setEntity(entity);
+    	
+    	HttpResponse response = client.execute(request);
+    	String responseMessage = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+		assertEquals(200, response.getStatusLine().getStatusCode());
+
+		String expectedContent = String.format("{%s:[{%s:%s,%s:%d,%s:{%s:{%s:%s}}}]}",
+				"\"objects\"",
+				"\"oid\"", "\"" + blob.hash + "\"",
+				"\"size\"", blob.length,
+				"\"actions\"",
+				"\"upload\"",
+				"\"href\"", "\"" + expectedUploadURL + "\"");
+		
+		assertEquals(expectedContent, responseMessage);
+		
+		
+		//Now try to upload the binary download
+		HttpPut putRequest = new HttpPut(expectedUploadURL);
+		putRequest.setEntity(new ByteArrayEntity(blob.blob));
+		response = client.execute(putRequest);
+		
+		responseMessage = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+		
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		
+		//Confirm behind the scenes that it is available
+		ByteArrayOutputStream savedBlob = new ByteArrayOutputStream();
+		assertEquals(Status.Available, filestore().downloadBlob(blob.hash, u, r, savedBlob));
+		assertArrayEquals(blob.blob,  savedBlob.toByteArray());
+	}
+
+	@Test
+	public void testMalformedUpload() throws Exception {
+		
+		FileUtils.delete(filestore().getStorageFolder());
+		filestore().clearFilestoreCache();
+		
+		//No upload limit
+		settings().overrideSetting(Keys.filestore.maxUploadSize, FilestoreManager.UNDEFINED_SIZE);
+
+		final BlobInfo blob = new BlobInfo(512*FileUtils.KB);
+        
+        final String initialUploadURL = GitBlitSuite.url + repoLfs + "batch";
+        
+        HttpClient client = HttpClientBuilder.create().build();
+    	HttpPost request = new HttpPost(initialUploadURL);
+
+    	// add request header
+    	request.addHeader(HttpHeaders.ACCEPT, FilestoreServlet.GIT_LFS_META_MIME);
+    	request.addHeader(HttpHeaders.CONTENT_ENCODING, FilestoreServlet.GIT_LFS_META_MIME);
+    	
+    	//Malformed JSON, comma instead of colon and unquoted strings
+    	String content = String.format("{%s:%s,%s:[{%s:%s,%s,%d}]}",
+    			"operation", "upload",
+    			"objects",
+    			"oid", blob.hash,
+    			"size", blob.length);
+    	
+    	HttpEntity entity = new ByteArrayEntity(content.getBytes("UTF-8"));
+    	request.setEntity(entity);
+    	
+    	HttpResponse response = client.execute(request);
+    	String responseMessage = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+		assertEquals(400, response.getStatusLine().getStatusCode());
+		
+		String expectedError = String.format("{%s:%s,%s:%d}",
+				"\"message\"", "\"Malformed Git-LFS request\"",
+				"\"code\"", 400);
+				
+		assertEquals(expectedError, responseMessage);
+	}
+	
+}

--
Gitblit v1.9.1