Coverage for mlos_bench/mlos_bench/tests/config/schemas/storage/test_storage_schemas.py: 100%
24 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 00:44 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 00:44 +0000
1#
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4#
5"""Tests for storage schema validation."""
7from os import path
9import pytest
11from mlos_bench.config.schemas import ConfigSchema
12from mlos_bench.storage.base_storage import Storage
13from mlos_bench.tests import try_resolve_class_name
14from mlos_bench.tests.config.schemas import (
15 check_test_case_against_schema,
16 check_test_case_config_with_extra_param,
17 get_schema_test_cases,
18)
19from mlos_core.tests import get_all_concrete_subclasses
21# General testing strategy:
22# - hand code a set of good/bad configs (useful to test editor schema checking)
23# - for each config, load and validate against expected schema
25TEST_CASES = get_schema_test_cases(path.join(path.dirname(__file__), "test-cases"))
27# Dynamically enumerate some of the cases we want to make sure we cover.
29expected_mlos_bench_storage_class_names = [
30 subclass.__module__ + "." + subclass.__name__
31 for subclass in get_all_concrete_subclasses(
32 Storage, # type: ignore[type-abstract]
33 pkg_name="mlos_bench",
34 )
35]
36assert expected_mlos_bench_storage_class_names
38# Do the full cross product of all the test cases and all the storage types.
41@pytest.mark.parametrize("test_case_subtype", sorted(TEST_CASES.by_subtype))
42@pytest.mark.parametrize("mlos_bench_storage_type", expected_mlos_bench_storage_class_names)
43def test_case_coverage_mlos_bench_storage_type(
44 test_case_subtype: str,
45 mlos_bench_storage_type: str,
46) -> None:
47 """Checks to see if there is a given type of test case for the given mlos_bench
48 storage type.
49 """
50 for test_case in TEST_CASES.by_subtype[test_case_subtype].values():
51 if try_resolve_class_name(test_case.config.get("class")) == mlos_bench_storage_type:
52 return
53 raise NotImplementedError(
54 f"Missing test case for subtype {test_case_subtype} "
55 f"for Storage class {mlos_bench_storage_type}"
56 )
59# Now we actually perform all of those validation tests.
62@pytest.mark.parametrize("test_case_name", sorted(TEST_CASES.by_path))
63def test_storage_configs_against_schema(test_case_name: str) -> None:
64 """Checks that the storage config validates against the schema."""
65 check_test_case_against_schema(TEST_CASES.by_path[test_case_name], ConfigSchema.STORAGE)
66 check_test_case_against_schema(TEST_CASES.by_path[test_case_name], ConfigSchema.UNIFIED)
69@pytest.mark.parametrize("test_case_name", sorted(TEST_CASES.by_type["good"]))
70def test_storage_configs_with_extra_param(test_case_name: str) -> None:
71 """Checks that the storage config fails to validate if extra params are present in
72 certain places.
73 """
74 check_test_case_config_with_extra_param(
75 TEST_CASES.by_type["good"][test_case_name],
76 ConfigSchema.STORAGE,
77 )
78 check_test_case_config_with_extra_param(
79 TEST_CASES.by_type["good"][test_case_name],
80 ConfigSchema.UNIFIED,
81 )
84if __name__ == "__main__":
85 pytest.main(
86 [__file__, "-n0"],
87 )