Repository navigation
Validate and print the value of Channel and Value params instead of hanging #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
d7d98d0
fca4bf6
ccbd62c
e7546d9
52c4e0f
545b4a2
2d38836
123b70d
cb92ef6
163165a
8a009f9
d945c9a
df0a0cb
e86c650
e804b6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package nextflow.validation.parameters | ||
|
|
||
| import static nextflow.validation.utils.Common.replaceDataflowParams | ||
| import static nextflow.NF.isSyntaxParserV2 | ||
|
|
||
| import static nextflow.validation.utils.Colors.getLogColors | ||
|
|
@@ -124,7 +125,11 @@ class ParameterValidator { | |
| final Map options = [:], | ||
| Session session | ||
| ) { | ||
| Map<String, Object> params = initialiseExpectedParams(session.params) | ||
| Map<String, Object> params = replaceDataflowParams( | ||
| initialiseExpectedParams(session.params), | ||
| session.cliParams, | ||
| session.config?.params | ||
| ) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you move this transformation to a converter in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Converter doesn't fit well, I think. It only gets the value, not where it sits, so it can't find the matching entry in the config params, and nested params ( .addConverter(Map) { Map map ->
map.is(params) ? replaceDataflowParams(map, session.config?.params) : map
}but that clashes with the existing
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those converters will also convert nested values. For example the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved it into the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really know what I'm doing here- might need your help for missing pieces if this doesn't cover them.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's empty at that point, then the validation itself will also find nothing to validate there, right? Maybe we should just skip validation of Channel objects then? 🤔
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Answered together with your converter question here: #230 (comment) |
||
| String schemaFilename = options?.containsKey('parameters_schema') ? | ||
| options.parameters_schema as String : | ||
| config.parametersSchema as String | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| /* groovylint-disable LineLength, MethodName */ | ||
| package nextflow.validation | ||
|
|
||
| import groovy.transform.CompileDynamic | ||
| import groovyx.gpars.dataflow.DataflowQueue | ||
| import groovyx.gpars.dataflow.DataflowVariable | ||
| import nextflow.Session | ||
| import nextflow.dataflow.ChannelImpl | ||
| import nextflow.dataflow.ValueImpl | ||
| import nextflow.validation.config.ValidationConfig | ||
| import nextflow.validation.exceptions.SchemaValidationException | ||
| import nextflow.validation.parameters.ParameterValidator | ||
| import spock.lang.Specification | ||
| import spock.lang.Timeout | ||
|
|
||
| import java.nio.file.Path | ||
|
|
||
| /** | ||
| * Validation of params that hold a dataflow value (a typed `Channel` or `Value` param), where the | ||
| * value given on the command line or in the config is validated in place of the dataflow object. | ||
| * The session is mocked so that the command line params can be set directly. | ||
| */ | ||
| @CompileDynamic | ||
| @Timeout(60) | ||
| class ValidateDataflowParamsTest extends Specification { | ||
|
|
||
| private static final String SCHEMA = 'src/testResources/nextflow_schema.json' | ||
| private static final String NESTED_SCHEMA = 'src/testResources/nextflow_schema_nested_parameters.json' | ||
|
|
||
| void 'should accept a valid command line value for a dataflow param'() { | ||
| given: | ||
| Session session = mockSession(topLevelParams(new DataflowVariable()), [input: 'src/testResources/correct.csv'], [:]) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| noExceptionThrown() | ||
| } | ||
|
|
||
| void 'should reject an invalid command line value for a dataflow param'() { | ||
| given: | ||
| Session session = mockSession(topLevelParams(new DataflowVariable()), [input: 'src/testResources/correct.txt'], [:]) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| SchemaValidationException error = thrown(SchemaValidationException) | ||
| error.message.contains('--input (src/testResources/correct.txt)') | ||
| } | ||
|
|
||
| void 'should validate the command line value over the config value - invalid command line value'() { | ||
| given: | ||
| Session session = mockSession( | ||
| topLevelParams(new DataflowVariable()), | ||
| [input: 'src/testResources/correct.txt'], | ||
| [input: 'src/testResources/correct.csv'] | ||
| ) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| SchemaValidationException error = thrown(SchemaValidationException) | ||
| error.message.contains('--input (src/testResources/correct.txt)') | ||
| } | ||
|
|
||
| void 'should validate the command line value over the config value - valid command line value'() { | ||
| given: | ||
| Session session = mockSession( | ||
| topLevelParams(new DataflowVariable()), | ||
| [input: 'src/testResources/correct.csv'], | ||
| [input: 'src/testResources/correct.txt'] | ||
| ) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| noExceptionThrown() | ||
| } | ||
|
|
||
| void 'should accept a valid command line value for a Value param'() { | ||
| given: | ||
| Session session = mockSession(topLevelParams(new ValueImpl(new DataflowVariable())), [input: 'src/testResources/correct.csv'], [:]) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| noExceptionThrown() | ||
| } | ||
|
|
||
| void 'should reject an invalid command line value for a Value param'() { | ||
| given: | ||
| Session session = mockSession(topLevelParams(new ValueImpl(new DataflowVariable())), [input: 'src/testResources/correct.txt'], [:]) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| SchemaValidationException error = thrown(SchemaValidationException) | ||
| error.message.contains('--input (src/testResources/correct.txt)') | ||
| } | ||
|
|
||
| void 'should accept a valid command line value for a Channel param'() { | ||
| given: | ||
| Session session = mockSession(topLevelParams(new ChannelImpl(new DataflowQueue())), [input: 'src/testResources/correct.csv'], [:]) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| noExceptionThrown() | ||
| } | ||
|
|
||
| void 'should reject an invalid command line value for a Channel param'() { | ||
| given: | ||
| Session session = mockSession(topLevelParams(new ChannelImpl(new DataflowQueue())), [input: 'src/testResources/correct.txt'], [:]) | ||
|
|
||
| when: | ||
| validate(session, SCHEMA) | ||
|
|
||
| then: | ||
| SchemaValidationException error = thrown(SchemaValidationException) | ||
| error.message.contains('--input (src/testResources/correct.txt)') | ||
| } | ||
|
|
||
| void 'should accept a valid command line value for a dataflow value nested in a record param'() { | ||
| given: | ||
| Session session = mockSession( | ||
| [map: [is: [so: [deep: new ValueImpl(new DataflowVariable())]]]], | ||
| [map: [is: [so: [deep: true]]]], | ||
| [:] | ||
| ) | ||
|
|
||
| when: | ||
| validate(session, NESTED_SCHEMA) | ||
|
|
||
| then: | ||
| noExceptionThrown() | ||
| } | ||
|
|
||
| void 'should reject an invalid command line value for a dataflow value nested in a record param'() { | ||
| given: | ||
| Session session = mockSession( | ||
| [map: [is: [so: [deep: new ValueImpl(new DataflowVariable())]]]], | ||
| [map: [is: [so: [deep: 'maybe']]]], | ||
| [:] | ||
| ) | ||
|
|
||
| when: | ||
| validate(session, NESTED_SCHEMA) | ||
|
|
||
| then: | ||
| SchemaValidationException error = thrown(SchemaValidationException) | ||
| error.message.contains('--map.is.so.deep') | ||
| } | ||
|
|
||
| private Session mockSession(Map params, Map cliParams, Map configParams) { | ||
| Session session = Mock(Session) | ||
| session.params >> params | ||
| session.cliParams >> cliParams | ||
| session.config >> [params: configParams] | ||
| session.baseDir >> Path.of('.').toAbsolutePath() | ||
| return session | ||
| } | ||
|
|
||
| private void validate(Session session, String schema) { | ||
| ValidationConfig config = new ValidationConfig([monochromeLogs: true], session) | ||
| new ParameterValidator(config).validateParametersMap( | ||
| [parameters_schema: Path.of(schema).toAbsolutePath().toString()], | ||
| session | ||
| ) | ||
| } | ||
|
|
||
| private Map topLevelParams(Object input) { | ||
| return [input: input, outdir: 'src/testResources/testDir'] | ||
| } | ||
|
|
||
| } |
Uh oh!
There was an error while loading. Please reload this page.