-
-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathtest_inputs_schema_gen.py
More file actions
145 lines (118 loc) · 4.23 KB
/
Copy pathtest_inputs_schema_gen.py
File metadata and controls
145 lines (118 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# SPDX-License-Identifier: Apache-2.0
"""Tests for cwl-inputs-schema-gen."""
import logging
from pathlib import Path
import pytest
from jsonschema.exceptions import SchemaError, ValidationError
from jsonschema.validators import validate
from ruamel.yaml import YAML
from cwl_utils.inputs_schema_gen import cwl_to_jsonschema
from cwl_utils.parser import load_document_by_uri
from .util import get_path
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
TEST_PARAMS = [
# Packed Case
(
get_path("testdata/revsort-packed.cwl"),
get_path("testdata/revsort-job.json"),
),
# The number of parameters is a little large, and the definition itself is a straightforward case.
(
get_path("testdata/bwa-mem-tool.cwl"),
get_path("testdata/bwa-mem-job.json"),
),
# The case where CommandInputParameter is shortened (e.g., param: string)
(
get_path("testdata/env-tool1.cwl"),
get_path("testdata/env-job.json"),
),
# Dir
(
get_path("testdata/dir.cwl"),
get_path("testdata/dir-job.yml"),
),
# SecondaryFiles
(
get_path("testdata/rename-inputs.cwl"),
get_path("testdata/rename-inputs.yml"),
),
# Stage array
(
get_path("testdata/stage-array.cwl"),
get_path("testdata/stage-array-job.json"),
),
]
@pytest.mark.parametrize("tool_path,inputs_path", TEST_PARAMS)
def test_cwl_inputs_to_jsonschema(tool_path: Path, inputs_path: Path) -> None:
cwl_obj = load_document_by_uri(tool_path.as_uri())
logger.info(f"Generating schema for {tool_path.name}")
json_schema = cwl_to_jsonschema(cwl_obj)
logger.info(
f"Testing {inputs_path.name} against schema generated for input {tool_path.name}"
)
input_obj = YAML().load(inputs_path)
try:
validate(input_obj, json_schema)
except (ValidationError, SchemaError) as err:
logger.error(
f"Validation failed for {inputs_path.name} "
f"against schema generated for input {tool_path.name}"
)
raise SchemaError(f"{inputs_path.name} failed schema validation") from err
def test_cwl_inputs_to_jsonschema_single_fail() -> None:
"""Compare tool schema of param 1 against input schema of param 2."""
tool_path: Path = TEST_PARAMS[0][0]
inputs_path: Path = TEST_PARAMS[3][1]
cwl_obj = load_document_by_uri(tool_path.as_uri())
logger.info(f"Generating schema for {tool_path.name}")
json_schema = cwl_to_jsonschema(cwl_obj)
logger.info(
f"Testing {inputs_path.name} against schema generated for input {tool_path.name}"
)
input_obj = YAML().load(inputs_path)
# We expect this to fail
with pytest.raises(ValidationError):
validate(input_obj, json_schema)
BAD_TEST_PARAMS = [
# Any without defaults cannot be unspecified
(
get_path("testdata/null-expression2-tool.cwl"),
get_path("testdata/empty.json"),
"'i1' is a required property",
),
# null to Any type without a default value.
(
get_path("testdata/null-expression2-tool.cwl"),
get_path("testdata/null-expression1-job.json"),
"None is not valid under any of the given schemas",
),
# Any without defaults, unspecified
(
get_path("testdata/echo-tool.cwl"),
get_path("testdata/null-expression-echo-job.json"),
"None is not valid under any of the given schemas",
),
# JSON null provided for required input
(
get_path("testdata/echo-tool.cwl"),
get_path("testdata/null-expression1-job.json"),
"'in' is a required property",
),
]
@pytest.mark.parametrize("tool_path,inputs_path,exception_message", BAD_TEST_PARAMS)
def test_cwl_inputs_to_jsonschema_fails(
tool_path: Path,
inputs_path: Path,
exception_message: str,
) -> None:
cwl_obj = load_document_by_uri(tool_path.as_uri())
logger.info(f"Generating schema for {tool_path.name}")
json_schema = cwl_to_jsonschema(cwl_obj)
logger.info(
f"Testing {inputs_path.name} against schema generated for input {tool_path.name}"
)
yaml = YAML()
input_obj = yaml.load(inputs_path)
with pytest.raises(ValidationError, match=exception_message):
validate(input_obj, json_schema)