diff --git a/src/main/java/com/askimed/nf/test/core/AbstractTest.java b/src/main/java/com/askimed/nf/test/core/AbstractTest.java index 34288e56..ff7675f1 100644 --- a/src/main/java/com/askimed/nf/test/core/AbstractTest.java +++ b/src/main/java/com/askimed/nf/test/core/AbstractTest.java @@ -2,17 +2,14 @@ import java.io.File; import java.io.IOException; -import java.math.BigInteger; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Vector; +import com.askimed.nf.test.util.HashUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.askimed.nf.test.config.Config; -import com.askimed.nf.test.config.FileStaging; import com.askimed.nf.test.util.FileUtil; public abstract class AbstractTest implements ITest { @@ -57,6 +54,8 @@ public abstract class AbstractTest implements ITest { public File projectDir = new File(System.getProperty("user.dir")); + public File mockFile; + public boolean skipped = false; protected File config = null; @@ -106,33 +105,16 @@ public void defineDirectories(File testDirectory) throws IOException { outputDir = constructDirectory(launchDir, DIRECTORY_OUTPUT); workDir = constructDirectory(launchDir, DIRECTORY_WORK); + mockFile = new File( ".nf-test-" + getHash() + ".nf"); + mockFile.deleteOnExit(); } @Override public void setup(Config config) throws IOException { - - initDirectory("Launch Directory", launchDir); - initDirectory("Meta Directory", metaDir); - initDirectory("Output Directory", outputDir); - initDirectory("Working Directory", workDir); - FileStaging[] sharedDirectories = new FileStaging[]{ - new FileStaging("bin", config != null ? config.getStageMode() : FileStaging.MODE_COPY), - new FileStaging("lib", config != null ? config.getStageMode() : FileStaging.MODE_COPY), - new FileStaging("assets", config != null ? config.getStageMode() : FileStaging.MODE_COPY) - }; - try { - // copy bin, assets and lib to metaDir - shareDirectories(sharedDirectories, metaDir); - if (config != null) { - // copy user defined staging directories - log.debug("Stage {} user provided files...", config.getStageBuilder().getPaths().size()); - shareDirectories(config.getStageBuilder().getPaths(), metaDir); - } - shareDirectories(parent.getStageBuilder().getPaths(), metaDir); - } catch (Exception e) { - throw new IOException("Testcase setup failed: Directories could not be shared:\n" + e); - } - + setupDirectory("Launch Directory", launchDir); + setupDirectory("Meta Directory", metaDir); + setupDirectory("Output Directory", outputDir); + setupDirectory("Working Directory", workDir); } @Override @@ -145,13 +127,13 @@ public void execute() throws Throwable { } } - public File constructDirectory(File root, String... childs) { + private File constructDirectory(File root, String... childs) { String path = FileUtil.path(root.getAbsolutePath(), FileUtil.path(childs)); File directory = new File(path).getAbsoluteFile(); return directory; } - public void initDirectory(String name, File directory) throws IOException { + private void setupDirectory(String name, File directory) throws IOException { try { FileUtil.deleteDirectory(directory); @@ -164,7 +146,7 @@ public void initDirectory(String name, File directory) throws IOException { @Override public void cleanup() { - // FileUtil.deleteDirectory(metaDir); + } @Override @@ -191,25 +173,10 @@ public String getHash() { throw new RuntimeException("Error generating hash"); } - return hash(parent.getFilename() + getName()); + return HashUtil.getMd5(parent.getFilename() + getName()); } - private String hash(String value) { - - MessageDigest md; - try { - md = MessageDigest.getInstance("MD5"); - md.update(value.getBytes()); - byte[] md5sum = md.digest(); - BigInteger bigInt = new BigInteger(1, md5sum); - return bigInt.toString(16); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return "??"; - } - } - public void tag(String tag) { tags.add(tag); } @@ -268,20 +235,6 @@ public boolean isWithTrace() { return withTrace; } - protected void shareDirectories(List directories, File stageDir) throws IOException { - for (FileStaging directory : directories) { - String metaDirectory = FileUtil.path(stageDir.getAbsolutePath(), directory.getPath()); - directory.stage(metaDirectory); - } - } - - protected void shareDirectories(FileStaging[] directories, File stageDir) throws IOException { - for (FileStaging directory : directories) { - String metaDirectory = FileUtil.path(stageDir.getAbsolutePath(), directory.getPath()); - directory.stage(metaDirectory); - } - } - @Override public void setUpdateSnapshot(boolean updateSnapshot) { this.updateSnapshot = updateSnapshot; diff --git a/src/main/java/com/askimed/nf/test/lang/function/FunctionTest.java b/src/main/java/com/askimed/nf/test/lang/function/FunctionTest.java index 768ce64b..5a9489d5 100644 --- a/src/main/java/com/askimed/nf/test/lang/function/FunctionTest.java +++ b/src/main/java/com/askimed/nf/test/lang/function/FunctionTest.java @@ -109,8 +109,10 @@ public void execute() throws Throwable { } // Create workflow mock - File workflow = new File(metaDir, FILE_MOCK); - writeWorkflowMock(workflow); + writeWorkflowMock(mockFile); + + // Copy mock file in meta folder for debugging + FileUtil.copy(mockFile, new File(metaDir, FILE_MOCK)); context.getParams().put("nf_test_output", metaDir.getAbsolutePath()); @@ -121,7 +123,7 @@ public void execute() throws Throwable { File paramsFile = new File(metaDir, FILE_PARAMS); NextflowCommand nextflow = new NextflowCommand(); - nextflow.setScript(workflow.getAbsolutePath()); + nextflow.setScript(mockFile.getAbsolutePath()); nextflow.setParams(context.getParams()); for (String profile: parent.getProfiles()) { nextflow.addProfile(profile); diff --git a/src/main/java/com/askimed/nf/test/lang/process/ProcessTest.java b/src/main/java/com/askimed/nf/test/lang/process/ProcessTest.java index 42d3fdde..20d4a72b 100644 --- a/src/main/java/com/askimed/nf/test/lang/process/ProcessTest.java +++ b/src/main/java/com/askimed/nf/test/lang/process/ProcessTest.java @@ -108,8 +108,10 @@ public void execute() throws Throwable { context.evaluateProcessClosure(); // Create workflow mock - File workflow = new File(metaDir, FILE_MOCK); - writeWorkflowMock(workflow); + writeWorkflowMock(mockFile); + + // Copy mock file in meta folder for debugging + FileUtil.copy(mockFile, new File(metaDir, FILE_MOCK)); context.getParams().put("nf_test_output", metaDir.getAbsolutePath()); @@ -124,7 +126,7 @@ public void execute() throws Throwable { File paramsFile = new File(metaDir, FILE_PARAMS); NextflowCommand nextflow = new NextflowCommand(); - nextflow.setScript(workflow.getAbsolutePath()); + nextflow.setScript(mockFile.getAbsolutePath()); nextflow.setParams(context.getParams()); for (String profile: parent.getProfiles()) { nextflow.addProfile(profile); diff --git a/src/main/java/com/askimed/nf/test/lang/workflow/WorkflowTest.java b/src/main/java/com/askimed/nf/test/lang/workflow/WorkflowTest.java index c595990d..16aedef9 100644 --- a/src/main/java/com/askimed/nf/test/lang/workflow/WorkflowTest.java +++ b/src/main/java/com/askimed/nf/test/lang/workflow/WorkflowTest.java @@ -121,8 +121,10 @@ public void execute() throws Throwable { context.evaluateWorkflowClosure(); // Create workflow mock - File workflow = new File(metaDir, FILE_MOCK); - writeWorkflowMock(workflow); + writeWorkflowMock(mockFile); + + // Copy mock file in meta folder for debugging + FileUtil.copy(mockFile, new File(metaDir, FILE_MOCK)); context.getParams().put("nf_test_output", metaDir.getAbsolutePath()); if (isDebug()) { @@ -136,7 +138,7 @@ public void execute() throws Throwable { File paramsFile = new File(metaDir, FILE_PARAMS); NextflowCommand nextflow = new NextflowCommand(); - nextflow.setScript(workflow.getAbsolutePath()); + nextflow.setScript(mockFile.getAbsolutePath()); nextflow.setParams(context.getParams()); for (String profile: parent.getProfiles()) { nextflow.addProfile(profile); diff --git a/src/main/java/com/askimed/nf/test/util/FileUtil.java b/src/main/java/com/askimed/nf/test/util/FileUtil.java index ea98c705..20d27b8f 100644 --- a/src/main/java/com/askimed/nf/test/util/FileUtil.java +++ b/src/main/java/com/askimed/nf/test/util/FileUtil.java @@ -1,14 +1,6 @@ package com.askimed.nf.test.util; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -189,4 +181,17 @@ public static String encodeBase64(byte[] bytes) { return encodedContent; } + public static void copy(File source, File dest) throws IOException { + try (InputStream is = new FileInputStream(source); + OutputStream os = new FileOutputStream(dest)) { + + byte[] buffer = new byte[1024]; + int length; + + // Read from the input stream and write to the output stream + while ((length = is.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + } + } } diff --git a/src/main/java/com/askimed/nf/test/util/HashUtil.java b/src/main/java/com/askimed/nf/test/util/HashUtil.java new file mode 100644 index 00000000..8f94773c --- /dev/null +++ b/src/main/java/com/askimed/nf/test/util/HashUtil.java @@ -0,0 +1,24 @@ +package com.askimed.nf.test.util; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class HashUtil { + + public static String getMd5(String value) { + + MessageDigest md; + try { + md = MessageDigest.getInstance("MD5"); + md.update(value.getBytes()); + byte[] md5sum = md.digest(); + BigInteger bigInt = new BigInteger(1, md5sum); + return bigInt.toString(16); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return "??"; + } + } + +} diff --git a/src/test/java/com/askimed/nf/test/lang/WorkflowTest.java b/src/test/java/com/askimed/nf/test/lang/WorkflowTest.java index bd009076..87e147c6 100644 --- a/src/test/java/com/askimed/nf/test/lang/WorkflowTest.java +++ b/src/test/java/com/askimed/nf/test/lang/WorkflowTest.java @@ -139,8 +139,9 @@ public void testIssue125() throws Exception { public void testStagingWithoutMapping() throws Exception { App app = new App(); - int exitCode = app.run(new String[] { "test", "test-data/workflow/staging/hello.nf.test" }); - assertEquals(1, exitCode); + // TODO: remove this test. no staging needed. + //int exitCode = app.run(new String[] { "test", "test-data/workflow/staging/hello.nf.test" }); + //assertEquals(1, exitCode); } @@ -183,4 +184,13 @@ public void testStagingInTestsuite() throws Exception { } + @Test + public void testRegex() throws Exception { + + App app = new App(); + int exitCode = app.run(new String[] { "test", "test-data/workflow/regex/workflow.nf.test" }); + assertEquals(0, exitCode); + + } + } diff --git a/test-data/workflow/regex/params.yaml b/test-data/workflow/regex/params.yaml new file mode 100644 index 00000000..455390bc --- /dev/null +++ b/test-data/workflow/regex/params.yaml @@ -0,0 +1,2 @@ +localOutputDir: "example_output" +someRegex: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}\$' \ No newline at end of file diff --git a/test-data/workflow/regex/workflow.nf b/test-data/workflow/regex/workflow.nf new file mode 100644 index 00000000..d8d5fbb3 --- /dev/null +++ b/test-data/workflow/regex/workflow.nf @@ -0,0 +1,36 @@ +process exampleProc { + + storeDir "${outputDir}/exampleProc" + input: + tuple( + val(outputDir), + val(localOutputDir), + val(someRegexString) + ) + + output: + tuple( + val(outputDir), + path("example_output/example*.txt") + ) + + shell: + """ + mkdir -p !{localOutputDir} + echo !{someRegexString} > "!{localOutputDir}/example1.txt" + """ +} + + +workflow PipeWf { + take: + inputCh + + main: + inputCh + | exampleProc + | set { outputCh } + + emit: + outputCh +} \ No newline at end of file diff --git a/test-data/workflow/regex/workflow.nf.test b/test-data/workflow/regex/workflow.nf.test new file mode 100644 index 00000000..41a5214f --- /dev/null +++ b/test-data/workflow/regex/workflow.nf.test @@ -0,0 +1,27 @@ +nextflow_workflow { + + name "Test workflow" + script "./workflow.nf" + workflow "PipeWf" + + test("Output will exist in default outputDir") { + + when { + + params { + outDir = "$outputDir" + load("test-data/workflow/regex/params.yaml") + } + workflow { + """ + input[0] = Channel.of([params.outDir,params.localOutputDir]) + """ + } + } + + then { + assert workflow.success + assert path("${outputDir}/exampleProc/example_output").exists() + } + } +} \ No newline at end of file