aboutsummaryrefslogtreecommitdiffstats
path: root/test_changelog.py
blob: b1454b85e98eebe43816c468e90a36ce01c4f0d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3
# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""Self-check: run `python3 test_changelog.py`. Fakes the mirror, exercises
parsing, caching and the stale fallback."""

import io
import urllib.request

import slackware_changelog as c

SAMPLE = """Mon Sep  7 22:56:39 UTC 2026
a/util-linux-2.42.3-x86_64-1.txz:  Upgraded.
  This update fixes bugs and security issues.
  For more information, see:
    https://www.cve.org/CVERecord?id=CVE-2026-76642
    https://www.cve.org/CVERecord?id=CVE-2026-78410
  (* Security fix *)
l/cryptopp-8.9.0-x86_64-3.txz:  Rebuilt.
  Fixed library location. Thanks to Petri Kaukasoina.
n/foo-1.0-x86_64-1.txz:  Added.
n/bar-1.0-x86_64-1.txz:  Removed.
+--------------------------+
Sun Sep  6 00:00:00 UTC 2026
a/should-not-appear-1.0-x86_64-1.txz:  Upgraded.
"""

fail = [False]


def fake_urlopen(url, timeout=0):
    if fail[0]:
        raise OSError("mirror down")
    return io.BytesIO(SAMPLE.encode())


urllib.request.urlopen = fake_urlopen

d = c.parse(SAMPLE)
assert d["date"] == "Mon Sep  7 22:56:39 UTC 2026", d["date"]
assert (d["packages"], d["upgraded"], d["rebuilt"], d["added"], d["removed"]) == (4, 1, 1, 1, 1), d
assert d["security"] == 1, d
assert d["cves"] == ["CVE-2026-76642", "CVE-2026-78410"], d["cves"]
assert "should-not-appear" not in d["entry"], "the next entry leaked in"
assert d["package_list"][0] == {"name": "a/util-linux-2.42.3-x86_64-1.txz",
                                "action": "upgraded"}, d["package_list"][0]
assert "1 upgraded" in d["summary"], d["summary"]

# An indented note that ends in a word plus a period is not a package line.
assert all("Thanks to" not in p["name"] for p in d["package_list"]), d["package_list"]

# Cache holds, and a failing refresh keeps serving the last good entry.
first = c.fetch()
assert first["date"] == d["date"]
fail[0] = True
stale = c.fetch(force=True)
assert stale["date"] == d["date"], "lost the cached entry on a failed refresh"
assert "mirror down" in stale["stale"], stale.get("stale")

# /top: flat keys, prefix and .txz stripped, overflow line when truncated.
t = c.top(d, n=2)
assert t["pkg1"] == "util-linux-2.42.3-x86_64-1 - upgraded", t["pkg1"]
assert t["pkg3"] == "... and 2 more", t
assert t["packages"] == 4 and t["date"] == d["date"], t
assert "pkg4" not in t, t
assert "pkg5" not in c.top(d, n=10), "overflow line on a complete list"
assert c.top(d, n=10)["pkg4"] == "bar-1.0-x86_64-1 - removed", c.top(d, n=10)

page = c.render(c._cache["data"])
assert "Sep  7" in page and "util-linux" in page
assert "<script" not in page.lower(), "changelog text must not reach the page as markup"

print("ok")