| #!/usr/bin/env python |
| |
| import json, sys |
| from common_paths import * |
| |
| def assert_non_empty_string(obj, field): |
| assert field in obj, 'Missing field "%s"' % field |
| assert isinstance(obj[field], basestring), \ |
| 'Field "%s" must be a string' % field |
| assert len(obj[field]) > 0, 'Field "%s" must not be empty' % field |
| |
| def assert_non_empty_list(obj, field): |
| assert isinstance(obj[field], list), \ |
| '%s must be a list' % field |
| assert len(obj[field]) > 0, \ |
| '%s list must not be empty' % field |
| |
| def assert_non_empty_dict(obj, field): |
| assert isinstance(obj[field], dict), \ |
| '%s must be a dict' % field |
| assert len(obj[field]) > 0, \ |
| '%s dict must not be empty' % field |
| |
| def assert_contains(obj, field): |
| assert field in obj, 'Must contain field "%s"' % field |
| |
| def assert_value_from(obj, field, items): |
| assert obj[field] in items, \ |
| 'Field "%s" must be from: %s' % (field, str(items)) |
| |
| def assert_atom_or_list_items_from(obj, field, items): |
| if isinstance(obj[field], basestring) or isinstance(obj[field], int): |
| assert_value_from(obj, field, items) |
| return |
| |
| assert_non_empty_list(obj, field) |
| for allowed_value in obj[field]: |
| assert allowed_value != '*', "Wildcard is not supported for lists!" |
| assert allowed_value in items, \ |
| 'Field "%s" must be from: %s' % (field, str(items)) |
| |
| def assert_contains_only_fields(obj, expected_fields): |
| for expected_field in expected_fields: |
| assert_contains(obj, expected_field) |
| |
| for actual_field in obj: |
| assert actual_field in expected_fields, \ |
| 'Unexpected field "%s".' % actual_field |
| |
| def assert_value_unique_in(value, used_values): |
| assert value not in used_values, 'Duplicate value "%s"!' % str(value) |
| used_values[value] = True |
| |
| |
| def validate(spec_json, details): |
| """ Validates the json specification for generating tests. """ |
| |
| details['object'] = spec_json |
| assert_contains_only_fields(spec_json, ["specification", |
| "referrer_policy_schema", |
| "test_expansion_schema", |
| "subresource_path", |
| "excluded_tests"]) |
| assert_non_empty_list(spec_json, "specification") |
| assert_non_empty_list(spec_json, "referrer_policy_schema") |
| assert_non_empty_dict(spec_json, "test_expansion_schema") |
| assert_non_empty_list(spec_json, "excluded_tests") |
| |
| specification = spec_json['specification'] |
| referrer_policy_schema = spec_json['referrer_policy_schema'] |
| test_expansion_schema = spec_json['test_expansion_schema'] |
| excluded_tests = spec_json['excluded_tests'] |
| subresource_path = spec_json['subresource_path'] |
| |
| valid_test_expansion_fields = ['name'] + test_expansion_schema.keys() |
| |
| # Validate each single spec. |
| for spec in specification: |
| details['object'] = spec |
| |
| # Validate required fields for a single spec. |
| assert_contains_only_fields(spec, ['name', |
| 'title', |
| 'description', |
| 'referrer_policy', |
| 'specification_url', |
| 'test_expansion']) |
| assert_non_empty_string(spec, 'name') |
| assert_non_empty_string(spec, 'title') |
| assert_non_empty_string(spec, 'description') |
| assert_non_empty_string(spec, 'specification_url') |
| assert_value_from(spec, 'referrer_policy', referrer_policy_schema) |
| assert_non_empty_list(spec, 'test_expansion') |
| |
| # Validate spec's test expansion. |
| used_spec_names = {} |
| |
| for spec_exp in spec['test_expansion']: |
| details['object'] = spec_exp |
| assert_non_empty_string(spec_exp, 'name') |
| # The name is unique in same expansion group. |
| assert_value_unique_in((spec_exp['expansion'], spec_exp['name']), |
| used_spec_names) |
| assert_contains_only_fields(spec_exp, valid_test_expansion_fields) |
| |
| for artifact in test_expansion_schema: |
| details['test_expansion_field'] = artifact |
| assert_atom_or_list_items_from( |
| spec_exp, artifact, ['*'] + test_expansion_schema[artifact]) |
| del details['test_expansion_field'] |
| |
| # Validate the test_expansion schema members. |
| details['object'] = test_expansion_schema |
| assert_contains_only_fields(test_expansion_schema, ['expansion', |
| 'delivery_method', |
| 'redirection', |
| 'origin', |
| 'source_protocol', |
| 'target_protocol', |
| 'subresource', |
| 'referrer_url']) |
| # Validate excluded tests. |
| details['object'] = excluded_tests |
| for excluded_test_expansion in excluded_tests: |
| assert_contains_only_fields(excluded_test_expansion, |
| valid_test_expansion_fields) |
| details['object'] = excluded_test_expansion |
| for artifact in test_expansion_schema: |
| details['test_expansion_field'] = artifact |
| assert_atom_or_list_items_from( |
| excluded_test_expansion, |
| artifact, |
| ['*'] + test_expansion_schema[artifact]) |
| del details['test_expansion_field'] |
| |
| # Validate subresource paths. |
| details['object'] = subresource_path |
| assert_contains_only_fields(subresource_path, |
| test_expansion_schema['subresource']); |
| |
| for subresource in subresource_path: |
| local_rel_path = "." + subresource_path[subresource] |
| full_path = os.path.join(test_root_directory, local_rel_path) |
| assert os.path.isfile(full_path), "%s is not an existing file" % path |
| |
| del details['object'] |
| |
| |
| def assert_valid_spec_json(spec_json): |
| error_details = {} |
| try: |
| validate(spec_json, error_details) |
| except AssertionError, err: |
| print 'ERROR:', err.message |
| print json.dumps(error_details, indent=4) |
| sys.exit(1) |
| |
| |
| def main(): |
| spec_json = load_spec_json(); |
| assert_valid_spec_json(spec_json) |
| print "Spec JSON is valid." |
| |
| |
| if __name__ == '__main__': |
| main() |