diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 1db445a..e46c79e 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,7 +1,7 @@ on: push: branch: - - master + - main name: 'Trigger: Push action' diff --git a/.github/workflows/validate_expected_kcidb_submission.yaml b/.github/workflows/validate_expected_kcidb_submission.yaml new file mode 100644 index 0000000..9048c07 --- /dev/null +++ b/.github/workflows/validate_expected_kcidb_submission.yaml @@ -0,0 +1,25 @@ +on: + push: + branch: + - main + +name: 'Validate: Expected KCIDB Submission' + +jobs: + validate: + name: Validate KCIDB Submission + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: setup python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r submission/examples/validate/requirements.txt + - name: Validate expected submission + run: | + cd submission/examples + python3 validate/validate.py diff --git a/submission/examples/5_3_schema.json b/submission/examples/5_3_schema.json new file mode 100644 index 0000000..de3d5b4 --- /dev/null +++ b/submission/examples/5_3_schema.json @@ -0,0 +1,1142 @@ +{ + "title": "kcidb", + "description": + "Kernel CI report data. To be submitted to/queried from the " + "common report database.\n" + "\n" + "Objects in the data are identified and linked together using " + "\"id\" and \"*_id\" string properties. Each value of these " + "properties must start with a non-empty string identifying the " + "CI system which submitted the object, followed by a colon ':' " + "character. The rest of the string is generated by the origin " + "CI system, and must identify that object uniquely among all " + "objects of the same type, coming from that CI system.\n" + "\n" + "Any of the immediate properties (except \"version\") can be " + "missing or be an empty list with each submission/query, but " + "only complete data stored in the database should be considered " + "valid.\n" + "\n" + "E.g. a test run referring to a non-existent build is allowed " + "into/from the database, but would only appear in reports once " + "both the build and its source code checkout are present.\n" + "\n" + "No special meaning apart from \"data is missing\" is attached to " + "any immediate or deeper properties being omitted, when they're " + "not required, and no default values should be assumed for them. " + "At the same time, no properties can be null.\n" + "\n" + "Any fields with names starting with an underscore \"_\" are " + "considered metadata, are ignored on submission, and are not " + "loaded into, or retrieved from the database by default.\n" + "\n" + "Extra free-form data can be stored under \"misc\" fields " + "associated with various objects throughout the schema, if " + "necessary. That data could later be used as the basis for " + "defining new properties to house it.", + "type": "object", + + "$defs": { + # A named remote resource + "resource": { + "title": "resource", + "description": "A named remote resource", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": + "Resource name. Must be usable as a local file " + "name for the downloaded resource. Cannot be " + "empty. Should not include directories.", + "pattern": "^[^/\\0]+$", + }, + "url": { + "type": "string", + "format": "uri", + "description": + "Resource URL. Must point to the resource " + "file directly, so it could be downloaded " + "automatically.", + }, + }, + "additionalProperties": False, + "required": ["name", "url"], + "examples": [ + { + "name": "console.log", + "url": + "https://artifacts.cki-project.org/pipelines/" + "223563/logs/aarch64_host_1_console.log" + }, + { + "name": "kernel.tar.gz", + "url": + "https://artifacts.cki-project.org/pipelines/" + "224569/kernel-stable-aarch64-" + "a2fc8ee6676067f27d2f5c6e4d512adff3d9938c.tar.gz" + } + ] + }, + + # A list of named remote resources + "resource_list": { + "type": "array", + "description": "A list of named remote resources", + "items": {"$ref": "#/$defs/resource"}, + }, + + # Status of a test or build run + "status": { + "title": "status", + "type": "string", + "description": + "The test status string, one of the following:\n" + "\n" + "\"FAIL\" - the test completed and reported the tested " + "code as faulty.\n" + "\n" + "\"ERROR\" - the test didn't complete due to a failure " + "in its code, and the status of the tested code is " + "unknown.\n" + "\n" + "\"MISS\" - the test didn't run due to a failure in the " + "test harness, and the status of both the test and the " + "tested code is unknown.\n" + "\n" + "\"PASS\" - the test completed and reported the tested " + "code as correct.\n" + "\n" + "\"DONE\" - the test completed and had not reported the " + "status of the tested code, but, for example, produced a " + "performance measurement result.\n" + "\n" + "\"SKIP\" - the test did not run or complete, because it " + "was not applicable, and the status of both the test and " + "the tested code is unknown.\n" + "\n" + "The status names above are listed in priority order " + "(highest to lowest), which can be used to produce a " + "summary status for a collection of test runs.\n" + "\n" + "For example, the summary status for all testing done on " + "a build would be the highest-priority status across all " + "its tests.", + "enum": ["FAIL", "ERROR", "MISS", "PASS", "DONE", "SKIP"], + }, + + "path": { + "type": "string", + "description": + "Dot-separated path through a tree. " + "The empty string signifies " + "the root of the tree.", + "pattern": path_re.pattern, + "examples": [ + "", + "ltp", + "ltp.sem01", + ], + }, + + # A source code checkout being tested + "checkout": { + "title": "checkout", + "description": + "The source code checkout being tested.\n" + "\n" + "Represents the way the tested source code was obtained " + "and its original location. E.g. checking out a" + " particular commit from a git " + "repo, and applying a set of patches on top.\n" + "\n" + "There could be multiple checkouts of the same source " + "code location, and multiple locations for the same " + "code revision. Such as multiple checkouts " + "of the same commit appearing in multiple " + "Git repos, or " + "multiple downloads and applications " + "of the same patchset sent to " + "multiple maillists.\n", + "type": "object", + "properties": { + "_timestamp": { + "type": "string", + "format": "date-time", + "description": + "The last time the checkout was updated in the " + "database.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "id": { + "type": "string", + "description": + "Source code checkout ID\n" + "\n" + "Must start with a non-empty string identifying" + " the CI system which submitted the checkout, " + "followed by a colon ':' character. The rest of " + "the string is generated by the " + "origin CI system, and must identify the checkout " + "uniquely among all checkouts, coming from " + "that CI system.\n", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "origin": { + "type": "string", + "description": + "The name of the CI system which submitted " + "the checkout", + "pattern": f"^{PreviousVersion.origin_pattern}$", + }, + "tree_name": { + "type": "string", + "description": + "The widely-recognized name of the sub-tree " + "(fork) of the main code tree where the checked " + "out base source code came from.", + "pattern": "^[^\\0]*$", + "examples": [ + "net-next", + "rdma", + "mainline", + ], + }, + "git_repository_url": { + "type": "string", + "format": "uri", + "description": + "The URL of the Git repository which contains the " + "checked out base source code. The shortest " + "possible https:// URL.", + "pattern": + "^" + + PreviousVersion.git_repository_url_re.pattern + + "$", + "examples": [ + "https://git.kernel.org/pub/scm/linux/kernel/git/" + "torvalds/linux.git", + ], # noqa: E122, silly flake8 + }, + "git_commit_hash": { + "type": "string", + "description": + "The full commit hash of the checked out base " + "source code", + "pattern": + f"^{PreviousVersion.git_commit_hash_pattern}$", + }, + "git_commit_name": { + "type": "string", + "description": + "A human-readable name of the commit containing " + "the checked out base source code, as would be " + "output by \"git describe\", at the checkout " + "time.", + "pattern": "^[^\\0]*$", + }, + "git_commit_tags": { + "type": "array", + "description": + "The list of (annotated) tags, found in the " + "checked-out repository, pointing directly " + "at the commit being checked out. I.e. as " + "output by \"git tag --points-at \".", + "items": { + "type": "string", + "description": + "A git tag pointing at the checked-out " + "commit", + "pattern": "^[^\\0]*$", + }, + }, + "git_commit_message": { + "type": "string", + "description": + "The complete message of the commit being " + "checked-out, both the subject and the body. " + "I.e. as output by \"git show -s --format=%B\".", + "pattern": "^[^\\0]*$", + }, + "git_repository_branch": { + "type": "string", + "description": + "The Git repository branch from which the commit " + "with the base source code was checked out.", + "pattern": "^[^\\0]*$", + }, + "git_repository_branch_tip": { + "type": "boolean", + "description": + "True if at the moment of checkout (specified in " + "\"start_time\") the checked out commit was at " + "the tip of the specified branch in the " + "specified repository. False if it was further " + "back in history.\n" + "\n" + "This information is used to reconstruct the " + "approximate history of the branch changes for " + "display and analyzis, in lieu of actual commit " + "graph walking." + }, + "patchset_files": { + "description": + "List of patch files representing the patchset " + "applied to the checked out base source code, " + "in order of application. Each linked file must " + "be in a format accepted by \"git apply\".", + "$ref": "#/$defs/resource_list" + }, + "patchset_hash": { + "type": "string", + "description": + "The patchset hash.\n" + "\n" + "A sha256 hash over newline-terminated sha256 " + "hashes of each patch from the patchset, in " + "order. E.g. generated with this shell command: " + "\"sha256sum *.patch | cut -c-64 | sha256sum | " + "cut -c-64\".\n" + "\n" + "An empty string, if no patches were applied to " + "the checked out base source code.\n", + "pattern": f"^$|^{PreviousVersion.sha256_pattern}$", + "examples": [ + "", + "903638c087335b10293663c682b9aa0076f9f7be478a8" + "e7828bc22e12d301b42" + ], + }, + "message_id": { + "type": "string", + "format": "email", + "description": + "The value of the Message-ID header of the e-mail " + "message introducing the checked-out source code, " + "if any. E.g. a message with the applied " + "patchset, or a release announcement sent to a " + "maillist.", + }, + "comment": { + "type": "string", + "description": + "A human-readable comment regarding the checkout. " + "E.g. the checked out release version, or the " + "subject of the message with the applied " + "patchset.", + "pattern": "^[^\\0]*$", + }, + "start_time": { + "type": "string", + "format": "date-time", + "description": + "The time the checkout was started.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "origin_builds_finish_time": { + "type": "string", + "format": "date-time", + "description": + "The time the origin of the checkout finished " + "all the builds it planned for it.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "origin_tests_finish_time": { + "type": "string", + "format": "date-time", + "description": + "The time the origin of the checkout finished " + "all the tests it planned for it.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "log_url": { + "type": "string", + "format": "uri", + "description": + "The URL of a plain-text log file of the " + "checkout attempt. " + "E.g. 'git am' output.", + }, + "log_excerpt": { + "type": "string", + "maxLength": 16384, + "description": + "A part of the log file of the checkout attempt " + "most relevant to its outcome.", + "pattern": "^[^\\0]*$", + "examples": [ + "error: patch failed: " + "arch/arm64/boot/dts/qcom/sc7180.dtsi:510\n" + "error: arch/arm64/boot/dts/qcom/sc7180.dtsi: " + "patch does not apply\n", + ], + }, + "valid": { + "type": "boolean", + "description": + "True if the checkout succeeded, i.e. if the " + "source code parts could be combined. False if " + "not, e.g. if the patches failed to apply." + }, + "misc": { + "type": "object", + "description": + "Miscellaneous extra data about the checkout", + }, + }, + "additionalProperties": False, + "required": [ + "id", + "origin", + ], + }, + + # A build of a source code checkout + "build": { + "title": "build", + "description": "A build of a source code checkout", + "type": "object", + "properties": { + "_timestamp": { + "type": "string", + "format": "date-time", + "description": + "The last time the build was updated in the " + "database.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "checkout_id": { + "type": "string", + "description": + "ID of the built source code checkout. The " + "checkout must be valid for the build to be " + "considered valid.", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "id": { + "type": "string", + "description": + "Build ID\n" + "\n" + "Must start with a non-empty string identifying " + "the CI system which submitted the build, " + "followed by a colon ':' character. The " + "rest of the string is generated by the origin " + "CI system, and must identify the build uniquely " + "among all builds, coming from that CI system.\n", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "origin": { + "type": "string", + "description": + "The name of the CI system which submitted the " + "build", + "pattern": f"^{PreviousVersion.origin_pattern}$", + }, + "comment": { + "type": "string", + "description": + "A human-readable comment regarding the build", + "pattern": "^[^\\0]*$", + }, + "start_time": { + "type": "string", + "format": "date-time", + "description": + "The time the build was started", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "duration": { + "type": "number", + "description": + "The number of seconds it took to complete the " + "build", + }, + "architecture": { + "type": "string", + "description": + "Target architecture of the build", + "pattern": "^[a-z0-9_]*$" + }, + "command": { + "type": "string", + "description": + "Full shell command line used to make the build, " + "including environment variables", + "pattern": "^[^\\0]*$", + }, + "compiler": { + "type": "string", + "description": + "Name and version of the compiler used to " + "make the build", + "pattern": "^[^\\0]*$", + }, + "input_files": { + "description": + "A list of build input files. E.g. configuration.", + "$ref": "#/$defs/resource_list" + }, + "output_files": { + "description": + "A list of build output files: images, packages, " + "etc.", + "$ref": "#/$defs/resource_list" + }, + "config_name": { + "type": "string", + "description": + "A name describing the build configuration " + "options.", + "pattern": "^[^\\0]*$", + }, + "config_url": { + "type": "string", + "format": "uri", + "description": + "The URL of the build configuration file.", + }, + "log_url": { + "type": "string", + "format": "uri", + "description": + "The URL of the plain-text build log file.", + }, + "log_excerpt": { + "type": "string", + "maxLength": 16384, + "description": + "A part of the log file of the build most " + "relevant to its " + "outcome.", + "pattern": "^[^\\0]*$", + "examples": [ + "In file included from " + "./arch/arm64/include/asm/processor.h:35:\n" + "./arch/arm64/include/asm/pointer_auth.h:62:3: " + "error: invalid input constraint 'rZ' in asm\n" + " __ptrauth_key_install(APIA, " + "keys->apia);\n ^\n" + "./arch/arm64/include/asm/pointer_auth.h:55:2: " + "note: expanded from macro " + "'__ptrauth_key_install'\n" + " write_sysreg_s(__pki_v.lo, " + "SYS_ ## k ## KEYLO_EL1); \\\n" + " ^\n./arch/arm64/include/asm/sysreg.h:" + "829:37:" + " note: expanded from macro 'write_sysreg_s'\n" + " asm volatile(__msr_s(r, \"%x0\") : : " + "\"rZ\" (__val)); \\\n" + " ^\n" + ], + }, + "status": { + "description": "Build status", + "$ref": "#/$defs/status", + }, + "misc": { + "type": "object", + "description": + "Miscellaneous extra data about the build", + }, + }, + "additionalProperties": False, + "required": ["checkout_id", "id", "origin"], + }, + + # A test run on a build + "test": { + "title": "test", + "description": + "A test run against a build.\n" + "\n" + "Could represent a result of execution of a test " + "suite program, a result of one of the tests done by " + "the test suite program, as well as a summary of a " + "collection of test suite results.\n" + "\n" + "Each test run should normally have a dot-separated " + "test \"path\" specified in the \"path\" property, " + "which could identify a specific test within a " + "test suite (e.g. \"LTPlite.sem01\"), a whole test " + "suite (e.g. \"LTPlite\"), or the summary " + "of all tests for a build " + "("" - the empty string).", + "type": "object", + "properties": { + "_timestamp": { + "type": "string", + "format": "date-time", + "description": + "The last time the test was updated in the " + "database.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "build_id": { + "type": "string", + "description": + "ID of the tested build. The build must be " + "valid for the test run to be considered valid.", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "id": { + "type": "string", + "description": + "ID of the test run\n" + "\n" + "Must start with a non-empty string identifying " + "the CI system which submitted the test run, " + "followed by a colon ':' character. " + "The rest of the string is generated by the " + "origin CI system, and must identify the test " + "run uniquely among all test runs, coming from " + "that CI system.\n", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "origin": { + "type": "string", + "description": + "The name of the CI system which submitted the" + " test run", + "pattern": f"^{PreviousVersion.origin_pattern}$", + }, + "environment": { + "type": "object", + "description": + "The environment the test ran in. " + "E.g. a host, a set of hosts, or a lab; " + "amount of memory/storage/CPUs, for each host; " + "process environment variables, etc.", + "properties": { + "compatible": { + "description": + "The values from the root-level " + "'compatible' property of the system's " + "device tree, if any, in the same order. " + "E.g. the contents of " + "/proc/device-tree/compatible with " + "each zero-terminated string as the " + "array's element.", + "type": "array", + "items": { + "type": "string", + "description": + "A single value from device tree " + "root-level 'compatible' property", + "pattern": "^[^ \\0]+(,[^ \\0]+)*$" + }, + "examples": [ + [ + "zyxel,nsa325", + "marvell,kirkwood-88f6282", + "marvell,kirkwood" + ], + ["yna,cu1830-neo", "ingenic,x1830"], + ], + }, + "comment": { + "type": "string", + "description": + "A human-readable comment regarding the " + "environment.", + "pattern": "^[^\\0]*$", + }, + "misc": { + "type": "object", + "description": + "Miscellaneous extra data about the " + "environment", + }, + }, + "additionalProperties": False, + }, + "path": { + "description": + "Dot-separated path to the node in the test " + "classification tree the executed test belongs to." + " E.g. \"ltp.sem01\". The empty string signifies" + " the root of the tree, i.e. all tests for " + "the build, executed by the origin CI system.", + "$ref": "#/$defs/path", + "examples": [ + "", + "ltp", + "ltp.sem01", + ], + }, + "comment": { + "type": "string", + "description": + "A human-readable comment regarding the test run", + "pattern": "^[^\\0]*$", + }, + "log_url": { + "type": "string", + "format": "uri", + "description": + "The URL of the plain-text test output or log " + "file. If the test produced multiple " + "outputs/files, this should point to the one " + "containing the highest-level overview of the " + "test's operation. The rest should go into " + "\"output_files\"." + }, + "log_excerpt": { + "type": "string", + "maxLength": 16384, + "description": + "A part of the test output/log file " + "(which could be) referenced by \"log_url\", " + "most relevant to the test outcome.", + "pattern": "^[^\\0]*$", + "examples": [ + "netns_breakns_ns_exec_ipv4_ioctl FAIL 2\n", + "kernel BUG at net/core/dev.c:2648!\n", + ], + }, + "status": { + "description": "Test status", + "$ref": "#/$defs/status", + }, + "number": { + "description": + "The numerical output produced by the test.\n" + "\n" + "The meaning of the output is determined by the " + "particular test. Should only be considered when " + "the test has actually executed. That is, with a " + "\"FAIL\", \"ERROR\", \"PASS\", or \"DONE\" " + "status only. Normally \"DONE\" should be used, " + "when it's the main and not an auxiliary output.", + "type": "object", + "properties": { + "value": { + "description": + "The floating-point output value.\n" + "\n" + "The receiving system should dedicate at " + "least 64 bits for its storage.", + "type": "number", + }, + "unit": { + "description": + "The (compound) unit symbol(s) the value " + "is measured in.\n" + "\n" + "If includes unit prefixes, " + "they should be used consistently to " + "allow comparison of the values.\n" + "\n" + "Alternatively, the prefixes can be " + "omitted from the unit, and the " + "\"prefix\" can be specified. Based on " + "that, and on the value itself, " + "an appropriate prefix will be added to " + "the unit string and the value will be " + "scaled, when displaying.\n" + "\n" + "If not specified, the value is " + "considered dimensionless.", + "type": "string", + "pattern": "^[^\\0]*$", + "examples": [ + "s", + "GB", + "MiB", + "B/s", + "IOPS", + ], + }, + "prefix": { + "description": + "The type of prefix to add to the " + "unit, after the value is scaled. " + "If unit is not specified, the prefix " + "alone is used in its place.\n" + "\n" + "If \"binary\", the value display " + "scaling should be 1024-based, and the " + "added prefix - binary. " + "E.g. Ki, Mi, Gi, etc.\n" + "\n" + "If \"metric\" the value display scaling " + "should be 10-based, and the added " + "prefix - metric. E.g. K, M, G, etc.\n" + "\n" + "No scaling or prefix is applied, " + "if not specified.", + "type": "string", + "enum": ["metric", "binary"], + }, + }, + "required": ["value"], + "additionalProperties": False, + "examples": [ + { + "value": 42, + # Display: 42 + }, + { + "value": 3.14159, + # Display: 3.14159 + }, + { + "value": 720, + "unit": "KB", + # Display: 720 KB + }, + { + "value": 145000, + "prefix": "metric" + # Display: 145 K + }, + { + "value": 1.6e-7, + "unit": "s", + "prefix": "metric", + # Display: 160 ns + }, + { + "value": 5.12e5, + "unit": "B", + "prefix": "binary", + # Display: 500 KiB + }, + ], + }, + "start_time": { + "type": "string", + "format": "date-time", + "description": + "The time the test run was started", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "duration": { + "type": "number", + "description": + "The number of seconds it took to run the test", + }, + "input_files": { + "description": + "A list of inputs files: rootfs, initram, etc. ", + "$ref": "#/$defs/resource_list" + }, + "output_files": { + "description": + "A list of test outputs: logs, dumps, etc. " + "Except the file referenced by \"log_url\".", + "$ref": "#/$defs/resource_list" + }, + "misc": { + "type": "object", + "description": + "Miscellaneous extra data about the test run", + }, + }, + "additionalProperties": False, + "required": ["build_id", "id", "origin"], + }, + + # An issue + "issue": { + "title": "issue", + "description": + "An issue found in reports.", + "type": "object", + "properties": { + "_timestamp": { + "type": "string", + "format": "date-time", + "description": + "The last time the issue was updated in the " + "database.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "id": { + "type": "string", + "description": + "Issue ID\n" + "\n" + "Must start with a non-empty string identifying" + " the CI system which submitted the checkout, " + "followed by a colon ':' character. The rest of " + "the string is generated by the " + "origin CI system, and must identify the issue" + " uniquely among all issues, coming from " + "that CI system.\n", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "version": { + "type": "integer", + "description": + "The modification version number of the issue. " + "Only the highest-numbered version is used for " + "triaging.", + "minimum": 0, + }, + "origin": { + "type": "string", + "description": + "The name of the CI system which submitted " + "the issue", + "pattern": f"^{PreviousVersion.origin_pattern}$", + }, + "categories": { + "description": + "An array of dot-separated paths pointing to " + "nodes in the categorization tree the issue " + "belongs to. The agreed-upon categories are " + "defined outside the schema.", + "type": "array", + "items": {"$ref": "#/$defs/path"}, + "examples": [ + ["build.error", "compiler.bug"], + ["runtime.oops", "runtime.driver.networking"], + ], + }, + "report_url": { + "type": "string", + "format": "uri", + "description": + "The URL of a report describing the issue.", + "examples": [ + "https://bugzilla.kernel.org/show_bug.cgi?" + "id=207065" + ] + }, + "report_subject": { + "type": "string", + "description": + "The subject of the report describing the issue.", + "pattern": "^[^\\0]*$", + "examples": [ + "C-media USB audio device stops working from " + "5.2.0-rc3 onwards" + ] + }, + "culprit": { + "type": "object", + "description": + "Layers of the execution stack responsible " + "for the issue. If all are false, the issue is " + "considered invalid.", + "properties": { + "code": { + "type": "boolean", + "description": "The built/tested code." + }, + "tool": { + "type": "boolean", + "description": + "The tool - the static " + "analyzer, the build toolchain, " + "the test, etc." + }, + "harness": { + "type": "boolean", + "description": + "The harness - the system controlling " + "the execution of the build/test.", + }, + }, + "additionalProperties": False, + }, + "comment": { + "type": "string", + "description": + "A human-readable comment regarding the issue. " + "E.g. a brief description, or a report subject.", + "pattern": "^[^\\0]*$", + }, + "misc": { + "type": "object", + "description": + "Miscellaneous extra data about the issue", + }, + }, + "additionalProperties": False, + "required": [ + "id", + "version", + "origin", + ], + }, + + # An incident + "incident": { + "title": "incident", + "description": + "An incident - an issue occurence/absence.", + "type": "object", + "properties": { + "_timestamp": { + "type": "string", + "format": "date-time", + "description": + "The last time the incident was updated in the " + "database.", + "examples": [ + "2020-08-14T23:08:06.967000+00:00", + ], + }, + "id": { + "type": "string", + "description": + "Incident ID\n" + "\n" + "Must start with a non-empty string identifying" + " the CI system which submitted the incident, " + "followed by a colon ':' character. The rest of " + "the string is generated by the " + "origin CI system, and must identify the incident" + " uniquely among all incidents, coming from " + "that CI system.\n", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "origin": { + "type": "string", + "description": + "The name of the CI system which submitted " + "the incident", + "pattern": f"^{PreviousVersion.origin_pattern}$", + }, + "issue_id": { + "type": "string", + "description": + "The ID of the occurring/absent issue.", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "issue_version": { + "type": "integer", + "description": + "The modification version number of the " + "occurring/absent issue.", + "minimum": 0, + }, + "build_id": { + "type": "string", + "description": + "The ID of the build object exhibiting/missing " + "the issue.", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "test_id": { + "type": "string", + "description": + "The ID of the test object exhibiting/missing " + "the issue.", + "pattern": f"^{PreviousVersion.origin_id_pattern}$", + }, + "present": { + "type": "boolean", + "description": + "True if the issue occurred in the linked " + "objects. False if it was absent." + }, + "comment": { + "type": "string", + "description": + "A human-readable comment regarding the " + "incident.", + "pattern": "^[^\\0]*$", + }, + "misc": { + "type": "object", + "description": + "Miscellaneous extra data about the incident.", + }, + }, + "additionalProperties": False, + "required": [ + "id", + "origin", + "issue_id", + "issue_version", + ], + }, + }, + + "properties": { + "version": { + "type": "object", + "properties": { + "major": { + "type": "integer", + "const": major, + "description": + "Major number of the schema version.\n" + "\n" + "Increases represent backward-incompatible " + "changes. E.g. deleting or renaming a " + "property, changing a property type, " + "restricting values, making a property " + "required, or adding a new required " + "property.", + }, + "minor": { + "type": "integer", + "minimum": 0, + "maximum": minor, + "description": + "Minor number of the schema version.\n" + "\n" + "Increases represent backward-compatible " + "changes. E.g. relaxing value restrictions, " + "making a property optional, or adding a new " + "optional property.", + } + }, + "additionalProperties": False, + "required": [ + "major", + ], + }, + "checkouts": { + "description": "List of source code checkouts", + "type": "array", + "items": {"$ref": "#/$defs/checkout"}, + }, + "builds": { + "description": "List of builds", + "type": "array", + "items": {"$ref": "#/$defs/build"}, + }, + "tests": { + "description": "List of test runs", + "type": "array", + "items": {"$ref": "#/$defs/test"}, + }, + "issues": { + "description": "List of issues", + "type": "array", + "items": {"$ref": "#/$defs/issue"}, + }, + "incidents": { + "description": "List of incidents", + "type": "array", + "items": {"$ref": "#/$defs/incident"}, + }, + }, + "additionalProperties": False, + "required": [ + "version", + ], + } diff --git a/submission/examples/submission.yaml b/submission/examples/submission.yaml new file mode 100644 index 0000000..ba5f1a7 --- /dev/null +++ b/submission/examples/submission.yaml @@ -0,0 +1,122 @@ +version: + major: 5 + minor: 3 + +# TODO: builds should include timestamps of every step for the _timestamp field +# TODO: log_url should be hosted somewhere and permanently accessible +# TODO: figure out what to do with issues and incidents. are these even relevant to gkci? +# TODO: is this the correct use of "id" fields? +# TODO: is the git_repository_url accurate in the first checkout, since we aren't retrieving via git? +# TODO: patchset_hash is missing, not sure how to generate it + +# trying to use https://gkernelci.gentoo.org/#/builders/26/builds/76 as an example +checkouts: + - id: "gkci:linux-8ad6ee8c16640c433f2c8b12480c69aaf5154f66" + origin: "gkci" + tree_name: "mainline" + git_repository_url: "https://cdn.kernel.org/pub/linux/kernel/v6.x/incr/patch-6.16.8-9.xz" # validation script doesn't allow http (only https) but cdn.kernel.org might not support https + git_repository_branch: "6.16" + git_repository_branch_tip: false + patchset_files: + - name: 1000_linux-6.16.1.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1000_linux-6.16.1.patch?h=6.16" + - name: 1001_linux-6.16.2.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1001_linux-6.16.2.patch?h=6.16" + - name: 1002_linux-6.16.3.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1002_linux-6.16.3.patch?h=6.16" + - name: 1003_linux-6.16.4.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1003_linux-6.16.4.patch?h=6.16" + - name: 1004_linux-6.16.5.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1004_linux-6.16.5.patch?h=6.16" + - name: 1005_linux-6.16.6.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1005_linux-6.16.6.patch?h=6.16" + - name: 1006_linux-6.16.7.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1006_linux-6.16.7.patch?h=6.16" + - name: 1007_linux-6.16.8.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1007_linux-6.16.8.patch?h=6.16" + - name: 1008_linux-6.16.9.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1008_linux-6.16.9.patch?h=6.16" + - name: 1510_fs-enable-link-security-restrictions-by-default.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1510_fs-enable-link-security-restrictions-by-default.patch?h=6.16" + - name: 1700_sparc-address-warray-bound-warnings.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1700_sparc-address-warray-bound-warnings.patch?h=6.16" + - name: 1730_parisc-Disable-prctl.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/1730_parisc-Disable-prctl.patch?h=6.16" + - name: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch?h=6.16" + - name: 2901_permit-menuconfig-sorting.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/2901_permit-menuconfig-sorting.patch?h=6.16" + - name: 2920_sign-file-patch-for-libressl.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/2920_sign-file-patch-for-libressl.patch?h=6.16" + - name: 2990_libbpf-v2-workaround-Wmaybe-uninitialized-false-pos.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/2990_libbpf-v2-workaround-Wmaybe-uninitialized-false-pos.patch?h=6.16" + - name: 2991_libbpf_add_WERROR_option.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/2991_libbpf_add_WERROR_option.patch?h=6.16" + - name: 3000_Support-printing-firmware-info.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/3000_Support-printing-firmware-info.patch?h=6.16" + - name: 4567_distro-Gentoo-Kconfig.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/4567_distro-Gentoo-Kconfig.patch?h=6.16" + - name: 5010_enable-cpu-optimizations-universal.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/5010_enable-cpu-optimizations-universal.patch?h=6.16" + - name: 5020_BMQ-and-PDS-io-scheduler-v6.16-r0.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/5020_BMQ-and-PDS-io-scheduler-v6.16-r0.patch?h=6.16" + - name: 5021_BMQ-and-PDS-gentoo-defaults.patch + url: "https://gitweb.gentoo.org/proj/linux-patches.git/plain/5021_BMQ-and-PDS-gentoo-defaults.patch?h=6.16" + git_commit_hash: "a3c256e1f2e1b60c0d02a2cf19e76b4dcf0c5df3" + valid: true + - id: "gkci:linux-patches-fb4386cb8d3a0e3944fcbd135b1a7c53cd28d3ad" + origin: "gkci" + git_repository_url: "https://anongit.gentoo.org/git/proj/linux-patches.git" + git_repository_branch: "6.16" + git_repository_branch_tip: true + git_commit_hash: fb4386cb8d3a0e3944fcbd135b1a7c53cd28d3ad + git_commit_message: "Linux patch 6.16.9\n\nSigned-off-by: Arisu Tachibana " + - id: "gkci:Ghelper-main" + origin: "gkci" + git_repository_url: "https://github.com/GKernelCI/Ghelper.git" + git_repository_branch: "main" + git_repository_branch_tip: true + git_commit_hash: 8ad6ee8c16640c433f2c8b12480c69aaf5154f66 + git_commit_message: "Add fix for experimental patches\n\nSigned-off-by: Arisu Tachibana " + +builds: + - id: "gkci:linux-8ad6ee8c16640c433f2c8b12480c69aaf5154f66" + origin: "gkci" + checkout_id: "gkci:linux-8ad6ee8c16640c433f2c8b12480c69aaf5154f66" + architecture: "x86_64" + start_time: "2025-09-25T12:12:55+00:00" + status: "PASS" + duration: 519.154513 + command: "/bin/bash build-kernel.sh amd64 6.16:amd64:gcc 76" + compiler: "gcc" + log_url: https://gkernelci.gentoo.org/api/v2/logs/29973/raw_inline + +tests: + - id: "gkci:builders-26-build-76" + origin: "gkci" + build_id: "gkci:builders-26-build-76" + start_time: "2025-09-25T12:12:55+00:00" + status: "PASS" + log_excerpt: "{'gentoo': {2053: {'devicename': 'qemu-x86_64', 'health': 'Complete', 'state': 'Finished'}}}" + +issues: + - id: "ci1:issue-1" + version: 1 + origin: "ci1" + categories: + - "runtime.oops" + report_url: "https://bugzilla.kernel.org/show_bug.cgi?id=207065" + report_subject: "Kernel crash in net/core/dev.c" + culprit: + code: true + tool: false + harness: false + +incidents: + - id: "ci1:incident-1" + origin: "ci1" + issue_id: "ci1:issue-1" + issue_version: 1 + build_id: "ci1:build-123" + test_id: "ci1:test-123" + present: true diff --git a/submission/examples/validate/requirements.txt b/submission/examples/validate/requirements.txt new file mode 100644 index 0000000..e4fc09a --- /dev/null +++ b/submission/examples/validate/requirements.txt @@ -0,0 +1,3 @@ +pyyaml +git+https://github.com/kernelci/kcidb-io.git + diff --git a/submission/examples/validate/validate.py b/submission/examples/validate/validate.py new file mode 100644 index 0000000..fd4c67f --- /dev/null +++ b/submission/examples/validate/validate.py @@ -0,0 +1,7 @@ +import yaml +import kcidb_io + +with open("submission.yaml", "r") as f: + submission = yaml.safe_load(f) + +kcidb_io.schema.V5_3().validate(submission)