xref: /trunk/test/aoo-test/src/aootest/kinds.py (revision 2c760c133df3253aa7075d23c106a30339fca6f2)
185d6e4e5SJim Jagielski################################################################
285d6e4e5SJim Jagielski#
385d6e4e5SJim Jagielski#  Licensed to the Apache Software Foundation (ASF) under one
485d6e4e5SJim Jagielski#  or more contributor license agreements.  See the NOTICE file
585d6e4e5SJim Jagielski#  distributed with this work for additional information
685d6e4e5SJim Jagielski#  regarding copyright ownership.  The ASF licenses this file
785d6e4e5SJim Jagielski#  to you under the Apache License, Version 2.0 (the
885d6e4e5SJim Jagielski#  "License"); you may not use this file except in compliance
985d6e4e5SJim Jagielski#  with the License.  You may obtain a copy of the License at
1085d6e4e5SJim Jagielski#
1185d6e4e5SJim Jagielski#    http://www.apache.org/licenses/LICENSE-2.0
1285d6e4e5SJim Jagielski#
1385d6e4e5SJim Jagielski#  Unless required by applicable law or agreed to in writing,
1485d6e4e5SJim Jagielski#  software distributed under the License is distributed on an
1585d6e4e5SJim Jagielski#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1685d6e4e5SJim Jagielski#  KIND, either express or implied.  See the License for the
1785d6e4e5SJim Jagielski#  specific language governing permissions and limitations
1885d6e4e5SJim Jagielski#  under the License.
1985d6e4e5SJim Jagielski"""Error kinds of the extended save modes. Those modes write extension content on purpose, so their output is not expected to be
2085d6e4e5SJim Jagielskischema valid; what must not happen is that it gets worse. A baseline per (mode, schema) lists the documents it covers and each
2185d6e4e5SJim Jagielskikind of error (the message with the expected-alternatives tail removed) with its count and the packages that have it. A run is
2285d6e4e5SJim Jagielskiworse when a kind is new, a count or a package count went up, or a baseline document is no longer covered. Only documents the
2385d6e4e5SJim Jagielskitests build or create are used: the ones an install ships differ from install to install."""
2485d6e4e5SJim Jagielskiimport json
2585d6e4e5SJim Jagielskiimport re
2685d6e4e5SJim Jagielski
2785d6e4e5SJim Jagielskifrom aootest.checkers import compare, report
2885d6e4e5SJim Jagielskifrom aootest.paths import DATA
2985d6e4e5SJim Jagielski
3085d6e4e5SJim JagielskiBASELINE = DATA / "baseline"
31*2c760c13SJim Jagielski# (save mode, schema): 12, 13 and 14 are the plain schemas, 12x, 13x and 14x the same with foreign content removed first
32*2c760c13SJim JagielskiPAIRS = (("ext", "12"), ("ext", "12x"), ("x13", "13"), ("x13", "13x"), ("x14", "14"), ("x14", "14x"))
3385d6e4e5SJim JagielskiSTABLE_PREFIXES = ("built/", "generated/")
3485d6e4e5SJim Jagielski
3585d6e4e5SJim Jagielski
3685d6e4e5SJim Jagielskidef stable(sources):
3785d6e4e5SJim Jagielski    """The sources whose files do not depend on the install."""
3885d6e4e5SJim Jagielski    return [s for s in sources if s.id.startswith(STABLE_PREFIXES)]
3985d6e4e5SJim Jagielski
4085d6e4e5SJim Jagielski
4185d6e4e5SJim Jagielskidef kinds_of(val, version, packages):
4285d6e4e5SJim Jagielski    """The kinds of the errors that validate.check() found against `version` in the named packages. A jing failure that names
4385d6e4e5SJim Jagielski    the work directory is grouped under one key, whatever the directory was."""
4485d6e4e5SJim Jagielski    entries = [e for e in val["errors"][version] if e[0].split("/", 1)[0] in packages]
4585d6e4e5SJim Jagielski    res = {}
4685d6e4e5SJim Jagielski    for key, v in report.kinds_of({"errors": {version: entries}}, version).items():
4785d6e4e5SJim Jagielski        key = re.sub(r"/[^ ]*/w-validate", "<workdir>", key)
4885d6e4e5SJim Jagielski        old = res.setdefault(key, {"errors": 0, "packages": []})
4985d6e4e5SJim Jagielski        old["errors"] += v["errors"]
5085d6e4e5SJim Jagielski        old["packages"] = sorted(set(old["packages"]) | set(v["packages"]))
5185d6e4e5SJim Jagielski    return res
5285d6e4e5SJim Jagielski
5385d6e4e5SJim Jagielski
5485d6e4e5SJim Jagielskidef path(mode, version):
5585d6e4e5SJim Jagielski    return BASELINE / ("kinds-%s-%s.json" % (mode, version))
5685d6e4e5SJim Jagielski
5785d6e4e5SJim Jagielski
5885d6e4e5SJim Jagielskidef load(mode, version):
5985d6e4e5SJim Jagielski    p = path(mode, version)
6085d6e4e5SJim Jagielski    return json.loads(p.read_text(encoding="utf-8")) if p.exists() else None
6185d6e4e5SJim Jagielski
6285d6e4e5SJim Jagielski
6385d6e4e5SJim Jagielskidef write(mode, version, documents, kinds):
6485d6e4e5SJim Jagielski    BASELINE.mkdir(exist_ok=True)
6585d6e4e5SJim Jagielski    path(mode, version).write_text(json.dumps({"documents": sorted(documents), "kinds": kinds}, indent=1, sort_keys=True) + "\n", encoding="utf-8")
6685d6e4e5SJim Jagielski
6785d6e4e5SJim Jagielski
6885d6e4e5SJim Jagielskidef judge(baseline, documents, kinds):
6985d6e4e5SJim Jagielski    """(lines, bad): how `kinds` of the run differ from the baseline, and whether it is worse."""
7085d6e4e5SJim Jagielski    missing = sorted(set(baseline["documents"]) - set(documents))
7185d6e4e5SJim Jagielski    lines, bad = compare.compare(baseline["kinds"], kinds)
7285d6e4e5SJim Jagielski    return ["NOT COVERED  " + d for d in missing] + lines, bool(missing) or bad
73