From 17c6d5eb478386ad183fa7e11b688217645d8f4f Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 5 Dec 2023 20:33:38 -0500 Subject: [PATCH] unittests: migrate from jsonschema to fastjsonschema The former has rust dependencies, which lead to max capping on Cygwin since there is no rust compiler there. But it turns out there are other disadvantages of jsonschema: - it involves installing 5 wheels, instead of just 1 - it is much slower To give some perspective to the latter issue, this is what it looks like when I test with jsonschema: ``` ===== 1 passed, 509 deselected in 3.07s ===== Total time: 3.341 seconds ``` And here's what it looks like when I test with fastjsonschema: ``` ===== 1 passed, 509 deselected, 1 warning in 0.28s ===== Total time: 0.550 seconds ``` I cannot think of a good reason to use the former. Although in order to work on old CI images, we'll support it as a fallback mechanism --- .github/workflows/cygwin.yml | 3 +-- .github/workflows/macos.yml | 2 +- .github/workflows/msys2.yml | 4 ++-- ci/ciimage/common.sh | 2 +- ci/run.ps1 | 2 +- unittests/internaltests.py | 27 +++++++++++++++++++-------- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index e62c745af..3b1b18516 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -76,8 +76,7 @@ jobs: - name: Run pip run: | export PATH=/usr/bin:/usr/local/bin:$(cygpath ${SYSTEMROOT})/system32 - # jsonschema is max capped because the new version depends on rust dependencies which are... hard to get on cygwin - python3 -m pip --disable-pip-version-check install gcovr 'jsonschema<4.18' pefile pytest pytest-subtests pytest-xdist coverage + python3 -m pip --disable-pip-version-check install gcovr fastjsonschema pefile pytest pytest-subtests pytest-xdist coverage shell: C:\cygwin\bin\bash.exe --noprofile --norc -o igncr -eo pipefail '{0}' - uses: actions/cache/save@v3 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 6d6b43af7..0e5002a40 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -33,7 +33,7 @@ jobs: python-version: '3.x' - run: | python -m pip install --upgrade pip - python -m pip install pytest pytest-xdist pytest-subtests jsonschema coverage + python -m pip install pytest pytest-xdist pytest-subtests fastjsonschema coverage - run: brew install pkg-config ninja llvm qt@5 - env: CPPFLAGS: "-I/usr/local/include" diff --git a/.github/workflows/msys2.yml b/.github/workflows/msys2.yml index 2bdcdd30e..043f5ce2a 100644 --- a/.github/workflows/msys2.yml +++ b/.github/workflows/msys2.yml @@ -80,7 +80,7 @@ jobs: mingw-w64-${{ matrix.MSYS2_ARCH }}-python-lxml mingw-w64-${{ matrix.MSYS2_ARCH }}-python-setuptools mingw-w64-${{ matrix.MSYS2_ARCH }}-python-pip - mingw-w64-${{ matrix.MSYS2_ARCH }}-python-jsonschema + mingw-w64-${{ matrix.MSYS2_ARCH }}-python-fastjsonschema mingw-w64-${{ matrix.MSYS2_ARCH }}-${{ matrix.TOOLCHAIN }} - name: Install dependencies @@ -100,7 +100,7 @@ jobs: - name: Run Tests run: | if [[ "${{ matrix.MSYS2_ARCH }}" == "x86_64" ]]; then - # There apparently is no clean way to add to the PATH in the + # There apparently is no clean way to add to the PATH in the # previous step? # See for instance https://github.com/msys2/setup-msys2/issues/171 export PATH=$PATH:$PWD/pypy3local diff --git a/ci/ciimage/common.sh b/ci/ciimage/common.sh index 67d59978f..016918240 100644 --- a/ci/ciimage/common.sh +++ b/ci/ciimage/common.sh @@ -15,7 +15,7 @@ base_python_pkgs=( pytest-xdist pytest-subtests coverage - jsonschema + fastjsonschema ) python_pkgs=( diff --git a/ci/run.ps1 b/ci/run.ps1 index badb4a74e..05bb6b69e 100644 --- a/ci/run.ps1 +++ b/ci/run.ps1 @@ -92,7 +92,7 @@ python --version # Needed for running unit tests in parallel. echo "" -python -m pip --disable-pip-version-check install --upgrade pefile pytest-xdist pytest-subtests jsonschema coverage +python -m pip --disable-pip-version-check install --upgrade pefile pytest-xdist pytest-subtests fastjsonschema coverage # Needed for running the Cython tests python -m pip --disable-pip-version-check install cython diff --git a/unittests/internaltests.py b/unittests/internaltests.py index 1c55b2976..66bf4586c 100644 --- a/unittests/internaltests.py +++ b/unittests/internaltests.py @@ -1012,19 +1012,30 @@ class InternalTests(unittest.TestCase): def test_validate_json(self) -> None: """Validate the json schema for the test cases.""" try: - from jsonschema import validate, ValidationError + from fastjsonschema import compile, JsonSchemaValueException as JsonSchemaFailure + fast = True except ImportError: - if is_ci(): - raise - raise unittest.SkipTest('Python jsonschema module not found.') - - schema = json.loads(Path('data/test.schema.json').read_text(encoding='utf-8')) + try: + from jsonschema import validate, ValidationError as JsonSchemaFailure + fast = False + except: + if is_ci(): + raise + raise unittest.SkipTest('neither Python fastjsonschema nor jsonschema module not found.') + + with open('data/test.schema.json', 'r', encoding='utf-8') as f: + data = json.loads(f.read()) + + if fast: + schema_validator = compile(data) + else: + schema_validator = lambda x: validate(x, schema=data) errors: T.List[T.Tuple[Path, Exception]] = [] for p in Path('test cases').glob('**/test.json'): try: - validate(json.loads(p.read_text(encoding='utf-8')), schema=schema) - except ValidationError as e: + schema_validator(json.loads(p.read_text(encoding='utf-8'))) + except JsonSchemaFailure as e: errors.append((p.resolve(), e)) for f, e in errors: