diff options
Diffstat (limited to 'src/test/java/com/gitblit/tests/FilestoreServletTest.java')
-rw-r--r-- | 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 00000000..4e4b056a --- /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); + } + +} |