Land feature 57's SDK work on its release branch
mesh/merge-gate head d3e182503c19 merged into trunk c8b07242a009 — pass: [release feat/57-config-and-provisioning, judged by its controller fcdecb436117] t…
mesh/repo-check head d3e182503c19 merged into trunk c8b07242a009 — pass: [release feat/57-config-and-provisioning, judged by its controller fcdecb436117] i…
mesh/delivery delivered
mesh/merge-gate head d3e182503c19 merged into trunk c8b07242a009 — pass: [release feat/57-config-and-provisioning, judged by its controller fcdecb436117] t…
mesh/repo-check head d3e182503c19 merged into trunk c8b07242a009 — pass: [release feat/57-config-and-provisioning, judged by its controller fcdecb436117] i…
mesh/delivery delivered
Providers, the state bus, templates and the environment collection that the feature's modules build on (feature 57, config and provisioning).
This commit is contained in:
+6
-6
@@ -8,7 +8,7 @@ import { mkdtemp, writeFile, rm } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { runProvisioner, provisionerTools, RETIREMENT_EVENT, type Provisioner } from "../dist/provisioner/index.js";
|
||||
import { runProviderLoop, providerLoopTools, RETIREMENT_EVENT, type ProviderLoop } from "../dist/provider-loop/index.js";
|
||||
import { resetTools, collectTools } from "../dist/tools/index.js";
|
||||
|
||||
const EVERY = 10;
|
||||
@@ -32,7 +32,7 @@ interface World {
|
||||
reenabled: string[];
|
||||
events: Record<string, unknown>[];
|
||||
said: string[];
|
||||
p: Provisioner;
|
||||
p: ProviderLoop;
|
||||
done(): void;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ async function world(
|
||||
...(opts.retire === false ? {} : { async retire(p: { as: string; why: string }) { w.retired.push({ as: p.as, why: p.why }); } }),
|
||||
...(opts.held ? { async held() { return opts.held!; } } : {}),
|
||||
};
|
||||
w.p = runProvisioner("postgres-database", adapter, {
|
||||
w.p = runProviderLoop("postgres-database", adapter, {
|
||||
receives, everyMs: EVERY, node: "anchor", stableForMs: opts.stableForMs ?? 0,
|
||||
// Only retirement is these tests'; the standing (provisioner.failing, .recovered) is standing.test.ts's.
|
||||
announce: (event, body) => { if (event === RETIREMENT_EVENT) w.events.push(body); },
|
||||
@@ -168,7 +168,7 @@ test("five passes are not enough: the same set must also hold for stableForMs",
|
||||
});
|
||||
|
||||
test("the default hold is ten minutes", async () => {
|
||||
const { STABLE_FOR_MS } = await import("../dist/provisioner/index.js");
|
||||
const { STABLE_FOR_MS } = await import("../dist/provider-loop/index.js");
|
||||
assert.equal(STABLE_FOR_MS, 10 * 60_000);
|
||||
});
|
||||
|
||||
@@ -327,7 +327,7 @@ test("the four tools are registered for the module and answer", async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), "retire-tools-"));
|
||||
const receives = join(dir, "r.json");
|
||||
await writeFile(receives, JSON.stringify({ requirement: "r", given: [] }));
|
||||
const p = runProvisioner("r", { async create() {}, async remove() {} }, { receives, everyMs: EVERY, module: "postgres" });
|
||||
const p = runProviderLoop("r", { async create() {}, async remove() {} }, { receives, everyMs: EVERY, module: "postgres" });
|
||||
try {
|
||||
const mine = collectTools({}).find((c) => c.module === "postgres");
|
||||
assert.deepEqual(mine?.tools.map((t) => t.name), [
|
||||
@@ -336,7 +336,7 @@ test("the four tools are registered for the module and answer", async () => {
|
||||
const answer = (await mine!.tools[0].run({})) as { resource: string; waiting: unknown };
|
||||
assert.equal(answer.resource, "r");
|
||||
assert.equal(answer.waiting, null);
|
||||
assert.equal(provisionerTools(p).length, 4);
|
||||
assert.equal(providerLoopTools(p).length, 4);
|
||||
} finally {
|
||||
p();
|
||||
resetTools();
|
||||
|
||||
+26
-13
@@ -6,7 +6,7 @@ import { join } from "node:path";
|
||||
|
||||
import { compareVersions } from "../dist/primitives/index.js";
|
||||
import { registerModuleTools, collectTools, collectToolsEach, resetTools, serveTools, listTools, invokeTool } from "../dist/tools/index.js";
|
||||
import { runProvisioner } from "../dist/provisioner/index.js";
|
||||
import { runProviderLoop } from "../dist/provider-loop/index.js";
|
||||
import { emit, on, type Event } from "../dist/events/index.js";
|
||||
import { useBroker } from "../dist/messaging/index.js";
|
||||
|
||||
@@ -47,7 +47,7 @@ test("provisioner creates each consumer with the mesh's login and password; remo
|
||||
doc([{ from: "webapp", node: "anchor", as: "webapp-anchor", secret: join(dir, "webapp.secret"), values: { name: "webapp" } }]),
|
||||
);
|
||||
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"analytics",
|
||||
{
|
||||
async create(p) {
|
||||
@@ -101,7 +101,7 @@ test("provisioner hands the adapter what the mesh derived, and still has it at w
|
||||
});
|
||||
await writeFile(receives, doc([entry("mesh-anchor-ncloud")]));
|
||||
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"s3-bucket",
|
||||
{
|
||||
async create(p) {
|
||||
@@ -153,7 +153,7 @@ test("provisioner stops calling an unreadable secret a race, and says what to lo
|
||||
console.error = (line: unknown) => { said.push(String(line)); };
|
||||
let stop: (() => void) | undefined;
|
||||
try {
|
||||
stop = runProvisioner("db", { async create() {}, async remove() {} }, { receives, everyMs: 5 });
|
||||
stop = runProviderLoop("db", { async create() {}, async remove() {} }, { receives, everyMs: 5 });
|
||||
await waitFor(() => said.some((l) => l.includes("CANNOT READ")), 3000);
|
||||
} finally {
|
||||
stop?.();
|
||||
@@ -185,7 +185,7 @@ test("provisioner removes nothing while its contributions file cannot be used (n
|
||||
]);
|
||||
await writeFile(receives, both);
|
||||
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"postgres-database",
|
||||
{
|
||||
async create(p) {
|
||||
@@ -239,7 +239,7 @@ test("provisioner applies again what the backend no longer holds, and trusts mem
|
||||
const backend = new Set<string>();
|
||||
let creates = 0;
|
||||
let asked = 0;
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create(p) {
|
||||
@@ -271,7 +271,7 @@ test("provisioner applies again what the backend no longer holds, and trusts mem
|
||||
// An adapter without holds is trusted from memory, as before: a forgotten backend stays forgotten.
|
||||
const forgetful = new Set<string>();
|
||||
let plainCreates = 0;
|
||||
const stopPlain = runProvisioner(
|
||||
const stopPlain = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create(p) {
|
||||
@@ -299,7 +299,7 @@ test("provisioner keeps a consumer applied when the backend cannot be asked", as
|
||||
);
|
||||
let creates = 0;
|
||||
let asked = 0;
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create() {
|
||||
@@ -330,7 +330,7 @@ test("provisioner backs off when create does not satisfy holds, and says so", as
|
||||
const original = console.error;
|
||||
console.error = (...a: unknown[]) => logged.push(a.join(" "));
|
||||
try {
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create() {
|
||||
@@ -371,7 +371,7 @@ test("provisioner treats a failed or hung holds as could-not-ask, and never logs
|
||||
const original = console.error;
|
||||
console.error = (...a: unknown[]) => logged.push(a.join(" "));
|
||||
try {
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create() {
|
||||
@@ -404,7 +404,7 @@ test("provisioner treats a failed or hung holds as could-not-ask, and never logs
|
||||
const hungLogged: string[] = [];
|
||||
console.error = (...a: unknown[]) => hungLogged.push(a.join(" "));
|
||||
try {
|
||||
const stopHung = runProvisioner(
|
||||
const stopHung = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create() {
|
||||
@@ -438,7 +438,7 @@ test("provisioner stops a verify pass at a timeout, and retries a failed re-appl
|
||||
try {
|
||||
// A timeout on "a" means "b" is not asked in that pass.
|
||||
const askedFor: string[] = [];
|
||||
const stopHung = runProvisioner(
|
||||
const stopHung = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create() {},
|
||||
@@ -460,7 +460,7 @@ test("provisioner stops a verify pass at a timeout, and retries a failed re-appl
|
||||
let createCalls = 0;
|
||||
const logged: string[] = [];
|
||||
console.error = (...a: unknown[]) => logged.push(a.join(" "));
|
||||
const stop = runProvisioner(
|
||||
const stop = runProviderLoop(
|
||||
"cache",
|
||||
{
|
||||
async create(p) {
|
||||
@@ -649,3 +649,16 @@ test("each registration is given the environment asked for it, and sees no other
|
||||
assert.deepEqual(seen.beta, { BETA_URL: "http://127.0.0.1:3000" });
|
||||
resetTools();
|
||||
});
|
||||
|
||||
test("the provider loop is named for what it is, and its old name stays an alias until its providers move (issue 678)", async () => {
|
||||
const loop = await import("../dist/provider-loop/index.js");
|
||||
const old = await import("../dist/index.js");
|
||||
assert.equal(old.provisioner.runProvisioner, loop.runProviderLoop);
|
||||
assert.equal(old.provisioner.provisionerTools, loop.providerLoopTools);
|
||||
assert.equal(old.providerLoop.runProviderLoop, loop.runProviderLoop);
|
||||
const pkg = JSON.parse(await (await import("node:fs/promises")).readFile(new URL("../package.json", import.meta.url), "utf8"));
|
||||
assert.equal(pkg.exports["./provider-loop"], "./dist/provider-loop/index.js");
|
||||
assert.equal(pkg.exports["./provisioner"], pkg.exports["./provider-loop"]);
|
||||
// The events and tools are what the controller and the operator read on the bus: their names stay.
|
||||
assert.equal(loop.FAILING_EVENT, "provisioner.failing");
|
||||
});
|
||||
|
||||
@@ -9,9 +9,9 @@ import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import {
|
||||
runProvisioner, classOf, FAILING_EVENT, RECOVERED_EVENT, RETIREMENT_EVENT,
|
||||
runProviderLoop, classOf, FAILING_EVENT, RECOVERED_EVENT, RETIREMENT_EVENT,
|
||||
CLASS_CREDENTIALS, CLASS_UNREACHABLE, CLASS_SECRET, CLASS_REFUSED, type Adapter,
|
||||
} from "../dist/provisioner/index.js";
|
||||
} from "../dist/provider-loop/index.js";
|
||||
import { useBroker } from "../dist/messaging/index.js";
|
||||
|
||||
const EVERY = 10;
|
||||
@@ -68,7 +68,7 @@ async function world(opts: { classify?: boolean; announce?: false; stableForMs?:
|
||||
};
|
||||
const was = console.error;
|
||||
console.error = () => {};
|
||||
const stop = runProvisioner("postgres-database", adapter, {
|
||||
const stop = runProviderLoop("postgres-database", adapter, {
|
||||
receives, everyMs: EVERY, verifyEveryMs: 0, node: "home-server",
|
||||
failingAfterMs: FAILING_AFTER, sayAgainEveryMs: SAY_AGAIN, stableForMs: opts.stableForMs ?? 0,
|
||||
...(opts.announce === false ? {} : {
|
||||
|
||||
Reference in New Issue
Block a user