blob: ee004777fdd28f3dc973d0cac10107478388ea80 [file] [log] [blame]
/*
* 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.commons.vfs2;
import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
import org.apache.commons.vfs2.provider.AbstractFileSystem;
import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
import org.junit.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
/**
* File system test cases, which verifies the structure and naming functionality.
* <p>
* Works from a base folder, and assumes a particular structure under that base folder.
*/
public abstract class AbstractProviderTestCase extends AbstractVfsTestCase {
private FileObject baseFolder;
private FileObject readFolder;
private FileObject writeFolder;
private DefaultFileSystemManager manager;
private ProviderTestConfig providerConfig;
private Method method;
private boolean addEmptyDir;
// Expected contents of "file1.txt"
public static final String FILE1_CONTENT = "This is a test file.";
// Expected contents of test files
public static final String TEST_FILE_CONTENT = "A test file.";
/**
* Sets the test method.
*/
public void setMethod(final Method method) {
this.method = method;
}
/**
* Configures this test.
*/
public void setConfig(final DefaultFileSystemManager manager, final ProviderTestConfig providerConfig,
final FileObject baseFolder, final FileObject readFolder, final FileObject writeFolder) {
this.manager = manager;
this.providerConfig = providerConfig;
this.baseFolder = baseFolder;
this.readFolder = readFolder;
this.writeFolder = writeFolder;
assertNotNull("setConfig manager", manager);
assertNotNull("setConfig providerConfig", providerConfig);
assertNotNull("setConfig baseFolder", baseFolder);
assertNotNull("setConfig readFolder", readFolder);
assertNotNull("setConfig writeFolder", writeFolder);
}
/**
* Returns the file system manager used by this test.
*/
protected DefaultFileSystemManager getManager() {
return manager;
}
/**
* creates a new uninitialized file system manager
*
* @throws Exception
*/
protected DefaultFileSystemManager createManager() throws Exception {
final DefaultFileSystemManager fs = getProviderConfig().getDefaultFileSystemManager();
fs.setFilesCache(getProviderConfig().getFilesCache());
getProviderConfig().prepare(fs);
if (!fs.hasProvider("file")) {
fs.addProvider("file", new DefaultLocalFileProvider());
}
return fs;
}
/**
* some provider config do some post-initialization in getBaseTestFolder. This is a hack to allow access to this
* code for {@code createManager}
*/
public FileObject getBaseTestFolder(final FileSystemManager fs) throws Exception {
return providerConfig.getBaseTestFolder(fs);
}
protected FileSystem getFileSystem() {
final FileObject rFolder = getReadFolder();
Assert.assertNotNull("This test's read folder should not be null", rFolder);
return rFolder.getFileSystem();
}
/**
* Returns the base test folder. This is the parent of both the read test and write test folders.
*/
public FileObject getBaseFolder() {
return baseFolder;
}
/**
* get the provider configuration
*/
public ProviderTestConfig getProviderConfig() {
return providerConfig;
}
/**
* Returns the read test folder.
*/
protected FileObject getReadFolder() {
return readFolder;
}
/**
* Returns the write test folder.
*/
protected FileObject getWriteFolder() {
return writeFolder;
}
/**
* Sets the write test folder.
*
* @param folder
*/
protected void setWriteFolder(final FileObject folder) {
writeFolder = folder;
}
/**
* Returns the capabilities required by the tests of this test case. The tests are not run if the provider being
* tested does not support all the required capabilities. Return null or an empty array to always run the tests.
* <p>
* This implementation returns null.
*/
protected Capability[] getRequiredCapabilities() {
return null;
}
/**
* Runs the test. This implementation short-circuits the test if the provider being tested does not have the
* capabilities required by this test.
* <p>
* TODO - Handle negative caps as well - ie, only run a test if the provider does not have certain caps.
* </p>
* <p>
* TODO - Figure out how to remove the test from the TestResult if the test is skipped.
* </p>
*/
@Override
protected void runTest() throws Throwable {
// Check the capabilities
final Capability[] caps = getRequiredCapabilities();
if (caps != null) {
for (final Capability cap2 : caps) {
final Capability cap = cap2;
final FileSystem fs = getFileSystem();
if (!fs.hasCapability(cap)) {
// String name = fs.getClass().getName();
// int index = name.lastIndexOf('.');
// String fsName = (index > 0) ? name.substring(index + 1) : name;
// System.out.println("skipping " + getName() + " because " +
// fsName + " does not have capability " + cap);
return;
}
}
}
// Provider has all the capabilities - execute the test
if (method != null) {
try {
method.invoke(this, (Object[]) null);
} catch (final InvocationTargetException e) {
throw e.getTargetException();
}
} else {
super.runTest();
}
if (readFolder != null && ((AbstractFileSystem) readFolder.getFileSystem()).isOpen()) {
String name = "unknown";
if (method != null) {
name = method.getName();
}
throw new IllegalStateException(getClass().getName() + ": filesystem has open streams after: " + name);
}
}
/**
* Asserts that the content of a file is the same as expected. Checks the length reported by getContentLength() is
* correct, then reads the content as a byte stream and compares the result with the expected content. Assumes files
* are encoded using UTF-8.
*/
protected void assertSameURLContent(final String expected, final URLConnection connection) throws Exception {
// Get file content as a binary stream
final byte[] expectedBin = expected.getBytes(StandardCharsets.UTF_8);
// Check lengths
assertEquals("same content length", expectedBin.length, connection.getContentLength());
// Read content into byte array
final InputStream instr = connection.getInputStream();
final ByteArrayOutputStream outstr;
try {
outstr = new ByteArrayOutputStream();
final byte[] buffer = new byte[256];
int nread = 0;
while (nread >= 0) {
outstr.write(buffer, 0, nread);
nread = instr.read(buffer);
}
} finally {
instr.close();
}
// Compare
assertArrayEquals("same binary content", expectedBin, outstr.toByteArray());
}
/**
* Asserts that the content of a file is the same as expected. Checks the length reported by getSize() is correct,
* then reads the content as a byte stream and compares the result with the expected content. Assumes files are
* encoded using UTF-8.
*/
protected void assertSameContent(final String expected, final FileObject file) throws Exception {
// Check the file exists, and is a file
assertTrue(file.exists());
assertSame(FileType.FILE, file.getType());
assertTrue(file.isFile());
// Get file content as a binary stream
final byte[] expectedBin = expected.getBytes(StandardCharsets.UTF_8);
// Check lengths
final FileContent content = file.getContent();
assertEquals("same content length", expectedBin.length, content.getSize());
// Read content into byte array
final InputStream instr = content.getInputStream();
final ByteArrayOutputStream outstr;
try {
outstr = new ByteArrayOutputStream(expectedBin.length);
final byte[] buffer = new byte[256];
int nread = 0;
while (nread >= 0) {
outstr.write(buffer, 0, nread);
nread = instr.read(buffer);
}
} finally {
instr.close();
}
// Compare
assertArrayEquals("same binary content", expectedBin, outstr.toByteArray());
}
/**
* Builds the expected structure of the read tests folder.
*
* @throws FileSystemException (possibly)
*/
protected FileInfo buildExpectedStructure() throws FileSystemException {
// Build the expected structure
final FileInfo base = new FileInfo(getReadFolder().getName().getBaseName(), FileType.FOLDER);
base.addFile("file1.txt", FILE1_CONTENT);
// file%.txt - test out encoding
base.addFile("file%25.txt", FILE1_CONTENT);
// file?test.txt - test out encoding (test.txt is not the queryString)
// as we do not know if the current file provider we need to
// ask it to normalize the name
// todo: move this into the FileInfo class to do it generally?
/*
* webdav-bug?: didnt manage to get the "?" correctly through webdavlib FileSystemManager fsm =
* getReadFolder().getFileSystem().getFileSystemManager(); FileName fn =
* fsm.resolveName(getReadFolder().getName(), "file%3ftest.txt"); String baseName = fn.getBaseName();
* base.addFile(baseName, FILE1_CONTENT);
*/
base.addFile("file space.txt", FILE1_CONTENT);
base.addFile("empty.txt", "");
if (addEmptyDir) {
base.addFolder("emptydir");
}
final FileInfo dir = base.addFolder("dir1");
dir.addFile("file1.txt", TEST_FILE_CONTENT);
dir.addFile("file2.txt", TEST_FILE_CONTENT);
dir.addFile("file3.txt", TEST_FILE_CONTENT);
final FileInfo subdir1 = dir.addFolder("subdir1");
subdir1.addFile("file1.txt", TEST_FILE_CONTENT);
subdir1.addFile("file2.txt", TEST_FILE_CONTENT);
subdir1.addFile("file3.txt", TEST_FILE_CONTENT);
final FileInfo subdir2 = dir.addFolder("subdir2");
subdir2.addFile("file1.txt", TEST_FILE_CONTENT);
subdir2.addFile("file2.txt", TEST_FILE_CONTENT);
subdir2.addFile("file3.txt", TEST_FILE_CONTENT);
final FileInfo subdir3 = dir.addFolder("subdir3");
subdir3.addFile("file1.txt", TEST_FILE_CONTENT);
subdir3.addFile("file2.txt", TEST_FILE_CONTENT);
subdir3.addFile("file3.txt", TEST_FILE_CONTENT);
final FileInfo subdir4 = dir.addFolder("subdir4.jar");
subdir4.addFile("file1.txt", TEST_FILE_CONTENT);
subdir4.addFile("file2.txt", TEST_FILE_CONTENT);
subdir4.addFile("file3.txt", TEST_FILE_CONTENT);
return base;
}
protected void addEmptyDir(final boolean addEmptyDir) {
this.addEmptyDir = addEmptyDir;
}
protected static Test notConfigured(final Class<?> testClass) {
return warning(testClass + " is not configured for tests, skipping");
}
private static Test warning(final String message) {
return new TestCase("warning") {
@Override
protected void runTest() {
System.out.println(message);
}
};
}
@Override
public String toString() {
return "AbstractProviderTestCase [baseFolder=" + baseFolder + ", readFolder=" + readFolder + ", writeFolder="
+ writeFolder + ", manager=" + manager + ", providerConfig=" + providerConfig + ", method=" + method
+ ", addEmptyDir=" + addEmptyDir + "]";
}
}