The FileService service gives access to files and file systems on local or remote drives as well as on FTP, SFTP, HTTP and HTTPS servers.
The configuration files have the base name fileService.properties and support the following configuration properties:
# protocol can be file, ftp, sftp or http protocol=file base.url=${user.dir} writing.permitted=false #linefeed can be either WINDOWS or LINUX linefeed=WINDOWS encoding=UTF-8 # for remote systems user=myuser password=1234 wait.timeout=5000 wait.max.retries=4
For information on how and where to configure these properties, please refer to Service Configuration.
A FileService instance defined as above is retrieved in the test class code by inheriting the test class from AludraTestCase and calling the method getService().
Example:
import java.util.List; import org.aludratest.testcase.Test; import org.aludratest.testcase.AludraTestCase; import org.aludratest.service.ComponentId; import org.aludratest.service.file.FileService; public class ExampleFsTest extends AludraTestCase { @Test public void test() { FileService fileService = getService(ComponentId.create(FileService.class, "myservice")); List<String> children = fileService.perform().getChildren("/"); for (String child : children) { System.out.println(child); } } }
The FileService interface gives access to three action interfaces by which you can perform interactions, verifications and checks on a file system:
public interface FileService extends AludraService { FileInteraction perform(); FileVerification verify(); FileCondition check(); }
A file is identified by its file path relative to the the service's root directory.
So, "/" refers to the base URL as defined in the fileService properties and may internally resolve to an absolute path such as /home/myuser/testdata/fileService/. Consequentially, path names like "/subfolder/test.txt" and "subfolder/test.txt" would resolve to the same file.
Several operations which create, move or copy files have an overwrite parameter. When set to true, existing files are silently overwritten. When set to false and the operation encounters an existing file, a FunctionalFailure is thrown.
File content can be written and read via FileInteraction using text mode or binary mode methods. Text mode operations automatically convert character encoding and linefeed style between the OS on which the JVM is running and the configured (local or remote) file system.
There are methods which make file creation/reading a one-liner (read/WriteText/BinaryFile()): You provide the file name, the file content (as string or byte array) and specify whether existing files shall be overwritten. That's it.
Example:
String content = fileService.perform().readTextFile("file.txt"); System.out.println("File Content: " + content);
However, for very large files, this may not be viable and you need to use streaming.
For writing files, this requires two steps:
Example:
FileService fileService = getService(new ServiceId("localtest", FileService.class)); StringReader reader = new StringReader("Content to save"); // step 1. fileService.perform().writeTextFile("newFile.txt", reader, true); // step 2.
Reading file content requires one more step:
Hint: The method getReaderForTextFile() returns a BufferedReader whose readLine() method can be used to iterate through the stream linewise.
Attention: When iterating the Reader character by character, line feeds are not converted between the service's file system and the JVM's.
Example:
BufferedReader reader = null; try { reader = fileService.perform().getReaderForTextFile("file.txt"); // step 1 String s; while ((s = reader.readLine()) = null) { // step 2 System.out.println(line); } } finally { IOUtil.close(reader); // step 3 }
If there is limited knowledge about the file name to open (e.g. because its name contains a timestamp), you can provide FileService operations (getChildren() and waitForFirstMatch()) with a FileFilter implementation. This needs to implement an accept() method which is provided with a FileInfo object which is called for each file and provides file name, path, size, lastModifiedTime and wether it is a drirectory. The accept() method needs to return true for each file that is accepted.
A set of predefined FileFilter implementations enables you to compose even complex filters without having to develop your own:
An example to illustrate the composition:
In order to search for a file named BAPLIE_<Date>_<Company>_<Sequence>.EDI which has been put on the file system on 2013-11-13 after 9:00 AM, one can combine a RegexFilePathFilter with a LastModifiedTimeFileFilter using the AndFileFilter:
FileService fileService = getService(new ServiceId("localtest", FileService.class)); RegexFilePathFilter regexFilter = new RegexFilePathFilter("BAPLIE_[0-9]{4}-[0-9]{2}-[0-9]{2}_[A-Z]+_[0-9]*\\.EDI"); long minTimestamp = new GregorianCalendar(2013, 10, 13, 9, 0).getTimeInMillis(); LastModifiedTimeFileFilter timeFilter = new LastModifiedTimeFileFilter(minTimestamp, null); FileFilter filter = new AndFileFilter(regexFilter, timeFilter); List<String> matches = fileService.perform().getChildren("/", filter); for (String match matches) System.out.println(match);
There may be cases in which you trigger a process on the SUT which results in the creation of a file which you want to read for validation. Since the operation may be a lengthy process, the FileService provides a polling feature: You provide a file path or a FileFilter for selecting the file and make the FileService poll the file system for you (calling waitUntilExists() or waitForFirstMatch()). The timeout and the maximum number of polling operations is configured in the fileService.properties file. When no match was found before timeout, a FunctionalFailure is thrown.
Example:
String expectedFile = "results.txt"; fileService.perform().waitUntilExists(expectedFile); // this throws a FunctionalFailure if the file does not appear within timeout String content = fileService.perform().readTextFile(expectedFile); System.out.println(content);
public interface FileVerification extends Verification { public void assertPresence(String filePath); public void assertAbsence(String filePath); }
The assert* methods throw an FunctionalFailure exception when the asserted condition is not fulfilled.
public interface FileCondition extends Condition { public boolean exists(String filePath); boolean isDirectory(String filePath); }