Hi! I am working on implementing pipeline level nf...
# nf-test
s
Hi! I am working on implementing pipeline level nf-tests, but I get unstable behaviour: some
nf-test test
runs are successful, but for some I get a failed assertion. I then saw that files that I specify in the .nftignore are still added to the snapshot (which shouldn't happen, right?). The things I double checked is that my .nftignore is in the tests folder (
./tests/.nftignore
), .. I trigger .nftignore in
./nf-test.config
as:
Copy code
triggers 'nextflow.config', 'nf-test.config', 'conf/test.config', 'tests/nextflow.config', 'tests/.nftignore'
.. and I mention .nftignore my
test_<name>.nf.test
file:
Copy code
...
then {

            def stable_contents = getAllFilesFromDir(params.outdir,
                                                    relative: false,
                                                    includeDir: false,
                                                    ignoreFile: 'tests/.nftignore'
                                                    ) 
    ...
}
Is there anything else I can check to understand why my
./tests/.nftignore
is not being used when updating the snapshot (I did try to rebuild it several times)? Thank you! 🙏
m
Do you have an open PR for this?
s
Unfortunately this is not a public pipeline.
m
Then to debug, I would suggest making sure the paths are correct
s
Thanks for the tip! You mean the paths inside
.nftignore
? For example, now, in the
.nftignore
I have **/PCA.png, this regex should exclude PCA.png files in all folders and subfolders, right?
m
Yeah that should work indeed
s
Hm, still no luck. I am using "nextflow": "24.04.4" and "nf-test": "0.9.3", could there be any subtle syntax differences?
m
No there shouldn't. I've been using this since I developed the plugin and no changes in syntax or behavior there yet. Try to print out the list of the files to see more information. And maybe try a more specific path first
s
Thanks! I tried more specific paths and I tried printing the files to see if my .nftignore is read correctly and it actually does not seem to be the problem. What I did to print the files was to add a print statement inside my
test_<name>.nf.test
:
Copy code
...
        then {
            def stable_name = getAllFilesFromDir(params.outdir,
                                                relative: true,
                                                includeDir: true,
                                                ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc_dataset/*.html']
                                                )

            def stable_contents = getAllFilesFromDir(params.outdir,
                                                    relative: false,
                                                    includeDir: false,
                                                    ignoreFile: 'tests/.nftignore'
                                                    ) 

            // DEBUGGING
            def all_files = getAllFilesFromDir(
                params.outdir,
                relative: false,
                includeDir: false
            )

            // DEBUGGING 
            println "\n--- IGNORED FILES ---"
            (all_files - stable_contents).each { println it } // <---- printing files that are not in stable_contents, looks good! I see paths to files that I want to exclude.


            assertAll(

                // Check that file names and contents are stable
                { assert snapshot(
                    workflow.trace.succeeded().size(),
                    stable_name,
                    stable_contents
                    ).match() }
....
And yet I get 1 failed assertion
java.lang.RuntimeException: Different Snapshot:
where I see files (that I saw being excluded from stable_contents) having unmatched md5sums ( filename:md5, .1aaa.. | filename:md5, .2bbb.. ) Really puzzled.
I now also tried stripping the pipeline to only one process and played around with different regex in the .nftignore file. With this small test example I get expected behaviour (I can exclude the file I want and re-run the test wo any assertions failing).
Alright, I know what caused the issue(🎊), though I don't yet understand the full picture. Dynamic files (that I tried excluding with .nftignore, but which still caused failed assertion) were outputted by a process which used
publishDir
with `mode: 'symlink'`:
Copy code
publishDir "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}", mode: 'symlink', failOnError: true
Once I switched to
mode: 'copy'
I no longer got failed assertions. Is there something that one should be aware of when using symlinks and nf-test?
m
Ooooh, nice catch
🙌 1
You are good, it would definitively have taken me longer time to get this
For me this issue is more to do with the plugin than nf-test itself, but let me check with @Nicolas Vannieuwkerke what he's thinking
n
I'm actually not sure, I think you might be the first one to test this with symlinked files 😁.
😄 1
How do you get the filenames in the plugin?
n
That should be fine...
m
That's what I assumed
n
It could have something to do with your glob matching? Maybe it doesn't work properly on symlinks
s
I am now also trying to reproduce the failed assertion on the reduced version of the pipeline. Lets see.
Alright, I think the issue is not the symlink alone, but it is rather the combination of the symlink + process outputting a path to a folder (this is my best guess atm 🙂), e.g.:
Copy code
publishDir "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}", mode: 'symlink', failOnError: true

output:
path('test')
As a workaround, I now excluded the whole process output folder, e.g. by adding
test/**
to .nftignore.