xref: /linux/tools/unittests/test_kdoc_test_schema.py (revision 5181afcdf99527dd92a88f80fc4d0d8013e1b510)
1*8b69f522SMauro Carvalho Chehab#!/usr/bin/env python3
2*8b69f522SMauro Carvalho Chehab# SPDX-License-Identifier: GPL-2.0
3*8b69f522SMauro Carvalho Chehab"""
4*8b69f522SMauro Carvalho ChehabUnit‑test driver for kernel‑doc YAML tests.
5*8b69f522SMauro Carvalho Chehab
6*8b69f522SMauro Carvalho ChehabTwo kinds of tests are defined:
7*8b69f522SMauro Carvalho Chehab
8*8b69f522SMauro Carvalho Chehab* **Schema‑validation tests** – if ``jsonschema`` is available, the
9*8b69f522SMauro Carvalho Chehab  YAML files in this directory are validated against the JSON‑Schema
10*8b69f522SMauro Carvalho Chehab  described in ``kdoc-test-schema.yaml``.  When the library is not
11*8b69f522SMauro Carvalho Chehab  present, a warning is emitted and the validation step is simply
12*8b69f522SMauro Carvalho Chehab  skipped – the dynamic kernel‑doc tests still run.
13*8b69f522SMauro Carvalho Chehab
14*8b69f522SMauro Carvalho Chehab* **Kernel‑doc tests** – dynamically generate one test method per
15*8b69f522SMauro Carvalho Chehab  scenario in ``kdoc-test.yaml``.  Each method simply forwards
16*8b69f522SMauro Carvalho Chehab  the data to ``self.run_test`` – you only need to implement that
17*8b69f522SMauro Carvalho Chehab  helper in your own code.
18*8b69f522SMauro Carvalho Chehab
19*8b69f522SMauro Carvalho ChehabFile names are kept as module‑level constants so that the
20*8b69f522SMauro Carvalho Chehabimplementation stays completely independent of ``pathlib``.
21*8b69f522SMauro Carvalho Chehab"""
22*8b69f522SMauro Carvalho Chehab
23*8b69f522SMauro Carvalho Chehabimport os
24*8b69f522SMauro Carvalho Chehabimport sys
25*8b69f522SMauro Carvalho Chehabimport warnings
26*8b69f522SMauro Carvalho Chehabimport yaml
27*8b69f522SMauro Carvalho Chehabimport unittest
28*8b69f522SMauro Carvalho Chehabfrom typing import Any, Dict, List
29*8b69f522SMauro Carvalho Chehab
30*8b69f522SMauro Carvalho ChehabSRC_DIR = os.path.dirname(os.path.realpath(__file__))
31*8b69f522SMauro Carvalho Chehabsys.path.insert(0, os.path.join(SRC_DIR, "../lib/python"))
32*8b69f522SMauro Carvalho Chehab
33*8b69f522SMauro Carvalho Chehabfrom unittest_helper import run_unittest
34*8b69f522SMauro Carvalho Chehab
35*8b69f522SMauro Carvalho Chehab
36*8b69f522SMauro Carvalho Chehab#
37*8b69f522SMauro Carvalho Chehab# Files to read
38*8b69f522SMauro Carvalho Chehab#
39*8b69f522SMauro Carvalho ChehabBASE = os.path.realpath(os.path.dirname(__file__))
40*8b69f522SMauro Carvalho Chehab
41*8b69f522SMauro Carvalho ChehabSCHEMA_FILE = os.path.join(BASE, "kdoc-test-schema.yaml")
42*8b69f522SMauro Carvalho ChehabTEST_FILE = os.path.join(BASE, "kdoc-test.yaml")
43*8b69f522SMauro Carvalho Chehab
44*8b69f522SMauro Carvalho Chehab#
45*8b69f522SMauro Carvalho Chehab# Schema‑validation test
46*8b69f522SMauro Carvalho Chehab#
47*8b69f522SMauro Carvalho Chehabclass TestYAMLSchemaValidation(unittest.TestCase):
48*8b69f522SMauro Carvalho Chehab    """
49*8b69f522SMauro Carvalho Chehab    Checks if TEST_FILE matches SCHEMA_FILE.
50*8b69f522SMauro Carvalho Chehab    """
51*8b69f522SMauro Carvalho Chehab
52*8b69f522SMauro Carvalho Chehab    @classmethod
53*8b69f522SMauro Carvalho Chehab    def setUpClass(cls):
54*8b69f522SMauro Carvalho Chehab        """
55*8b69f522SMauro Carvalho Chehab        Import jsonschema if available.
56*8b69f522SMauro Carvalho Chehab        """
57*8b69f522SMauro Carvalho Chehab
58*8b69f522SMauro Carvalho Chehab        try:
59*8b69f522SMauro Carvalho Chehab            from jsonschema import Draft7Validator
60*8b69f522SMauro Carvalho Chehab        except ImportError:
61*8b69f522SMauro Carvalho Chehab            print("Warning: jsonschema package not available. Skipping schema validation")
62*8b69f522SMauro Carvalho Chehab            cls.validator = None
63*8b69f522SMauro Carvalho Chehab            return
64*8b69f522SMauro Carvalho Chehab
65*8b69f522SMauro Carvalho Chehab        with open(SCHEMA_FILE, encoding="utf-8") as fp:
66*8b69f522SMauro Carvalho Chehab            cls.schema = yaml.safe_load(fp)
67*8b69f522SMauro Carvalho Chehab
68*8b69f522SMauro Carvalho Chehab        cls.validator = Draft7Validator(cls.schema)
69*8b69f522SMauro Carvalho Chehab
70*8b69f522SMauro Carvalho Chehab    def test_kdoc_test_yaml_followsschema(self):
71*8b69f522SMauro Carvalho Chehab        """
72*8b69f522SMauro Carvalho Chehab        Run jsonschema validation if the validator is available.
73*8b69f522SMauro Carvalho Chehab        If not, emit a warning and return without failing.
74*8b69f522SMauro Carvalho Chehab        """
75*8b69f522SMauro Carvalho Chehab        if self.validator is None:
76*8b69f522SMauro Carvalho Chehab            return
77*8b69f522SMauro Carvalho Chehab
78*8b69f522SMauro Carvalho Chehab        with open(TEST_FILE, encoding="utf-8") as fp:
79*8b69f522SMauro Carvalho Chehab            data = yaml.safe_load(fp)
80*8b69f522SMauro Carvalho Chehab
81*8b69f522SMauro Carvalho Chehab        errors = self.validator.iter_errors(data)
82*8b69f522SMauro Carvalho Chehab
83*8b69f522SMauro Carvalho Chehab        msgs = []
84*8b69f522SMauro Carvalho Chehab        for error in errors:
85*8b69f522SMauro Carvalho Chehab            msgs.append(error.message)
86*8b69f522SMauro Carvalho Chehab
87*8b69f522SMauro Carvalho Chehab        if msgs:
88*8b69f522SMauro Carvalho Chehab            self.fail("Schema validation failed:\n\t" + "\n\t".join(msgs))
89*8b69f522SMauro Carvalho Chehab
90*8b69f522SMauro Carvalho Chehab# --------------------------------------------------------------------
91*8b69f522SMauro Carvalho Chehab# Entry point
92*8b69f522SMauro Carvalho Chehab# --------------------------------------------------------------------
93*8b69f522SMauro Carvalho Chehabif __name__ == "__main__":
94*8b69f522SMauro Carvalho Chehab    run_unittest(__file__)
95