mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-16 01:29:55 -07:00
forgetest tests: the confirmed trims of the tool's own unit tests
The cases that tested a mock, a timer, a wording or a table, or that
replayed a judgment a host test already holds, leave forgetest/tests.
What catches a false PASS, keeps the bench safe, or guards the gate
stays.
- test_baseline: the fake sysfs tree is a mixin with no test_ methods,
so ExtensionFreeTests and BaselineModeTests no longer re-run
BaselineTests' 25 cases (133 runs, now 45). CoolPublishTests, the
lamp-fade cases and TransientNotLeftoverTests go; PositionDeadbandTests
keeps a reading past the band and an unreadable reading, both never
excused. Both latch-relock cases stay.
- test_fixture: MdnsTests, the three timing cases, the probe's log
wording, and nine prompt-routing variants go. A live test never runs
unattended, the arm-press opt-in, the short-press edge, the presence
press handing over the arm press, and the arm notice dropping at the
press stay (35 cases, now 21).
- test_cloud_suite: three false-PASS guards stay: the latch open at a
dark print's button, a lid stop that is not edge-driven, the kernel
refusing the resume. The guards for the latch unlocking in the hold
and a paused print resuming left with their catalog tests in 6a434bb.
The rest go, with the harness pieces and the hunt-lid fixture only
they read (41 cases, now 3).
- test_cooling_suite: GateOffTests, CriticalTierTests, FanGateTests and
FansQuietTests go with their harness; the flow verdict's log reads
stay: only the text after the offset, never an older verdict before it
(the flow-under-load false-PASS guard), a rotated log read whole.
- test_queue: RunClockTests and three ordering cases go, and refusals
are judged by a reason given, not its words; both live
acknowledgment cases stay.
- test_takeover_position: the six cases that judge the head and move
nothing stay.
- test_camera_home_return: the five cases where the head must not move
stay, and so do the three that check the hand-back jog's direction and
distance (homed, unhomed with the counters not counted twice, after
cloud mode): a wrong sign or a double count drives the head into the
gantry stops (15 cases, now 8).
- test_server: the keep-alive and ETag cases, the takeover and scope
half of the bench case, and the page's self-contained asserts
(test_page.py's) go.
- test_operator: the wording cases, the fixture case (test_fixture.py's)
and JournalTests go.
- test_mode: the supervisor timeout table goes.
- test_takeover_client: the listener, the offline service back, the
online client without the hunt, and GRBL under no marker stay.
- test_responsiveness: PageTests and ImplementationCostTests go; the
log cache keeps appends, a partial line, a replaced file and a fresh
list, and the fingerprint cache a changed manifest and one with no
content hash.
- test_bench_registry: GfbenchTests and two description and argument
pins go.
- test_installer: the log-format and TLS-wording cases and
InstallerShapeTests go; the die case checks the reason is in the log,
not its format.
- test_image: KernelIdentTests and the registration pin go.
Each file's __main__ guard now ends the file, and the docstrings say what
each still proves.
Proof: each of the fifteen files passes under Linux as forgetest-ci
discovers it, and pyflakes reports nothing new in them.
Acceptance: none; test-only.
This commit is contained in:
@@ -8,7 +8,6 @@ fake bench tool. No hardware, no forgectrl."""
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
@@ -18,7 +17,7 @@ import urllib.request
|
||||
|
||||
import helpers
|
||||
from forgetest import bench as bench_mod
|
||||
from forgetest import catalog, server
|
||||
from forgetest import server
|
||||
from forgetest.log import Log
|
||||
from forgetest.runner import Failed, Runner
|
||||
|
||||
@@ -157,13 +156,6 @@ class ServerTests(unittest.TestCase):
|
||||
st, d = self.call("GET", "/", token=False)
|
||||
self.assertEqual(st, 200)
|
||||
self.assertIn(self.token.encode(), d)
|
||||
page = d.decode("utf-8")
|
||||
# one self-contained response: nothing linked, the token once,
|
||||
# the theme attribute the head script sets
|
||||
self.assertEqual(page.count(self.token), 1)
|
||||
self.assertNotIn("<link ", page)
|
||||
self.assertNotIn("<script src=", page)
|
||||
self.assertIn("data-bs-theme", page)
|
||||
st, d = self.call("GET", "/state", headers={"Host": "evil.example.net"})
|
||||
self.assertEqual(st, 403)
|
||||
st, d = self.call("GET", "/state", headers={"Origin": "http://evil.example.net"})
|
||||
@@ -179,23 +171,6 @@ class ServerTests(unittest.TestCase):
|
||||
st, d = self.call("GET", "/nope")
|
||||
self.assertEqual(st, 404)
|
||||
|
||||
def test_01c_connection_is_kept_alive(self):
|
||||
"""A poll per second over a fresh TCP connection each time is
|
||||
waste the board does not need to pay."""
|
||||
import http.client
|
||||
c = http.client.HTTPConnection("127.0.0.1", self.port, timeout=10)
|
||||
try:
|
||||
for _ in range(3):
|
||||
c.request("GET", "/state", headers={"Host": "127.0.0.1:%d" % self.port})
|
||||
r = c.getresponse()
|
||||
r.read()
|
||||
self.assertEqual(r.status, 200)
|
||||
self.assertEqual(r.version, 11)
|
||||
self.assertNotEqual((r.getheader("Connection") or "").lower(), "close")
|
||||
self.assertIsNotNone(r.getheader("Content-Length"))
|
||||
finally:
|
||||
c.close()
|
||||
|
||||
def test_01d_refused_post_does_not_poison_the_connection(self):
|
||||
"""A POST refused before its body is read leaves that body in the
|
||||
socket. On a kept-alive connection the next read would take it for
|
||||
@@ -364,22 +339,6 @@ class ServerTests(unittest.TestCase):
|
||||
st, d = self.call("POST", "/abort")
|
||||
state = self.wait_idle()
|
||||
self.assertEqual(state["last_run"]["finished"]["result"], "ABORTED")
|
||||
# a takeover tool runs inside the takeover wrapper (init.d is absent on the host: rc 127)
|
||||
st, d = self.call("POST", "/bench/start", {"tool": "tk"})
|
||||
self.assertEqual(st, 200, d)
|
||||
state = self.wait_idle(timeout=40) # two unreachable-forgectrl settle waits
|
||||
log = "\n".join(state["last_run"]["log"])
|
||||
self.assertIn("takeover: pulse device free", log)
|
||||
self.assertIn("takeover: forgectrl start", log)
|
||||
self.assertIn("baseline: forgectrl unreachable for 10 s", log)
|
||||
self.assertFalse(os.path.exists(os.environ["FORGETEST_MARKER"]))
|
||||
# a scope tool is a takeover too
|
||||
st, d = self.call("POST", "/bench/start", {"tool": "sc"})
|
||||
self.assertEqual(st, 200, d)
|
||||
state = self.wait_idle(timeout=40)
|
||||
log = "\n".join(state["last_run"]["log"])
|
||||
self.assertIn("takeover: pulse device free", log)
|
||||
self.assertIn("takeover: forgectrl start", log)
|
||||
# bench runs never touched the acceptance log
|
||||
recs = self.log.read()
|
||||
self.assertFalse(any(r.get("t") == "result" and r.get("test") == "echo" for r in recs))
|
||||
@@ -406,31 +365,6 @@ class ServerTests(unittest.TestCase):
|
||||
self.assertNotIn("messages", r.state()[0])
|
||||
self.assertFalse(os.path.exists(marker))
|
||||
|
||||
def test_10_state_is_conditional(self):
|
||||
"""The page polls; an unchanged state must cost a 304, and the
|
||||
ETag must move as soon as the state does.
|
||||
|
||||
Runs last because it invalidates: timestamps are whole seconds, and
|
||||
a PASS stamped in the same second as an invalidate is deliberately
|
||||
not inheritable, so an invalidate early in this class would decide
|
||||
the inheritance the earlier tests are checking.
|
||||
"""
|
||||
st, d, hdrs = self.call_h("GET", "/state")
|
||||
self.assertEqual(st, 200)
|
||||
etag = hdrs.get("ETag")
|
||||
self.assertTrue(etag and etag.startswith('"'), "no ETag on /state")
|
||||
st, _, hdrs2 = self.call_h("GET", "/state", headers={"If-None-Match": etag})
|
||||
self.assertEqual(st, 304)
|
||||
self.assertEqual(hdrs2.get("ETag"), etag)
|
||||
# a stale validator must not be honored
|
||||
st, _, _ = self.call_h("GET", "/state", headers={"If-None-Match": '"stale"'})
|
||||
self.assertEqual(st, 200)
|
||||
# and the validator moves with the state
|
||||
self.call("POST", "/invalidate", {"reason": "etag check"})
|
||||
st, _, hdrs3 = self.call_h("GET", "/state", headers={"If-None-Match": etag})
|
||||
self.assertEqual(st, 200)
|
||||
self.assertNotEqual(hdrs3.get("ETag"), etag)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user