From 7aa76c97f6edbd896abec2ebac35a031b1e250a9 Mon Sep 17 00:00:00 2001 From: Matthieu Baechler Date: Tue, 20 Oct 2015 15:48:01 +0000 Subject: [PATCH] JAMES-1606: Integration tests for FileSystem implementation git-svn-id: https://svn.apache.org/repos/asf/james/project/trunk@1709626 13f79535-47bb-0310-9956-ffa450edef68 --- server/container/filesystem-api/pom.xml | 10 + .../api/AbstractFileSystemTest.java | 299 ++++++++++++++++++ .../src/test/resources/class path Test.txt | 1 + .../src/test/resources/classpathTest.txt | 1 + server/container/spring/pom.xml | 16 + .../JamesServerApplicationContext.java | 14 +- .../TestApplicationContextProvider.java | 47 +++ .../spring/filesystem/FileSystemImplTest.java | 34 ++ server/pom.xml | 6 +- 9 files changed, 420 insertions(+), 8 deletions(-) create mode 100644 server/container/filesystem-api/src/test/java/org/apache/james/filesystem/api/AbstractFileSystemTest.java create mode 100644 server/container/filesystem-api/src/test/resources/class path Test.txt create mode 100644 server/container/filesystem-api/src/test/resources/classpathTest.txt create mode 100644 server/container/spring/src/test/java/org/apache/james/container/spring/context/TestApplicationContextProvider.java create mode 100644 server/container/spring/src/test/java/org/apache/james/container/spring/filesystem/FileSystemImplTest.java diff --git a/server/container/filesystem-api/pom.xml b/server/container/filesystem-api/pom.xml index 495331ac833..348fbf12aa7 100644 --- a/server/container/filesystem-api/pom.xml +++ b/server/container/filesystem-api/pom.xml @@ -50,6 +50,16 @@ junit junit + + org.assertj + assertj-core + test + + + pl.pragmatists + JUnitParams + test + diff --git a/server/container/filesystem-api/src/test/java/org/apache/james/filesystem/api/AbstractFileSystemTest.java b/server/container/filesystem-api/src/test/java/org/apache/james/filesystem/api/AbstractFileSystemTest.java new file mode 100644 index 00000000000..f44047cff54 --- /dev/null +++ b/server/container/filesystem-api/src/test/java/org/apache/james/filesystem/api/AbstractFileSystemTest.java @@ -0,0 +1,299 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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 org.apache.james.filesystem.api; + +import static junitparams.JUnitParamsRunner.$; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; + +@SuppressWarnings("restriction") +@RunWith(JUnitParamsRunner.class) +public abstract class AbstractFileSystemTest { + private static final String FAKE_DIRECTORY = "b7b73e3a-5234-11e5-87f2-9b171f273b49/"; + private static final String FAKE_FILE = "d9091ae6-521f-11e5-b666-bb11fef67c2a"; + private static final String EXISTING_CLASSPATH_FILE = "classpathTest.txt"; + private static final String EXISTING_CLASSPATH_FILE_WITH_SPACES = "class path Test.txt"; + + @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); + + protected FileSystem fileSystem; + + private HttpServer httpServer; + private File rootDirectory; + + protected abstract FileSystem buildFileSystem(String configurationRootDirectory); + + @Before + public void setUp() throws Exception { + httpServer = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + httpServer.createContext("/", new SlashHandler()); + httpServer.start(); + + rootDirectory = tmpFolder.getRoot(); + createSubFolderWithAFileIn("conf", "conf.txt", "confcontent"); + createSubFolderWithAFileIn("var", "var.txt", "varcontent"); + + fileSystem = buildFileSystem(rootDirectory.getAbsolutePath()); + } + + private void createSubFolderWithAFileIn(String folderName, String fileName, String fileContent) throws IOException { + File folder = tmpFolder.newFolder(folderName); + File file = new File(folder.getAbsolutePath() + "/" + fileName); + FileUtils.writeStringToFile(file, fileContent); + } + + @After + public void tearDown() throws Exception { + httpServer.stop(0); + } + + private static class SlashHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + if (exchange.getRequestURI().getPath().equals("/")) { + String response = "content"; + exchange.sendResponseHeaders(200, response.length()); + OutputStream responseBody = exchange.getResponseBody(); + responseBody.write(response.getBytes()); + responseBody.close(); + } else { + exchange.sendResponseHeaders(404, 0); + } + } + } + + @Test + public final void getBaseDirShouldReturnParentDir() throws Exception { + File basedir = fileSystem.getBasedir(); + assertThat(basedir.getPath()).isEqualTo(rootDirectory.getAbsolutePath()); + } + + @Test(expected = NullPointerException.class) + public final void nullInputShouldThrowNullPointerException() throws Exception { + fileSystem.getFile(null); + } + + public final void emptyInputShouldThrowReturnEmptyPathFile() throws Exception { + File file = fileSystem.getFile(""); + assertThat(file.getPath()).isEmpty();; + } + + @Test + public final void protocolOnlyShouldReturnEmptyPathFile() throws Exception { + File file = fileSystem.getFile("file:"); + assertThat(file.getPath()).isEmpty(); + } + + @Test + public final void protocolWithDoubleSlashesOnlyShouldReturnDir() throws Exception { + File file = fileSystem.getFile("file://"); + assertThat(file).isDirectory(); + } + + public static class UrlsAsFileThrowingFileNotFoundExceptionProvider { + public static Object[] provides() { + return $( + $("bad://file"), + $("classpath:" + FAKE_FILE), + $("classpath:/" + FAKE_FILE), + $("http://localhost:$PORT$/"), + $("classpath:" + new File(ClassLoader.getSystemResource(EXISTING_CLASSPATH_FILE).getFile()).getAbsolutePath()), + $("classpath:java/lang/String.class") + ); + } + } + + @Test(expected = FileNotFoundException.class) + @Parameters(source = UrlsAsFileThrowingFileNotFoundExceptionProvider.class) + public final void urlAsFileThrowingFileNotFoundException(String url) throws Exception { + url = replacePort(url); + + fileSystem.getFile(url); + } + + public static class NonExistingFilesProvider { + public static Object[] provides() { + return $( + $("file:///" + FAKE_FILE), + $("file:///" + FAKE_DIRECTORY + FAKE_FILE), + $("file://conf/" + FAKE_FILE), + $("file://var/" + FAKE_FILE) + ); + } + } + + @Test + @Parameters(source = NonExistingFilesProvider.class) + public void nonExistingFilesShouldNotExist(String url) throws Exception { + File f = fileSystem.getFile(url); + assertThat(f).doesNotExist(); + } + + public static class NonAvailableStreamsProvider { + public static Object[] provide() { + return $( + $("http://localhost:$PORT$/" + FAKE_FILE), + $("classpath:java/lang/" + FAKE_FILE + ".clas"), + $("classpath:" + FAKE_FILE) + ); + } + } + + @Test(expected = FileNotFoundException.class) + @Parameters(source = NonAvailableStreamsProvider.class) + public final void getFakeHttpResourceAsInputStreamShouldThrow(String url) throws Exception { + url = replacePort(url); + + fileSystem.getResource(url); + } + + public static class AvailableStreamsProvider { + public static Object[] provide() { + return $( + $("http://localhost:$PORT$/"), + $("classpath:java/lang/String.class"), + $("classpath:" + EXISTING_CLASSPATH_FILE), + $("classpath:" + EXISTING_CLASSPATH_FILE_WITH_SPACES), + $("classpath:/" + EXISTING_CLASSPATH_FILE), + $("classpath:/" + EXISTING_CLASSPATH_FILE_WITH_SPACES) + ); + } + } + + @Test + @Parameters(source = AvailableStreamsProvider.class) + public final void availableInputStreamShouldReturnANonEmptyStream(String url) throws Exception { + url = replacePort(url); + InputStream inputStream = fileSystem.getResource(url); + try { + assertThat(IOUtils.toString(inputStream).length()).isGreaterThan(0); + } finally { + IOUtils.closeQuietly(inputStream); + } + } + + private String replacePort(String url) { + return url.replace("$PORT$", String.valueOf(httpServer.getAddress().getPort())); + } + + public static class FileToCreateProvider { + public static Object[] provide() { + return $( + $("fileSystemTest", ".txt"), + $("file System Test", ".txt") + ); + } + } + + @Test + @Parameters(source = FileToCreateProvider.class) + public final void createdFilesShouldExist(String name, String extension) throws Exception { + File temp = createTempFile(name, extension); + try { + File expected = fileSystem.getFile("file:" + temp.getAbsolutePath()); + assertThat(expected).exists(); + } finally { + temp.delete(); + } + } + + @Test + @Parameters(source = FileToCreateProvider.class) + public final void createdFilesShouldExistWhenAccessedWithTwoSlashes(String name, String extension) throws Exception { + File temp = createTempFile(name, extension); + try { + File expected = fileSystem.getFile("file://" + temp.getAbsolutePath()); + assertThat(expected).exists(); + } finally { + temp.delete(); + } + } + + @Test + @Parameters(source = FileToCreateProvider.class) + public final void createdFilesAsInputStreamShouldBeAvailable(String name, String extension) throws Exception { + File temp = createTempFile(name, extension); + InputStream inputStream = null; + try { + inputStream = fileSystem.getResource("file:" + temp.getAbsolutePath()); + assertThat(IOUtils.toString(inputStream)).isEqualTo("content"); + } finally { + IOUtils.closeQuietly(inputStream); + temp.delete(); + } + } + + @Test + @Parameters(source = FileToCreateProvider.class) + public final void createdFilesAsInputStreamShouldBeAvailableWhenAccessedWithTwoSlashes(String name, String extension) throws Exception { + File temp = createTempFile(name, extension); + InputStream inputStream = null; + try { + inputStream = fileSystem.getResource("file://" + temp.getAbsolutePath()); + assertThat(IOUtils.toString(inputStream)).isEqualTo("content"); + } finally { + IOUtils.closeQuietly(inputStream); + temp.delete(); + } + } + + private File createTempFile(String name, String extension) throws IOException { + File temp = File.createTempFile(name, extension); + FileUtils.write(temp, "content"); + return temp; + } + + @Test + public void testConfProtocolSouldReturnConfFile() throws Exception { + File file = fileSystem.getFile("file://conf/conf.txt"); + + assertThat(file).hasContent("confcontent"); + } + + @Test + public void testVarProtocolSouldReturnVarFile() throws Exception { + File file = fileSystem.getFile("file://var/var.txt"); + + assertThat(file).hasContent("varcontent"); + } + +} diff --git a/server/container/filesystem-api/src/test/resources/class path Test.txt b/server/container/filesystem-api/src/test/resources/class path Test.txt new file mode 100644 index 00000000000..37eca45d2e8 --- /dev/null +++ b/server/container/filesystem-api/src/test/resources/class path Test.txt @@ -0,0 +1 @@ +Non empty diff --git a/server/container/filesystem-api/src/test/resources/classpathTest.txt b/server/container/filesystem-api/src/test/resources/classpathTest.txt new file mode 100644 index 00000000000..37eca45d2e8 --- /dev/null +++ b/server/container/filesystem-api/src/test/resources/classpathTest.txt @@ -0,0 +1 @@ +Non empty diff --git a/server/container/spring/pom.xml b/server/container/spring/pom.xml index 70a5c7c3c96..ca4882a3a6b 100644 --- a/server/container/spring/pom.xml +++ b/server/container/spring/pom.xml @@ -43,6 +43,12 @@ org.apache.james james-server-filesystem-api + + org.apache.james + james-server-filesystem-api + test + test-jar + org.apache.james james-server-mailetcontainer-api @@ -156,6 +162,16 @@ org.apache.geronimo.specs geronimo-jpa_2.0_spec + + org.assertj + assertj-core + test + + + pl.pragmatists + JUnitParams + test + diff --git a/server/container/spring/src/main/java/org/apache/james/container/spring/context/JamesServerApplicationContext.java b/server/container/spring/src/main/java/org/apache/james/container/spring/context/JamesServerApplicationContext.java index be4ff74ae9c..8c9689ff0f3 100644 --- a/server/container/spring/src/main/java/org/apache/james/container/spring/context/JamesServerApplicationContext.java +++ b/server/container/spring/src/main/java/org/apache/james/container/spring/context/JamesServerApplicationContext.java @@ -45,7 +45,7 @@ public JamesServerApplicationContext(String[] configs) { */ public Resource getResource(String fileURL) { // delegate the loading to the resourceloader - Resource r = resourceLoader.getResource(fileURL); + Resource r = getResourceLoader().getResource(fileURL); if (r == null) { r = super.getResource(fileURL); } @@ -57,7 +57,7 @@ public Resource getResource(String fileURL) { * org.apache.james.container.spring.resource.JamesResourceLoader#getAbsoluteDirectory() */ public String getAbsoluteDirectory() { - return resourceLoader.getAbsoluteDirectory(); + return getResourceLoader().getAbsoluteDirectory(); } /** @@ -65,7 +65,7 @@ public String getAbsoluteDirectory() { * org.apache.james.container.spring.resource.JamesResourceLoader#getConfDirectory() */ public String getConfDirectory() { - return resourceLoader.getConfDirectory(); + return getResourceLoader().getConfDirectory(); } /** @@ -73,7 +73,7 @@ public String getConfDirectory() { * org.apache.james.container.spring.resource.JamesResourceLoader#getVarDirectory() */ public String getVarDirectory() { - return resourceLoader.getVarDirectory(); + return getResourceLoader().getVarDirectory(); } /** @@ -81,17 +81,17 @@ public String getVarDirectory() { * org.apache.james.container.spring.resource.JamesResourceLoader#getRootDirectory() */ public String getRootDirectory() { - return resourceLoader.getRootDirectory(); + return getResourceLoader().getRootDirectory(); } /** * Protected accessor for the resource loader. */ - protected static JamesServerResourceLoader getResourceLoader() { + protected JamesServerResourceLoader getResourceLoader() { return resourceLoader; } - protected static final class JamesServerResourceLoader extends AbstractJamesResourceLoader { + protected static class JamesServerResourceLoader extends AbstractJamesResourceLoader { /** * @see org.apache.james.container.spring.resource.JamesResourceLoader#getAbsoluteDirectory() diff --git a/server/container/spring/src/test/java/org/apache/james/container/spring/context/TestApplicationContextProvider.java b/server/container/spring/src/test/java/org/apache/james/container/spring/context/TestApplicationContextProvider.java new file mode 100644 index 00000000000..2f10e0e7fa2 --- /dev/null +++ b/server/container/spring/src/test/java/org/apache/james/container/spring/context/TestApplicationContextProvider.java @@ -0,0 +1,47 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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 org.apache.james.container.spring.context; + +public class TestApplicationContextProvider extends JamesServerApplicationContext { + private String configurationRootDirectory; + + public TestApplicationContextProvider(String configurationRootDirectory, String[] configs) { + super(configs); + this.configurationRootDirectory = configurationRootDirectory; + } + + @Override + public JamesServerResourceLoader getResourceLoader() { + return new TestDirectoryProvider(configurationRootDirectory); + } + + private static class TestDirectoryProvider extends JamesServerResourceLoader { + private String configurationRootDirectory; + + public TestDirectoryProvider(String configurationRootDirectory) { + this.configurationRootDirectory = configurationRootDirectory; + } + + @Override + public String getRootDirectory() { + return configurationRootDirectory; + } + } + +} diff --git a/server/container/spring/src/test/java/org/apache/james/container/spring/filesystem/FileSystemImplTest.java b/server/container/spring/src/test/java/org/apache/james/container/spring/filesystem/FileSystemImplTest.java new file mode 100644 index 00000000000..073332e5fd3 --- /dev/null +++ b/server/container/spring/src/test/java/org/apache/james/container/spring/filesystem/FileSystemImplTest.java @@ -0,0 +1,34 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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 org.apache.james.container.spring.filesystem; + +import org.apache.james.container.spring.context.TestApplicationContextProvider; +import org.apache.james.filesystem.api.AbstractFileSystemTest; +import org.apache.james.filesystem.api.FileSystem; + +public class FileSystemImplTest extends AbstractFileSystemTest { + + @Override + protected FileSystem buildFileSystem(String configurationRootDirectory) { + FileSystemImpl fs = new FileSystemImpl(); + fs.setApplicationContext(new TestApplicationContextProvider(configurationRootDirectory, null)); + return fs; + } + +} diff --git a/server/pom.xml b/server/pom.xml index e1a5a3f008f..5dac697db5c 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -846,7 +846,11 @@ 1.7.1 test - + + pl.pragmatists + JUnitParams + 1.0.4 + org.mockito mockito-core