| 20 |
20 |
from jsonschema import ValidationError
|
| 21 |
21 |
|
| 22 |
22 |
from hydrilla import util as hydrilla_util
|
|
23 |
from hydrilla.util._util import _major_version_re
|
| 23 |
24 |
from hydrilla.builder import build, _version, local_apt
|
| 24 |
25 |
from hydrilla.builder.common_errors import *
|
| 25 |
26 |
|
| ... | ... | |
| 60 |
61 |
|
| 61 |
62 |
del src_files['report.spdx']
|
| 62 |
63 |
|
|
64 |
expected_source_copyright = [{
|
|
65 |
'file': 'report.spdx',
|
|
66 |
'sha256': sha256_hashes['report.spdx']
|
|
67 |
}, {
|
|
68 |
'file': 'LICENSES/CC0-1.0.txt',
|
|
69 |
'sha256': sha256_hashes['LICENSES/CC0-1.0.txt']
|
|
70 |
}]
|
|
71 |
|
| 63 |
72 |
expected_resources = [{
|
| 64 |
73 |
'$schema': 'https://hydrilla.koszko.org/schemas/api_resource_description-1.schema.json',
|
| 65 |
74 |
'source_name': 'hello',
|
| 66 |
|
'source_copyright': [{
|
| 67 |
|
'file': 'report.spdx',
|
| 68 |
|
'sha256': sha256_hashes['report.spdx']
|
| 69 |
|
}, {
|
| 70 |
|
'file': 'LICENSES/CC0-1.0.txt',
|
| 71 |
|
'sha256': sha256_hashes['LICENSES/CC0-1.0.txt']
|
| 72 |
|
}],
|
|
75 |
'source_copyright': expected_source_copyright,
|
| 73 |
76 |
'type': 'resource',
|
| 74 |
77 |
'identifier': 'helloapple',
|
| 75 |
78 |
'long_name': 'Hello Apple',
|
| ... | ... | |
| 89 |
92 |
}, {
|
| 90 |
93 |
'$schema': 'https://hydrilla.koszko.org/schemas/api_resource_description-1.schema.json',
|
| 91 |
94 |
'source_name': 'hello',
|
| 92 |
|
'source_copyright': [{
|
| 93 |
|
'file': 'report.spdx',
|
| 94 |
|
'sha256': sha256_hashes['report.spdx']
|
| 95 |
|
}, {
|
| 96 |
|
'file': 'LICENSES/CC0-1.0.txt',
|
| 97 |
|
'sha256': sha256_hashes['LICENSES/CC0-1.0.txt']
|
| 98 |
|
}],
|
|
95 |
'source_copyright': expected_source_copyright,
|
| 99 |
96 |
'type': 'resource',
|
| 100 |
97 |
'identifier': 'hello-message',
|
| 101 |
98 |
'long_name': 'Hello Message',
|
| ... | ... | |
| 114 |
111 |
expected_mapping = {
|
| 115 |
112 |
'$schema': 'https://hydrilla.koszko.org/schemas/api_mapping_description-1.schema.json',
|
| 116 |
113 |
'source_name': 'hello',
|
| 117 |
|
'source_copyright': [{
|
| 118 |
|
'file': 'report.spdx',
|
| 119 |
|
'sha256': sha256_hashes['report.spdx']
|
| 120 |
|
}, {
|
| 121 |
|
'file': 'LICENSES/CC0-1.0.txt',
|
| 122 |
|
'sha256': sha256_hashes['LICENSES/CC0-1.0.txt']
|
| 123 |
|
}],
|
|
114 |
'source_copyright': expected_source_copyright,
|
| 124 |
115 |
'type': 'mapping',
|
| 125 |
116 |
'identifier': 'helloapple',
|
| 126 |
117 |
'long_name': 'Hello Apple',
|
| ... | ... | |
| 141 |
132 |
expected_source_description = {
|
| 142 |
133 |
'$schema': 'https://hydrilla.koszko.org/schemas/api_source_description-1.schema.json',
|
| 143 |
134 |
'source_name': 'hello',
|
| 144 |
|
'source_copyright': [{
|
| 145 |
|
'file': 'report.spdx',
|
| 146 |
|
'sha256': sha256_hashes['report.spdx']
|
| 147 |
|
}, {
|
| 148 |
|
'file': 'LICENSES/CC0-1.0.txt',
|
| 149 |
|
'sha256': sha256_hashes['LICENSES/CC0-1.0.txt']
|
| 150 |
|
}],
|
|
135 |
'source_copyright': expected_source_copyright,
|
| 151 |
136 |
'source_archives': {
|
| 152 |
137 |
'zip': {
|
| 153 |
138 |
'sha256': '!!!!value to fill during test!!!!',
|
| ... | ... | |
| 155 |
140 |
},
|
| 156 |
141 |
'upstream_url': 'https://git.koszko.org/hydrilla-source-package-example',
|
| 157 |
142 |
'definitions': [{
|
|
143 |
'type': 'mapping',
|
|
144 |
'identifier': 'helloapple',
|
|
145 |
'long_name': 'Hello Apple',
|
|
146 |
'version': [2021, 11, 10],
|
|
147 |
}, {
|
| 158 |
148 |
'type': 'resource',
|
| 159 |
149 |
'identifier': 'helloapple',
|
| 160 |
150 |
'long_name': 'Hello Apple',
|
| ... | ... | |
| 164 |
154 |
'identifier': 'hello-message',
|
| 165 |
155 |
'long_name': 'Hello Message',
|
| 166 |
156 |
'version': [2021, 11, 10],
|
| 167 |
|
}, {
|
| 168 |
|
'type': 'mapping',
|
| 169 |
|
'identifier': 'helloapple',
|
| 170 |
|
'long_name': 'Hello Apple',
|
| 171 |
|
'version': [2021, 11, 10],
|
| 172 |
157 |
}],
|
| 173 |
158 |
'generated_by': expected_generated_by
|
| 174 |
159 |
}
|
| 175 |
160 |
|
| 176 |
|
expected = [*expected_resources, expected_mapping, expected_source_description]
|
|
161 |
expected = [expected_mapping, *expected_resources, expected_source_description]
|
|
162 |
expected_items = expected[:3]
|
| 177 |
163 |
|
| 178 |
164 |
def run_reuse(command, **kwargs):
|
| 179 |
165 |
"""
|
| ... | ... | |
| 212 |
198 |
class MockedPiggybacked:
|
| 213 |
199 |
"""Minimal mock of Piggybacked object."""
|
| 214 |
200 |
package_license_files = [PurePosixPath('.apt-root/.../copyright')]
|
| 215 |
|
package_must_depend = [{'identifier': 'apt-common-licenses'}]
|
|
201 |
resource_must_depend = [{'identifier': 'apt-common-licenses'}]
|
| 216 |
202 |
|
| 217 |
203 |
def resolve_file(path):
|
| 218 |
204 |
"""
|
| 219 |
|
For each path that starts with '.apt-root' return a valid
|
| 220 |
|
dummy file path.
|
|
205 |
For each path that starts with '.apt-root' return a valid dummy file
|
|
206 |
path.
|
| 221 |
207 |
"""
|
| 222 |
208 |
if path.parts[0] != '.apt-root':
|
| 223 |
209 |
return None
|
| ... | ... | |
| 289 |
275 |
@variant_maker
|
| 290 |
276 |
def sample_source_add_comments(monkeypatch, sample_source):
|
| 291 |
277 |
"""Add index.json comments that should be preserved."""
|
| 292 |
|
for dictionary in (index_obj, expected_source_description):
|
|
278 |
for dictionary in index_obj, *index_obj['definitions'], *expected:
|
| 293 |
279 |
monkeypatch.setitem(dictionary, 'comment', 'index.json comment')
|
| 294 |
280 |
|
| 295 |
|
for i, dicts in enumerate(zip(index_obj['definitions'], expected)):
|
| 296 |
|
for dictionary in dicts:
|
| 297 |
|
monkeypatch.setitem(dictionary, 'comment', 'index.json comment')
|
| 298 |
|
|
| 299 |
281 |
@variant_maker
|
| 300 |
282 |
def sample_source_remove_spdx(monkeypatch, sample_source):
|
| 301 |
283 |
"""Remove spdx report generation."""
|
| 302 |
284 |
monkeypatch.delitem(index_obj, 'reuse_generate_spdx_report')
|
| 303 |
285 |
|
| 304 |
|
for obj, key in [
|
| 305 |
|
(index_obj, 'copyright'),
|
| 306 |
|
*((definition, 'source_copyright') for definition in expected)
|
| 307 |
|
]:
|
| 308 |
|
new_list = [r for r in obj[key] if r['file'] != 'report.spdx']
|
| 309 |
|
monkeypatch.setitem(obj, key, new_list)
|
|
286 |
pred = lambda ref: ref['file'] != 'report.spdx'
|
|
287 |
copy_refs_in = list(filter(pred, index_obj['copyright']))
|
|
288 |
monkeypatch.setitem(index_obj, 'copyright', copy_refs_in)
|
|
289 |
|
|
290 |
copy_refs_out = list(filter(pred, expected_source_copyright))
|
|
291 |
for obj in expected:
|
|
292 |
monkeypatch.setitem(obj, 'source_copyright', copy_refs_out)
|
| 310 |
293 |
|
| 311 |
294 |
monkeypatch.delitem(dist_files, 'report.spdx')
|
| 312 |
295 |
|
| ... | ... | |
| 325 |
308 |
@variant_maker
|
| 326 |
309 |
def sample_source_remove_script(monkeypatch, sample_source):
|
| 327 |
310 |
"""Use default value ([]) for 'scripts' property in one of the resources."""
|
| 328 |
|
monkeypatch.delitem(index_obj['definitions'][1], 'scripts')
|
|
311 |
monkeypatch.delitem(index_obj['definitions'][2], 'scripts')
|
| 329 |
312 |
|
| 330 |
313 |
monkeypatch.setitem(expected_resources[1], 'scripts', [])
|
| 331 |
314 |
|
| ... | ... | |
| 335 |
318 |
@variant_maker
|
| 336 |
319 |
def sample_source_remove_payloads(monkeypatch, sample_source):
|
| 337 |
320 |
"""Use default value ({}) for 'payloads' property in mapping."""
|
| 338 |
|
monkeypatch.delitem(index_obj['definitions'][2], 'payloads')
|
|
321 |
monkeypatch.delitem(index_obj['definitions'][0], 'payloads')
|
| 339 |
322 |
|
| 340 |
323 |
monkeypatch.setitem(expected_mapping, 'payloads', {})
|
| 341 |
324 |
|
| ... | ... | |
| 363 |
346 |
if k != 'payloads')
|
| 364 |
347 |
monkeypatch.setitem(processed, 'spurious_property', 'some_value')
|
| 365 |
348 |
|
|
349 |
@variant_maker
|
|
350 |
def sample_source_make_version_2(monkeypatch, sample_source,
|
|
351 |
expected_documents_to_modify=[]):
|
|
352 |
"""Increase sources' schema version from to 2."""
|
|
353 |
for obj in index_obj, *expected_documents_to_modify:
|
|
354 |
monkeypatch.setitem(obj, '$schema', obj['$schema'].replace('1', '2'))
|
|
355 |
|
|
356 |
@variant_maker
|
|
357 |
def sample_source_cors_bypass_ignored(monkeypatch, sample_source, value=True):
|
|
358 |
"""
|
|
359 |
Specify CORS bypass permissions in sources, but keep sources' schema version
|
|
360 |
at 1.
|
|
361 |
"""
|
|
362 |
for definition in index_obj['definitions']:
|
|
363 |
monkeypatch.setitem(definition, 'permissions', {'cors_bypass': value})
|
|
364 |
|
|
365 |
@variant_maker
|
|
366 |
def sample_source_cors_bypass(monkeypatch, sample_source):
|
|
367 |
"""Specify CORS bypass permissions in sources."""
|
|
368 |
sample_source_cors_bypass_ignored(monkeypatch, sample_source, value=True)
|
|
369 |
sample_source_make_version_2(monkeypatch, sample_source, expected_items)
|
|
370 |
|
|
371 |
for obj in expected_items:
|
|
372 |
monkeypatch.setitem(obj, 'permissions', {'cors_bypass': True})
|
|
373 |
|
|
374 |
@variant_maker
|
|
375 |
def sample_source_cors_bypass_defaults(monkeypatch, sample_source):
|
|
376 |
"""
|
|
377 |
Specify CORS bypass permissions in sources but use the default value
|
|
378 |
("False").
|
|
379 |
"""
|
|
380 |
sample_source_cors_bypass_ignored(monkeypatch, sample_source, value=False)
|
|
381 |
sample_source_make_version_2(monkeypatch, sample_source)
|
|
382 |
|
|
383 |
@variant_maker
|
|
384 |
def sample_source_req_mappings_ignored(monkeypatch, sample_source,
|
|
385 |
value=[{'identifier': 'mapping-dep'}]):
|
|
386 |
"""
|
|
387 |
Specify dependencies on mappings, but keep sources' schema version at 1.
|
|
388 |
"""
|
|
389 |
for definition in index_obj['definitions']:
|
|
390 |
monkeypatch.setitem(definition, 'required_mappings', value);
|
|
391 |
|
|
392 |
@variant_maker
|
|
393 |
def sample_source_req_mappings(monkeypatch, sample_source):
|
|
394 |
"""Specify dependencies on mappings."""
|
|
395 |
sample_source_req_mappings_ignored(monkeypatch, sample_source)
|
|
396 |
sample_source_make_version_2(monkeypatch, sample_source, expected_items)
|
|
397 |
|
|
398 |
for obj in expected_items:
|
|
399 |
monkeypatch.setitem(obj, 'required_mappings',
|
|
400 |
[{'identifier': 'mapping-dep'}])
|
|
401 |
|
|
402 |
@variant_maker
|
|
403 |
def sample_source_req_mappings_defaults(monkeypatch, sample_source):
|
|
404 |
"""Specify dependencies of a mapping, but use the default value ("[]")."""
|
|
405 |
sample_source_req_mappings_ignored(monkeypatch, sample_source, value=[])
|
|
406 |
sample_source_make_version_2(monkeypatch, sample_source)
|
|
407 |
|
|
408 |
@variant_maker
|
|
409 |
def sample_source_combined_def(monkeypatch, sample_source):
|
|
410 |
"""Define mapping and resource together."""
|
|
411 |
sample_source_make_version_2(monkeypatch, sample_source)
|
|
412 |
|
|
413 |
mapping_def = index_obj['definitions'][0]
|
|
414 |
resource_defs = index_obj['definitions'][1:3]
|
|
415 |
|
|
416 |
item_defs_shortened = [mapping_def, resource_defs[1]]
|
|
417 |
monkeypatch.setitem(index_obj, 'definitions', item_defs_shortened)
|
|
418 |
|
|
419 |
monkeypatch.setitem(mapping_def, 'type', 'mapping_and_resource')
|
|
420 |
|
|
421 |
new_mapping_ver = [*expected_mapping['version'], 1]
|
|
422 |
monkeypatch.setitem(mapping_def, 'revision', 1)
|
|
423 |
monkeypatch.setitem(expected_mapping, 'version', new_mapping_ver)
|
|
424 |
|
|
425 |
for prop in 'scripts', 'dependencies':
|
|
426 |
monkeypatch.setitem(mapping_def, prop, resource_defs[0][prop])
|
|
427 |
|
|
428 |
monkeypatch.setitem(expected_resources[0], 'uuid', mapping_def['uuid'])
|
|
429 |
monkeypatch.setitem(expected_resources[0], 'description',
|
|
430 |
mapping_def['description'])
|
|
431 |
|
|
432 |
monkeypatch.setitem(expected_source_description['definitions'][0],
|
|
433 |
'version', new_mapping_ver)
|
|
434 |
|
|
435 |
@variant_maker
|
|
436 |
def sample_source_minmax_haketilo_ver_ignored(monkeypatch, sample_source,
|
|
437 |
min_ver=[1, 2], max_ver=[1, 2]):
|
|
438 |
"""
|
|
439 |
Specify version constraints on Haketilo, but keep sources' schema version at
|
|
440 |
1.
|
|
441 |
"""
|
|
442 |
mapping_def = index_obj['definitions'][0]
|
|
443 |
monkeypatch.setitem(mapping_def, 'min_haketilo_version', min_ver)
|
|
444 |
monkeypatch.setitem(mapping_def, 'max_haketilo_version', max_ver)
|
|
445 |
|
|
446 |
@variant_maker
|
|
447 |
def sample_source_minmax_haketilo_ver(monkeypatch, sample_source):
|
|
448 |
"""Specify version constraints on Haketilo."""
|
|
449 |
sample_source_minmax_haketilo_ver_ignored(monkeypatch, sample_source)
|
|
450 |
sample_source_make_version_2(monkeypatch, sample_source, [expected_mapping])
|
|
451 |
|
|
452 |
monkeypatch.setitem(expected_mapping, 'min_haketilo_version', [1, 2])
|
|
453 |
monkeypatch.setitem(expected_mapping, 'max_haketilo_version', [1, 2])
|
|
454 |
|
|
455 |
@variant_maker
|
|
456 |
def sample_source_minmax_haketilo_ver_default(monkeypatch, sample_source):
|
|
457 |
"""Specify version constraints on Haketilo, but use default values."""
|
|
458 |
sample_source_minmax_haketilo_ver_ignored(monkeypatch, sample_source,
|
|
459 |
min_ver=[1], max_ver=[65536])
|
|
460 |
sample_source_make_version_2(monkeypatch, sample_source)
|
|
461 |
|
| 366 |
462 |
piggyback_archive_names = [
|
| 367 |
463 |
'apt/something.deb',
|
| 368 |
464 |
'apt/something.orig.tar.gz',
|
| ... | ... | |
| 371 |
467 |
]
|
| 372 |
468 |
|
| 373 |
469 |
@variant_maker
|
| 374 |
|
def sample_source_add_piggyback(monkeypatch, sample_source,
|
| 375 |
|
extra_build_args={}):
|
| 376 |
|
"""Add piggybacked foreign system packages."""
|
|
470 |
def sample_source_add_piggyback_ignored(monkeypatch, sample_source,
|
|
471 |
extra_build_args={}):
|
|
472 |
"""
|
|
473 |
Add piggybacked foreign system packages, but keep sources' schema version at
|
|
474 |
1.
|
|
475 |
"""
|
| 377 |
476 |
old_build = build.Build
|
| 378 |
477 |
new_build = lambda *a, **kwa: old_build(*a, **kwa, **extra_build_args)
|
| 379 |
478 |
monkeypatch.setattr(build, 'Build', new_build)
|
| ... | ... | |
| 384 |
483 |
'packages': ['somelib=1.0'],
|
| 385 |
484 |
'dependencies': False
|
| 386 |
485 |
})
|
| 387 |
|
schema = 'https://hydrilla.koszko.org/schemas/package_source-2.schema.json'
|
| 388 |
|
monkeypatch.setitem(index_obj, '$schema', schema)
|
|
486 |
|
|
487 |
@variant_maker
|
|
488 |
def sample_source_add_piggyback(monkeypatch, sample_source,
|
|
489 |
extra_build_args={}):
|
|
490 |
"""Add piggybacked foreign system packages."""
|
|
491 |
sample_source_add_piggyback_ignored\
|
|
492 |
(monkeypatch, sample_source, extra_build_args)
|
|
493 |
|
|
494 |
sample_source_make_version_2(monkeypatch, sample_source)
|
| 389 |
495 |
|
| 390 |
496 |
new_refs = {}
|
| 391 |
497 |
for name in '.apt-root/.../copyright', '.apt-root/.../script.js':
|
| ... | ... | |
| 395 |
501 |
monkeypatch.setitem(sha256_hashes, name, digest)
|
| 396 |
502 |
new_refs[PurePosixPath(name).name] = {'file': name, 'sha256': digest}
|
| 397 |
503 |
|
|
504 |
new_list = [*expected_source_copyright, new_refs['copyright']]
|
| 398 |
505 |
for obj in expected:
|
| 399 |
|
new_list = [*obj['source_copyright'], new_refs['copyright']]
|
| 400 |
506 |
monkeypatch.setitem(obj, 'source_copyright', new_list)
|
| 401 |
507 |
|
| 402 |
508 |
for obj in expected_resources:
|
| 403 |
509 |
new_list = [{'identifier': 'apt-common-licenses'}, *obj['dependencies']]
|
| 404 |
510 |
monkeypatch.setitem(obj, 'dependencies', new_list)
|
| 405 |
511 |
|
| 406 |
|
for obj in index_obj['definitions'][0], expected_resources[0]:
|
|
512 |
for obj in index_obj['definitions'][1], expected_resources[0]:
|
| 407 |
513 |
new_list = [new_refs['script.js'], *obj['scripts']]
|
| 408 |
514 |
monkeypatch.setitem(obj, 'scripts', new_list)
|
| 409 |
515 |
|
| ... | ... | |
| 484 |
590 |
|
| 485 |
591 |
return index_path
|
| 486 |
592 |
|
|
593 |
def try_validate(as_what, instance):
|
|
594 |
"""
|
|
595 |
Select the right JSON schema. Return without errors only if the instance
|
|
596 |
validates against it.
|
|
597 |
"""
|
|
598 |
major = _major_version_re.search(instance['$schema']).group('major')
|
|
599 |
exact_schema_version = {'1': '1.0.1', '2': '2'}[major]
|
|
600 |
schema_filename = f'{as_what}-{exact_schema_version}.schema.json'
|
|
601 |
hydrilla_util.validator_for(schema_filename).validate(instance)
|
|
602 |
|
| 487 |
603 |
@pytest.mark.subprocess_run(build, run_reuse)
|
| 488 |
604 |
@pytest.mark.usefixtures('mock_subprocess_run')
|
| 489 |
605 |
def test_build(sample_source, sample_source_make_variants, tmpdir):
|
| ... | ... | |
| 516 |
632 |
|
| 517 |
633 |
for resource_json in expected_resources:
|
| 518 |
634 |
subdir = resource_dir / resource_json['identifier']
|
| 519 |
|
assert ['2021.11.10'] == [path.name for path in subdir.iterdir()]
|
|
635 |
ver_str = hydrilla_util.version_string(resource_json['version'])
|
|
636 |
assert [ver_str] == [path.name for path in subdir.iterdir()]
|
| 520 |
637 |
|
| 521 |
|
assert json.loads((subdir / '2021.11.10').read_text()) == resource_json
|
|
638 |
assert json.loads((subdir / ver_str).read_text()) == resource_json
|
| 522 |
639 |
|
| 523 |
|
hydrilla_util.validator_for('api_resource_description-1.0.1.schema.json')\
|
| 524 |
|
.validate(resource_json)
|
|
640 |
try_validate('api_resource_description', resource_json)
|
| 525 |
641 |
|
| 526 |
642 |
# Verify files under 'mapping/'
|
| 527 |
643 |
mapping_dir = tmpdir / 'mapping'
|
| 528 |
644 |
assert ['helloapple'] == [path.name for path in mapping_dir.iterdir()]
|
| 529 |
645 |
|
| 530 |
646 |
subdir = mapping_dir / 'helloapple'
|
| 531 |
|
assert ['2021.11.10'] == [path.name for path in subdir.iterdir()]
|
| 532 |
647 |
|
| 533 |
|
assert json.loads((subdir / '2021.11.10').read_text()) == expected_mapping
|
|
648 |
ver_str = hydrilla_util.version_string(expected_mapping['version'])
|
|
649 |
assert [ver_str] == [path.name for path in subdir.iterdir()]
|
| 534 |
650 |
|
| 535 |
|
hydrilla_util.validator_for('api_mapping_description-1.0.1.schema.json')\
|
| 536 |
|
.validate(expected_mapping)
|
|
651 |
assert json.loads((subdir / ver_str).read_text()) == expected_mapping
|
|
652 |
|
|
653 |
try_validate('api_mapping_description', expected_mapping)
|
| 537 |
654 |
|
| 538 |
655 |
# Verify files under 'source/'
|
| 539 |
656 |
source_dir = tmpdir / 'source'
|
| ... | ... | |
| 558 |
675 |
assert json.loads((source_dir / 'hello.json').read_text()) == \
|
| 559 |
676 |
expected_source_description
|
| 560 |
677 |
|
| 561 |
|
hydrilla_util.validator_for('api_source_description-1.0.1.schema.json')\
|
| 562 |
|
.validate(expected_source_description)
|
|
678 |
try_validate('api_source_description', expected_source_description)
|
| 563 |
679 |
|
| 564 |
680 |
error_makers = []
|
| 565 |
681 |
def error_maker(function):
|
| ... | ... | |
| 642 |
758 |
monkeypatch.setitem(index_obj, 'copyright', new_list)
|
| 643 |
759 |
return FileReferenceError, '^report_spdx_not_in_copyright_list$'
|
| 644 |
760 |
|
|
761 |
@error_maker
|
|
762 |
def sample_source_error_combined_unsupported(monkeypatch, sample_source):
|
|
763 |
"""
|
|
764 |
Define mapping and resource together but leave source schema version at 1.x
|
|
765 |
where this is unsupported.
|
|
766 |
"""
|
|
767 |
mapping_def = index_obj['definitions'][0]
|
|
768 |
monkeypatch.setitem(mapping_def, 'type', 'mapping_and_resource')
|
|
769 |
|
|
770 |
return ValidationError,
|
|
771 |
|
| 645 |
772 |
@pytest.fixture(params=error_makers)
|
| 646 |
773 |
def sample_source_make_errors(request, monkeypatch, sample_source):
|
| 647 |
774 |
"""
|
add tests for features from version 2 of source package JSON schema