feat(v4.0.0): Hera kills a node by number and tells the others it is gone
Hera keeps a table of the nodes she has had born, number and place. KILL ( n -- ): she asks the kernel to remove node n, forgets her own way to it, and sends GONE about it to every other node in the table. A node she never had born, herself, or one she has killed already is an error that says so, and nothing is removed. v3's word and meaning; v3's takes a name, and a mesh node has a number. test_host_unit.c, 74 checks: Hera kills node 14 while node 12 is blocked writing to it, and what 12 then sends there is refused; node 12 waits on node 13, stuck in a loop and not its neighbour, and the wait ends Node gone when Hera kills 13; Hera waits on node 12, stuck, and a line typed at the console ends her wait Interrupted and then kills 12. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
cbe1cd5e44
commit
ee2bbf4ecf
@@ -499,21 +499,62 @@ int main(void)
|
||||
CHECK(strcmp(tell(10, "(LOST) @ ."), "0 ") == 0 && strcmp(tell(12, "(LOST) @ ."), "0 ") == 0, "and no message was let go");
|
||||
CHECK(waiting(10) && waiting(11) && waiting(12) && waiting(13) && waiting(14), "all five are waiting at their ports again");
|
||||
|
||||
/* ---- a node is killed while its neighbour is writing to it ---- */
|
||||
/* ---- Hera kills a node by number, and tells the others it is gone (MESH.md 7b) ---- */
|
||||
|
||||
/* a node is killed while its neighbour is writing to it */
|
||||
step_limit = 3000000ul;
|
||||
CHECK(strcmp(tell(14, ": SPIN BEGIN 0 UNTIL ; SPIN"), "(still running)") == 0, "node 14 is stuck in a loop that never ends");
|
||||
CHECK(strcmp(tell(12, ": TO14 S\" 65 EMIT\" 14 SEND ; TO14"), "(still running)") == 0 && node_numbered(12)->asking,
|
||||
"node 12, beside it, sends it text: 14 never reads, and 12 is blocked writing to it");
|
||||
{
|
||||
unsigned born = born_count;
|
||||
const char *r = tell(10, "(P4) @ NODE-KILL 65 EMIT");
|
||||
CHECK(strstr(printed, "A") != NULL && node_numbered(14) == NULL && born_count == born, "Hera kills node 14: \"%s\"", r);
|
||||
const char *r = tell(10, "14 KILL 65 EMIT");
|
||||
CHECK(strstr(printed, "A") != NULL && node_numbered(14) == NULL && born_count == born, "Hera kills node 14, by its number: \"%s\"", r);
|
||||
}
|
||||
CHECK(!node_numbered(12)->asking && !node_numbered(12)->stopped && waiting(12), "node 12 is no longer blocked: it is waiting at its ports");
|
||||
CHECK(strstr(printed, "No one on that port") != NULL, "what it was doing ended in an error, which said so: \"%s\"", printed);
|
||||
step_limit = 30000000ul;
|
||||
CHECK(strcmp(tell(12, "12 100 * ."), "1200 ") == 0 && strcmp(tell(13, "13 100 * ."), "1300 ") == 0 && strcmp(tell(10, "1 2 + ."), "3 ") == 0, "and everything else keeps running: \"%s\"", printed);
|
||||
CHECK(strstr(tell(12, ": AGAIN14 S\" 65 EMIT\" 14 SEND ; AGAIN14"), "No one on that port") != NULL && waiting(12), "a later write to where node 14 was is an error at once, not a wait: \"%s\"", printed);
|
||||
CHECK(strstr(tell(12, "5 3 PORT!"), "No one on that port") != NULL && waiting(12), "a write to the port node 14 was on is an error at once, not a wait: \"%s\"", printed);
|
||||
{
|
||||
v4_cell refused = node_numbered(12)->mem[REFUSED];
|
||||
CHECK(tell(12, ": AGAIN14 S\" 65 EMIT\" 14 SEND ; AGAIN14")[0] == 0 && node_numbered(12)->mem[REFUSED] == refused + 1 && waiting(12),
|
||||
"every node was told 14 is gone and forgot the way: what node 12 sends it now goes toward Hera, who has no way either, and is refused: \"%s\"", printed);
|
||||
CHECK(strstr(tell(10, ": H14 S\" 1\" 14 SEND ; H14"), "Argument out of range") != NULL, "Hera herself has no way to it");
|
||||
}
|
||||
|
||||
/* a node waits on one that is stuck and is not its neighbour; Hera kills the stuck one */
|
||||
step_limit = 3000000ul;
|
||||
CHECK(strcmp(tell(13, ": SPIN BEGIN 0 UNTIL ; SPIN"), "(still running)") == 0, "node 13 is stuck in a loop");
|
||||
CHECK(strcmp(tell(12, ": W13 13 AWAIT . ; W13"), "(still running)") == 0 && node_numbered(12)->mem[AWAIT_FROM] == 13 && waiting(12),
|
||||
"node 12, which is not wired to it, waits for its answer");
|
||||
(void)tell(10, "13 KILL");
|
||||
CHECK(node_numbered(13) == NULL && strstr(printed, "Node gone") != NULL && node_numbered(12)->mem[AWAIT_FROM] == 0 && waiting(12),
|
||||
"Hera kills node 13: node 12's wait ends, with an error that says the node is gone: \"%s\"", printed);
|
||||
step_limit = 30000000ul;
|
||||
CHECK(strcmp(tell(12, "12 100 * ."), "1200 ") == 0 && strcmp(tell(11, "11 100 * ."), "1100 ") == 0, "and the others go on");
|
||||
|
||||
/* Hera's own wait, on a node that is stuck: a line from the console ends it */
|
||||
step_limit = 3000000ul;
|
||||
CHECK(strcmp(tell(12, ": SPIN BEGIN 0 UNTIL ; SPIN"), "(still running)") == 0, "node 12 is stuck in a loop");
|
||||
CHECK(strcmp(tell(10, "12 AWAIT ."), "(still running)") == 0 && node_numbered(10)->mem[AWAIT_FROM] == 12 && waiting(10), "Hera waits for its answer, which will not come");
|
||||
{
|
||||
const char *r = tell(10, "12 KILL 66 EMIT");
|
||||
CHECK(strstr(r, "Interrupted\n") != NULL && strstr(r, "B") != NULL && strstr(r, "Interrupted\n") < strstr(r, "B") && ended == 2,
|
||||
"a line typed at the console ends her wait, with an error that says so, and is then done: \"%s\"", r);
|
||||
CHECK(node_numbered(12) == NULL && node_numbered(10)->mem[AWAIT_FROM] == 0, "the line killed the stuck node");
|
||||
}
|
||||
step_limit = 30000000ul;
|
||||
|
||||
/* what is not a node she has had born */
|
||||
{
|
||||
unsigned born = born_count;
|
||||
CHECK(strstr(tell(10, "99 KILL"), "KILL: no such node") != NULL && ended_how == V4_TEXT_ERROR, "KILL of a node there never was is an error that says so: \"%s\"", printed);
|
||||
CHECK(strstr(tell(10, "10 KILL"), "KILL: no such node") != NULL && ended_how == V4_TEXT_ERROR && node_numbered(10) != NULL, "so is KILL of Hera herself");
|
||||
CHECK(strstr(tell(10, "14 KILL"), "KILL: no such node") != NULL && ended_how == V4_TEXT_ERROR, "and of a node she has killed already");
|
||||
CHECK(born_count == born && node_numbered(11) != NULL && strcmp(tell(11, "11 100 * ."), "1100 ") == 0 && strcmp(tell(10, "1 2 + ."), "3 ") == 0,
|
||||
"nothing was removed, and the two that are left go on");
|
||||
}
|
||||
|
||||
printf(" %d checks, %d failures\n", checks, failures);
|
||||
return failures != 0;
|
||||
|
||||
Reference in New Issue
Block a user