Skip to content

Commit 4916ea2

Browse files
author
alanbchristie
authored
Merge pull request #14 from InformaticsMatters/issue-9
Now validates against used outputDescriptor definitions
2 parents 278d2b8 + f22d62d commit 4916ea2

File tree

7 files changed

+263
-105
lines changed

7 files changed

+263
-105
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ dist
1010
work
1111
.nextflow
1212
.nextflow.log*
13-
/tmp
13+
**/tmp
1414
**/*.egg-info
1515
**/.DS_Store

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ installed as normal:
2626
> The module utilities should support both Python 2 and 3 but we recommend
2727
any modules/pipelines you write support both flavours.
2828

29+
## Adding this project as a submodule for a new pipelines project
30+
If you have started a new pipelines project you can add these utilities
31+
to it by running the following from the project root of your new project: -
32+
33+
$ git submodule add https://github.com/InformaticsMatters/pipelines-utils.git
34+
35+
This will create a new directory (`pipelines-utils`) and a `.gitmodules` file.
36+
You must add the `.gitmodules` to your project. Read about the Git [Submodule]
37+
for more information.
38+
39+
If you checkout a new working copy you will need to initialise the submodule
40+
with the command: -
41+
42+
$ git submodule update --init --remote
43+
2944
## Running the test framework
3045
> We plan to release the Python utility modules to [PIP] at some stage. The
3146
distribution is based on `setup.py` is present and works and will be

src/groovy/Log.groovy

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env groovy
2+
3+
/**
4+
* Copyright (c) 2018 Informatics Matters Ltd.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
/**
20+
* A simple log/printing utility module.
21+
*/
22+
23+
// Number of warnings generated
24+
def warningCount = 7
25+
26+
/**
27+
* Print a simple separator (a bar) to stdout.
28+
* Used to visually separate generated output into logical blocks.
29+
*/
30+
static separate() {
31+
32+
// To look 'pretty' this should align with the field width
33+
// used in the info() function
34+
println "+----------------+"
35+
36+
}
37+
38+
/**
39+
* Print an 'info' message prefixed with `->` string. You can specify a
40+
* tag and a message which is printed as "-> <tag> : <msg>"
41+
*/
42+
static info(String tag, String msg) {
43+
44+
println ":" + sprintf('%16s: %s', tag, msg)
45+
46+
}
47+
48+
/**
49+
* Print a warning message (and counts it).
50+
*/
51+
static warning(String msg) {
52+
53+
println "WARNING: $msg"
54+
Log.warningCount += 1
55+
56+
}
57+
58+
/**
59+
* Print an error message.
60+
*/
61+
static err(String msg) {
62+
63+
println "ERROR: $msg"
64+
65+
}

src/groovy/MediaChecker.groovy

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env groovy
2+
3+
/**
4+
* Copyright (c) 2018 Informatics Matters Ltd.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
/**
20+
* The MediaTypes class. A class to provide validation of files produced
21+
* by an executing pipeline.
22+
*/
23+
class MediaChecker {
24+
25+
final static String mediaTypesFile = 'MediaTypes.txt'
26+
27+
// A map of media type and expected file extension(s).
28+
// This is populated by the constructor, which reads the content
29+
// of 'mediaTypesFile'.
30+
def mediaTypesLookup = null
31+
32+
/**
33+
* Default constructor.
34+
* Reads media types config file.
35+
*/
36+
MediaChecker() {
37+
38+
mediaTypesLookup = new ConfigSlurper().parse(new File(mediaTypesFile).toURI().toURL())
39+
40+
}
41+
42+
/**
43+
* Checks that a pipeline's expected files exist.
44+
*
45+
* @param serviceDescriptor The test service descriptor
46+
* @param path The test path (where the pipeline's files are to be found)
47+
* @return True on success, False otherwise.
48+
*/
49+
boolean check(serviceDescriptor, File path) {
50+
51+
boolean retVal = true
52+
53+
// Check output descriptors for expected output file names...
54+
// Do all, regardless of individual failure.
55+
def opDescriptors = serviceDescriptor.serviceConfig.outputDescriptors
56+
opDescriptors.each { desc ->
57+
58+
// There must be a matching media type in our txt/lookup file.
59+
def typeExtList = mediaTypesLookup.media_types[desc.mediaType]
60+
if (typeExtList == null || typeExtList.size() == 0) {
61+
Log.err("Pipeline service descriptor output mediaType" +
62+
" '$desc.mediaType' is not listed in '$mediaTypesFile'")
63+
} else {
64+
// What are the expected file extensions for this media type?
65+
// It's a list of 1 or more entries.
66+
typeExtList.each { extension ->
67+
68+
String opName = desc.name + extension
69+
Log.info('Media check', opName)
70+
String opPath = path.toString() + File.separator + opName
71+
if (!new File(opPath).exists()) {
72+
Log.err("The pipeline's 'outputDescriptor'" +
73+
" expected '$opName' but the file wasn't found")
74+
retVal = false
75+
}
76+
77+
}
78+
}
79+
80+
}
81+
82+
return retVal
83+
84+
}
85+
86+
}

src/groovy/MediaTypes.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Input/Output Descriptor dictionary for use with the PipelineTester.
2+
// This is a map of input/output descriptor `mediaType` identifiers,
3+
// with expected filename extension(s).
4+
//
5+
// Read by MediaChecker.groovy
6+
7+
media_types = [
8+
9+
// Please keep the keys in alphabetical order...
10+
11+
'application/x-squonk-dataset-molecule+json': ['.data.gz', '.metadata'],
12+
'application/x-squonk-dataset-basic+json': ['.data.gz', '.metadata'],
13+
14+
'image/gif': ['.gif'],
15+
'image/jpeg': ['.jpg'],
16+
'image/png': ['.png'],
17+
18+
]

src/groovy/PipelineTester.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
// Version
3333
// Update with every change/release
34-
String version = '2.0.0'
34+
String version = '2.1.0'
3535

3636
println "+----------------+"
3737
println "| PipelineTester | v$version"

0 commit comments

Comments
 (0)