Website: machine estimator v3 — the bar shows what the box's memory is used for (still unlisted, R-997)
gates / gates (push) Successful in 6m29s
gates / gates (push) Successful in 6m29s
The bar keeps its length (the fits-well box memory) and is split into base system (box - guest), Felhom's own services, each app's peak (largest first, the dashboard's palette minus amber and its first blue; beyond 8 apps one group) and spare room (guest - peak) — all from the one rule; a test proves the parts sum to the bar within 1 MB. A legend under it (not sticky) and one sentence explain the recommended size. Typical figure moved into the method fold-out. English: 'an 8 GB machine'.
This commit is contained in:
@@ -59,6 +59,16 @@ def estimate(d, slugs): # mirrors sizing.js estimate()
|
||||
return peak, out
|
||||
|
||||
|
||||
def segments(d, slugs): # mirrors estimate().segments in sizing.js (v3)
|
||||
by = {a["slug"]: a for a in d["apps"]}
|
||||
apps = sorted((by[s] for s in slugs if not by[s].get("builtin")), key=lambda a: -a["peak_mb"])
|
||||
peak = d["platform_mb"] + sum(a["peak_mb"] for a in apps)
|
||||
well = min_box_gb(d, peak * d["headroom"])
|
||||
box, guest = well * 1024, guest_mib(d, well)
|
||||
return well, [("base", box - guest), ("platform", d["platform_mb"])] + \
|
||||
[(a["slug"], a["peak_mb"]) for a in apps] + [("spare", guest - peak)]
|
||||
|
||||
|
||||
def first(d, verdicts, want): # mirrors recommend_gb / tight_box_gb in sizing.js
|
||||
return next((gb for gb, v in zip(d["boxes_gb"], verdicts) if v == want), None)
|
||||
|
||||
@@ -112,6 +122,32 @@ class SizingWeb(unittest.TestCase):
|
||||
if rec is not None:
|
||||
self.assertGreaterEqual(rec, gb - 1 / 1024)
|
||||
|
||||
def test_segments_add_up_to_the_bar(self):
|
||||
for name, sel in {"household": HOUSEHOLD, "household without immich": [x for x in HOUSEHOLD if x != "immich"],
|
||||
"immich alone": ["immich"], "all 62": self.all, "nothing": []}.items():
|
||||
well, segs = segments(self.d, sel)
|
||||
self.assertAlmostEqual(sum(mb for _, mb in segs), well * 1024, delta=1, msg=name)
|
||||
self.assertGreaterEqual(dict(segs)["base"], 0, name + ": base system negative")
|
||||
self.assertGreaterEqual(dict(segs)["spare"], 0, name + ": spare negative")
|
||||
# the household preset, by hand: peak 5,515 MiB; the bar holds 5,515 * 1.5 = 8,272.5 in the guest
|
||||
well, segs = segments(self.d, HOUSEHOLD)
|
||||
self.assertAlmostEqual(dict(segs)["spare"], 5515 * 0.5, delta=1)
|
||||
self.assertAlmostEqual(dict(segs)["base"], 4708, delta=1) # 4,096 for Proxmox + 612 MemTotal shortfall
|
||||
|
||||
def test_english_article(self):
|
||||
with io.open(os.path.join(ROOT, "website", "en", "sizing.html"), encoding="utf-8-sig") as f:
|
||||
t = json.loads(re.search(r'id="sizer-strings">(.*?)</script>', f.read(), re.S).group(1))
|
||||
def say(tpl, gb): # mirrors fill() in sizing.js
|
||||
art = t["an"] if str(gb) in t["an_before"] else t["a"]
|
||||
return tpl.replace("{a}", art).replace("{gb}", str(gb))
|
||||
got = {gb: say(t["recommend"], gb) for gb in self.d["boxes_gb"]}
|
||||
self.assertEqual(got[8], "Recommended: an 8 GB machine.")
|
||||
for gb in self.d["boxes_gb"]:
|
||||
if gb != 8:
|
||||
self.assertEqual(got[gb], "Recommended: a %d GB machine." % gb)
|
||||
for k in ("tight_on", "only_tight", "none_fits"):
|
||||
self.assertNotRegex(say(t[k], 8), r"\ba 8\b", k)
|
||||
|
||||
def test_sizing_md_table_agrees_with_the_rule(self):
|
||||
with io.open(SIZING_MD, encoding="utf-8") as f:
|
||||
s = f.read()
|
||||
@@ -146,7 +182,8 @@ class SizingWeb(unittest.TestCase):
|
||||
nums = set(re.findall(r"(?<![\w.])\d+(?:\.\d+)?", code))
|
||||
allowed = {"0", "1", "2", "100", "1024"} # 100 = percent, 1024 = MiB per GiB; no rule constant
|
||||
self.assertTrue(nums <= allowed, "sizing.js holds its own numbers: %s" % sorted(nums - allowed))
|
||||
for need in ("data.bar_max_gb", "data.bar_marks_gb", "function minBoxGb", "guestMib(data, mid) >= needMib"):
|
||||
for need in ("data.bar_max_gb", "data.bar_marks_gb", "function minBoxGb", "guestMib(data, mid) >= needMib",
|
||||
"data.bar_app_colours", "boxMb - guestMb", "guestMb - peak"):
|
||||
self.assertIn(need, js)
|
||||
|
||||
def test_data_has_no_peak_below_typical(self):
|
||||
|
||||
Reference in New Issue
Block a user