Java tutorial
/* * 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.taverna.commandline; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.net.URI; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.comparator.NameFileComparator; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.apache.taverna.commandline.WorkflowTestSuite.Workflows; import org.apache.taverna.scufl2.api.container.WorkflowBundle; import org.apache.taverna.scufl2.api.io.WorkflowBundleIO; import org.apache.taverna.scufl2.rdfxml.RDFXMLReader; /** * Regression tests for Taverna Command-line Tool. */ @RunWith(WorkflowTestSuite.class) public class TavernaCommandLineTest { private static String baseVersion = "2.4.0"; private static boolean baseVersionReleased = true; private static String testVersion = "3.0.1-SNAPSHOT"; private static boolean testVersionReleased = false; private static boolean testVersionSupportsScufl2 = true; private static String script = "executeworkflow.sh"; private static String baseName = "taverna-commandline-" + baseVersion; private static String testName = "taverna-command-line-" + testVersion; private static String releasedLocation = "https://launchpad.net/taverna/t2/"; private static String unreleasedLocation = "http://build.mygrid.org.uk/ci/job/t3-taverna-commandline-product/lastSuccessfulBuild/net.sf.taverna.t2$taverna-commandline/artifact/net.sf.taverna.t2/taverna-commandline/"; private static String baseVersionLocation = (baseVersionReleased ? releasedLocation : unreleasedLocation) + baseVersion + "/+download/" + baseName + ".zip"; private static String testVersionLocation = (testVersionReleased ? releasedLocation : unreleasedLocation) + testVersion + "/" + testName + (testVersionReleased ? ".zip" : "-bin.zip"); private static String baseCommand; private static String testCommand; private static File buildDirectory; private File workflowDirectory; private File baseOutput; private File testOutput; private boolean secure; private List<File> inputs; private String ignorePort; private String message; public TavernaCommandLineTest(File workflowDirectory) throws Exception { this.workflowDirectory = workflowDirectory; if (buildDirectory == null) { String buildDirectoryLocation = System.getProperty("buildDirectory"); if (buildDirectoryLocation == null) { buildDirectoryLocation = System.getProperty("user.dir") + System.getProperty("file.separator") + "target"; } buildDirectory = new File(buildDirectoryLocation); buildDirectory.mkdirs(); } if (baseCommand == null) { File commandDirectory = new File(buildDirectory, baseName); if (!commandDirectory.exists()) { System.out.println("Fetching " + baseName); fetchTaverna(baseVersionLocation, baseName); } baseCommand = new File(baseName, script).getPath(); } if (testCommand == null) { File commandDirectory = new File(buildDirectory, testName); if (!commandDirectory.exists()) { System.out.println("Fetching " + testName); fetchTaverna(testVersionLocation, testName); } testCommand = new File(testName, script).getPath(); } File outputsDirectory = new File(buildDirectory, "test-outputs"); baseOutput = new File(outputsDirectory, workflowDirectory.getName() + "-" + baseVersion); testOutput = new File(outputsDirectory, workflowDirectory.getName() + "-" + testVersion); secure = workflowDirectory.getName().startsWith("secure"); inputs = getInputs(); ignorePort = getIgnorePort(); message = "Running {0} with version {1}"; } @Workflows public static List<File> workflows() { List<File> workflows = new ArrayList<File>(); for (File workflowDirectory : getResources("workflows")) { workflows.add(workflowDirectory); } for (File workflowDirectory : getResources("myexperiment")) { workflows.add(workflowDirectory); } return workflows; } @Before public void setup() throws Exception { if (!baseOutput.exists()) { if (baseVersion.equals("2.3.0") && workflowDirectory.getName().equals("tool")) return;// version 2.3.0 is missing tool plugin String workflow = getWorkflow().toASCIIString(); System.out.println(MessageFormat.format(message, workflow, baseVersion) + (inputs.size() > 0 ? " using input values" : "")); runWorkflow(baseCommand, workflow, baseOutput, true, secure, false); assertTrue(String.format("No output produced for %s", workflowDirectory.getName()), baseOutput.exists()); } } public boolean testExcluded() { // version 3.0.0 is missing biomoby activity if (testVersion.startsWith("3.") && workflowDirectory.getName().contains("biomoby")) return true; // version 3.0.0 is missing tool activity if (testVersion.startsWith("3.") && workflowDirectory.getName().equals("unix_external_tools_with_zip_and_unzip")) return true; if (testVersion.startsWith("3.") && workflowDirectory.getName().equals("unix_numerically_adding_two_values")) return true; if (testVersion.startsWith("3.") && workflowDirectory.getName().equals("unix_tool_service_using_string_replacement")) return true; // version 3.0.0 is missing looping configuration if (testVersion.startsWith("3.") && workflowDirectory.getName().equals("ebi_interproscan_newservices")) return true; if (testVersion.startsWith("3.") && workflowDirectory.getName().equals("biomartandembossanalysis")) return true; return false; } @Test public void testWorkflowWithoutInputs() throws Exception { assumeTrue(!testExcluded()); assumeTrue(baseOutput.exists()); assumeTrue(inputs.isEmpty()); FileUtils.deleteDirectory(testOutput); String workflow = getWorkflow().toASCIIString(); System.out.println(MessageFormat.format(message, workflow, testVersion)); runWorkflow(testCommand, workflow, testOutput, true, secure, false); assertTrue(String.format("No output produced for %s", workflowDirectory.getName()), testOutput.exists()); assertOutputsEquals(baseOutput, testOutput); } @Test public void testWorkflowWithInputValues() throws Exception { assumeTrue(!testExcluded()); assumeTrue(baseOutput.exists()); assumeTrue(inputs.size() > 0); FileUtils.deleteDirectory(testOutput); String workflow = getWorkflow().toASCIIString(); System.out.println(MessageFormat.format(message, workflow, testVersion) + " using input values"); runWorkflow(testCommand, workflow, testOutput, true, secure, false); assertTrue(String.format("No output produced for %s", workflowDirectory.getName()), testOutput.exists()); assertOutputsEquals(baseOutput, testOutput); } @Test public void testWorkflowWithInputFiles() throws Exception { assumeTrue(!testExcluded()); assumeTrue(baseOutput.exists()); assumeTrue(inputs.size() > 0); FileUtils.deleteDirectory(testOutput); String workflow = getWorkflow().toASCIIString(); System.out.println(MessageFormat.format(message, workflow, testVersion) + " using input files"); runWorkflow(testCommand, workflow, testOutput, false, secure, false); assertTrue(String.format("No output produced for %s", workflowDirectory.getName()), testOutput.exists()); assertOutputsEquals(baseOutput, testOutput); } @Test @Ignore public void testWorkflowWithDatabase() throws Exception { assumeTrue(!testExcluded()); assumeTrue(baseOutput.exists()); assumeTrue(inputs.size() > 0); FileUtils.deleteDirectory(testOutput); String workflow = getWorkflow().toASCIIString(); System.out.println(MessageFormat.format(message, workflow, testVersion) + " using database"); runWorkflow(testCommand, workflow, testOutput, true, secure, true); assertTrue(String.format("No output produced for %s", workflowDirectory.getName()), testOutput.exists()); assertOutputsEquals(baseOutput, testOutput); } @Test public void testScufl2Workflow() throws Exception { assumeTrue(!testExcluded()); assumeTrue(baseOutput.exists()); assumeTrue(testVersionSupportsScufl2); FileUtils.deleteDirectory(testOutput); String workflow = getScufl2Workflow().toASCIIString(); System.out.println(MessageFormat.format(message, workflow, testVersion) + (inputs.size() > 0 ? " using input values" : "")); runWorkflow(testCommand, workflow, testOutput, true, secure, true); assertTrue(String.format("No output produced for %s", workflowDirectory.getName()), testOutput.exists()); assertOutputsEquals(baseOutput, testOutput); } private synchronized void runWorkflow(String command, String workflow, File outputsDirectory, boolean inputValues, boolean secure, boolean database) throws Exception { ProcessBuilder processBuilder = new ProcessBuilder("sh", command); processBuilder.redirectErrorStream(true); processBuilder.directory(buildDirectory); List<String> args = processBuilder.command(); for (File input : inputs) { if (inputValues) { args.add("-inputvalue"); args.add(input.getName()); args.add(IOUtils.toString(new FileReader(input))); } else { args.add("-inputfile"); args.add(input.getName()); args.add(input.getAbsolutePath()); } } args.add("-outputdir"); args.add(outputsDirectory.getPath()); if (secure) { args.add("-cmdir"); args.add(getClass().getResource("/security").getFile()); args.add("-cmpassword"); } if (database) { args.add("-embedded"); } args.add(workflow); Process process = processBuilder.start(); if (secure) { PrintStream outputStream = new PrintStream(process.getOutputStream()); outputStream.println("test"); outputStream.flush(); } waitFor(process); } private URI getWorkflow() throws Exception { File workflow = new File(workflowDirectory, workflowDirectory.getName() + ".t2flow"); if (!workflow.exists()) { workflow = new File(workflowDirectory, workflowDirectory.getName() + ".url"); return new URI(IOUtils.toString(new FileReader(workflow))); } return workflow.toURI(); } private URI getScufl2Workflow() throws Exception { File workflow = new File(buildDirectory, workflowDirectory.getName() + ".wfbundle"); // if (!workflow.exists()) { WorkflowBundleIO workflowBundleIO = new WorkflowBundleIO(); WorkflowBundle bundle = workflowBundleIO.readBundle(getWorkflow().toURL(), null); workflowBundleIO.writeBundle(bundle, workflow, RDFXMLReader.APPLICATION_VND_TAVERNA_SCUFL2_WORKFLOW_BUNDLE); // } return workflow.toURI(); } private synchronized int waitFor(Process process) throws IOException { while (true) { try { wait(500); } catch (InterruptedException e) { } IOUtils.copy(process.getInputStream(), System.out); try { return process.exitValue(); } catch (IllegalThreadStateException e) { } } } private void assertOutputsEquals(File directory1, File directory2) { File[] directory1Files = directory1.listFiles(); File[] directory2Files = directory2.listFiles(); // assert directories contain same number of files assertEquals( String.format("%s has %s files but %s has %s files", directory1.getName(), directory1Files.length, directory2.getName(), directory2Files.length), directory1Files.length, directory2Files.length); // sort files in directory Arrays.sort(directory1Files, NameFileComparator.NAME_SYSTEM_COMPARATOR); Arrays.sort(directory2Files, NameFileComparator.NAME_SYSTEM_COMPARATOR); for (int i = 0; i < directory1Files.length; i++) { assertFilesEqual(directory1Files[i], directory2Files[i], !directory1Files[i].getName().equals(ignorePort)); } } private void assertDirectoriesEquals(File directory1, File directory2, boolean checkFileContents) { if (directory1.exists()) { assertTrue(String.format("%s exists but %s does not", directory1, directory2), directory2.exists()); } else { assertFalse(String.format("%s does not exists but %s does", directory1, directory2), directory2.exists()); } File[] directory1Files = directory1.listFiles(); File[] directory2Files = directory2.listFiles(); // assert directories contain same number of files assertEquals( String.format("%s has %s files but %s has %s files", directory1.getName(), directory1Files.length, directory2.getName(), directory2Files.length), directory1Files.length, directory2Files.length); // sort files in directory Arrays.sort(directory1Files, NameFileComparator.NAME_SYSTEM_COMPARATOR); Arrays.sort(directory2Files, NameFileComparator.NAME_SYSTEM_COMPARATOR); for (int i = 0; i < directory1Files.length; i++) { assertFilesEqual(directory1Files[i], directory2Files[i], checkFileContents); } } private void assertFilesEqual(File file1, File file2, boolean checkFileContents) { if (file1.isHidden()) { assertTrue(String.format("%s is hidden but %s is not", file1, file2), file2.isHidden()); } else { assertFalse(String.format("%s is not hidden but %s is", file1, file2), file2.isHidden()); assertEquals(file1.getName(), file2.getName()); if (file1.isDirectory()) { assertTrue(String.format("%s is a directory but %s is not", file1, file2), file2.isDirectory()); assertDirectoriesEquals(file1, file2, checkFileContents); } else { assertFalse(String.format("%s is not a directory but %s is", file1, file2), file2.isDirectory()); if (isZipFile(file1)) { assertZipFilesEqual(file1, file2); } else if (checkFileContents) { assertEquals(String.format("%s is a different length to %s", file1, file2), file1.length(), file2.length()); try { byte[] byteArray1 = IOUtils.toByteArray(new FileReader(file1)); byte[] byteArray2 = IOUtils.toByteArray(new FileReader(file2)); assertArrayEquals(String.format("%s != %s", file1, file2), byteArray1, byteArray2); } catch (FileNotFoundException e) { fail(e.getMessage()); } catch (IOException e) { fail(e.getMessage()); } } } } } private void assertZipFilesEqual(File file1, File file2) { ZipFile zipFile1 = null; ZipFile zipFile2 = null; try { zipFile1 = new ZipFile(file1); zipFile2 = new ZipFile(file2); } catch (Exception e) { assertTrue(String.format("%s and %s are not both zip files"), zipFile1 == null); } if (zipFile1 != null && zipFile2 != null) { Enumeration<? extends ZipEntry> entries1 = zipFile1.entries(); Enumeration<? extends ZipEntry> entries2 = zipFile2.entries(); while (entries1.hasMoreElements()) { assertTrue(entries2.hasMoreElements()); ZipEntry zipEntry1 = entries1.nextElement(); ZipEntry zipEntry2 = entries2.nextElement(); assertEquals(String.format("%s and %s are not both directories", zipEntry1, zipEntry2), zipEntry1.isDirectory(), zipEntry2.isDirectory()); assertEquals(String.format("%s and %s have different names", zipEntry1, zipEntry2), zipEntry1.getName(), zipEntry2.getName()); assertEquals(String.format("%s and %s have different sizes", zipEntry1, zipEntry2), zipEntry1.getSize(), zipEntry2.getSize()); try { byte[] byteArray1 = IOUtils.toByteArray(zipFile1.getInputStream(zipEntry1)); byte[] byteArray2 = IOUtils.toByteArray(zipFile2.getInputStream(zipEntry2)); assertArrayEquals(String.format("%s != %s", zipEntry1, zipEntry2), byteArray1, byteArray2); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } assertFalse(entries2.hasMoreElements()); } } private boolean isZipFile(File file) { try { new ZipFile(file); return true; } catch (Exception e) { return false; } } private static File[] getResources(String directory) { return new File(TavernaCommandLineTest.class.getResource("/" + directory).getFile()).listFiles(); } private List<File> getInputs() { File inputsDirectory = new File(workflowDirectory, "inputs"); if (inputsDirectory.exists() && inputsDirectory.isDirectory()) { return Arrays.asList(inputsDirectory.listFiles()); } return Collections.emptyList(); } private String getIgnorePort() throws Exception { File ignorePort = new File(workflowDirectory, "ignorePort"); if (ignorePort.exists()) { return IOUtils.toString(new FileReader(ignorePort)); } return ""; } private void fetchTaverna(String location, String name) throws Exception { File zipFile = new File(buildDirectory, name + ".zip"); IOUtils.copy(new URL(location).openStream(), new FileOutputStream(zipFile)); ProcessBuilder processBuilder = new ProcessBuilder("unzip", "-q", name); processBuilder.redirectErrorStream(true); processBuilder.directory(buildDirectory); System.out.println(processBuilder.command()); Process process = processBuilder.start(); waitFor(process); } }