1################################################################ 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19"""Error kinds of the extended save modes. Those modes write extension content on purpose, so their output is not expected to be 20schema valid; what must not happen is that it gets worse. A baseline per (mode, schema) lists the documents it covers and each 21kind of error (the message with the expected-alternatives tail removed) with its count and the packages that have it. A run is 22worse when a kind is new, a count or a package count went up, or a baseline document is no longer covered. Only documents the 23tests build or create are used: the ones an install ships differ from install to install.""" 24import json 25import re 26 27from aootest.checkers import compare, report 28from aootest.paths import DATA 29 30BASELINE = DATA / "baseline" 31# (save mode, schema): 12, 13 and 14 are the plain schemas, 12x, 13x and 14x the same with foreign content removed first 32PAIRS = (("ext", "12"), ("ext", "12x"), ("x13", "13"), ("x13", "13x"), ("x14", "14"), ("x14", "14x")) 33STABLE_PREFIXES = ("built/", "generated/") 34 35 36def stable(sources): 37 """The sources whose files do not depend on the install.""" 38 return [s for s in sources if s.id.startswith(STABLE_PREFIXES)] 39 40 41def kinds_of(val, version, packages): 42 """The kinds of the errors that validate.check() found against `version` in the named packages. A jing failure that names 43 the work directory is grouped under one key, whatever the directory was.""" 44 entries = [e for e in val["errors"][version] if e[0].split("/", 1)[0] in packages] 45 res = {} 46 for key, v in report.kinds_of({"errors": {version: entries}}, version).items(): 47 key = re.sub(r"/[^ ]*/w-validate", "<workdir>", key) 48 old = res.setdefault(key, {"errors": 0, "packages": []}) 49 old["errors"] += v["errors"] 50 old["packages"] = sorted(set(old["packages"]) | set(v["packages"])) 51 return res 52 53 54def path(mode, version): 55 return BASELINE / ("kinds-%s-%s.json" % (mode, version)) 56 57 58def load(mode, version): 59 p = path(mode, version) 60 return json.loads(p.read_text(encoding="utf-8")) if p.exists() else None 61 62 63def write(mode, version, documents, kinds): 64 BASELINE.mkdir(exist_ok=True) 65 path(mode, version).write_text(json.dumps({"documents": sorted(documents), "kinds": kinds}, indent=1, sort_keys=True) + "\n", encoding="utf-8") 66 67 68def judge(baseline, documents, kinds): 69 """(lines, bad): how `kinds` of the run differ from the baseline, and whether it is worse.""" 70 missing = sorted(set(baseline["documents"]) - set(documents)) 71 lines, bad = compare.compare(baseline["kinds"], kinds) 72 return ["NOT COVERED " + d for d in missing] + lines, bool(missing) or bad 73