@elaraai/e3-api-tests 1.0.84 → 1.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +13 -1
  2. package/dist/src/assertions.d.ts +15 -0
  3. package/dist/src/assertions.d.ts.map +1 -1
  4. package/dist/src/assertions.js +44 -1
  5. package/dist/src/assertions.js.map +1 -1
  6. package/dist/src/context.d.ts +29 -0
  7. package/dist/src/context.d.ts.map +1 -1
  8. package/dist/src/context.js +12 -9
  9. package/dist/src/context.js.map +1 -1
  10. package/dist/src/fixtures.d.ts +51 -4
  11. package/dist/src/fixtures.d.ts.map +1 -1
  12. package/dist/src/fixtures.js +78 -8
  13. package/dist/src/fixtures.js.map +1 -1
  14. package/dist/src/index.d.ts +12 -1
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +28 -14
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/suites/cli.d.ts.map +1 -1
  19. package/dist/src/suites/cli.js +19 -1
  20. package/dist/src/suites/cli.js.map +1 -1
  21. package/dist/src/suites/dataflow.d.ts.map +1 -1
  22. package/dist/src/suites/dataflow.js +347 -74
  23. package/dist/src/suites/dataflow.js.map +1 -1
  24. package/dist/src/suites/dataset-pages.js +4 -4
  25. package/dist/src/suites/dataset-pages.js.map +1 -1
  26. package/dist/src/suites/dataset-transfer.d.ts.map +1 -1
  27. package/dist/src/suites/dataset-transfer.js +115 -14
  28. package/dist/src/suites/dataset-transfer.js.map +1 -1
  29. package/dist/src/suites/functions.d.ts.map +1 -1
  30. package/dist/src/suites/functions.js +77 -7
  31. package/dist/src/suites/functions.js.map +1 -1
  32. package/dist/src/suites/package-transfer.d.ts.map +1 -1
  33. package/dist/src/suites/package-transfer.js +31 -3
  34. package/dist/src/suites/package-transfer.js.map +1 -1
  35. package/dist/src/suites/platform.d.ts.map +1 -1
  36. package/dist/src/suites/platform.js +7 -5
  37. package/dist/src/suites/platform.js.map +1 -1
  38. package/dist/src/suites/record-deploy.d.ts.map +1 -1
  39. package/dist/src/suites/record-deploy.js +16 -9
  40. package/dist/src/suites/record-deploy.js.map +1 -1
  41. package/dist/src/suites/records-keyed.d.ts.map +1 -1
  42. package/dist/src/suites/records-keyed.js +3 -2
  43. package/dist/src/suites/records-keyed.js.map +1 -1
  44. package/dist/src/suites/records.d.ts.map +1 -1
  45. package/dist/src/suites/records.js +40 -3
  46. package/dist/src/suites/records.js.map +1 -1
  47. package/dist/src/suites/workspaces.d.ts.map +1 -1
  48. package/dist/src/suites/workspaces.js +65 -1
  49. package/dist/src/suites/workspaces.js.map +1 -1
  50. package/package.json +14 -10
package/README.md CHANGED
@@ -47,19 +47,31 @@ The suites call as two callers:
47
47
 
48
48
  A server with no auth answers any token. One with auth needs both tokens signed or fetched, as `test/integration/src/api-compliance.spec.ts` signs them for the local server.
49
49
 
50
+ A harness whose server answers requests in its own process, such as e3 running in a page, gives `fetch`. Every request of the suites then goes through it: the client's calls, the suites' own requests (`ctx.fetch`) and e3's platform functions. `test/integration/src/api-compliance-fetch.spec.ts` runs the suites through a `fetch` that forwards to the local server, while the global `fetch` refuses every request.
51
+
52
+ A harness whose server runs no commands, such as e3 running in a page, sets `commands: false`. The suites' tasks are East, which every server runs, and their failing tasks fail in East: each is recorded `failed`, exit code 1, with its message in its stderr log. One case in `dataflowTests` runs a command, a custom task that exits 1. On a server that runs commands it expects that task `failed`, exit code 1; on one that runs none, recorded `error`, with a message saying the server runs no commands.
53
+
50
54
  ## Exports
51
55
 
52
56
  | Export | Description |
53
57
  |--------|-------------|
54
58
  | `TestSetup<T>` | Type for per-test context factory: `(t: TestContext) => Promise<T>` |
55
59
  | `createTestContext` | Create test context with helpers for setup/teardown |
56
- | `allApiTests` | Register all API test suites (repository, packages, workspaces, datasets, dataflow) |
60
+ | `allApiTests` | Register every API test suite of `apiTestSuites`: repository, packages, workspaces, datasets, dataset pages, dataset transfer, dataflow, functions, records, keyed records, record deploys, package transfer and platform |
61
+ | `apiTestSuites` | Every API test suite by name, in the order `allApiTests` registers them: for a harness that runs them in parts, and checks its parts name each once |
57
62
  | `allTests` | Register all tests including CLI tests (requires credentials env) |
58
63
  | `repositoryTests` | Repository CRUD tests |
59
64
  | `packageTests` | Package import/export tests |
60
65
  | `workspaceTests` | Workspace management tests |
61
66
  | `datasetTests` | Dataset read/write tests |
67
+ | `datasetPageTests` | Paged dataset reads and key search |
68
+ | `datasetTransferTests` | Dataset uploads and downloads through the transfer protocol |
62
69
  | `dataflowTests` | Dataflow execution tests |
70
+ | `functionTests` | Function calls, one-shots and split calls, as an admin and as a reader |
71
+ | `recordTests` | Record mutations |
72
+ | `keyedRecordTests` | Keyed records: every write form, and their indexes |
73
+ | `recordDeployTests` | Records across deploys: migrations |
74
+ | `packageTransferTests` | Package imports and exports as jobs |
63
75
  | `platformTests` | Platform capability tests |
64
76
  | `cliTests` | CLI integration tests |
65
77
  | `transferTests` | Cross-repository transfer tests |
@@ -2,6 +2,21 @@
2
2
  * Copyright (c) 2025 Elara AI Pty Ltd
3
3
  * Licensed under BSL 1.1. See LICENSE for details.
4
4
  */
5
+ /**
6
+ * Names no workspace can have, each with why, as a refusal says it: a lock's
7
+ * name (`main#dataflow`, the lock a run of main's dataflow holds), the
8
+ * characters that join a lock's parts, and one a file name cannot hold.
9
+ */
10
+ export declare const MALFORMED_WORKSPACE_NAMES: readonly [readonly ["main#dataflow", string], readonly ["a#b", string], readonly ["a~b", string], readonly ["bad:name", "holds \":\", which a file name cannot"]];
11
+ /**
12
+ * Checks an error is the API's refusal of `name` as no workspace's:
13
+ * `invalid_name`, whose details name the kind, the name and why.
14
+ *
15
+ * @param name - The name refused
16
+ * @param why - Why, as the refusal's message ends
17
+ * @returns An `assert.rejects` validator
18
+ */
19
+ export declare function refusedAsWorkspaceName(name: string, why: string): (err: unknown) => true;
5
20
  /** A single task entry in a dataflow result (subset we read for diagnostics). */
6
21
  interface TaskResultLike {
7
22
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../../src/assertions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,iFAAiF;AACjF,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,iEAAiE;AACjE,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAcD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAMzE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAO1F"}
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../../src/assertions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA6BH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,mKAK5B,CAAC;AAEX;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAYxF;AAED,iFAAiF;AACjF,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,iEAAiE;AACjE,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAcD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAMzE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAO1F"}
@@ -3,7 +3,8 @@
3
3
  * Licensed under BSL 1.1. See LICENSE for details.
4
4
  */
5
5
  /**
6
- * Diagnostic assertions for dataflow execution results.
6
+ * Assertions the suites share: of a dataflow's result, and of the API's
7
+ * refusal of a name no workspace can have.
7
8
  *
8
9
  * A bare `assert.strictEqual(result.success, true)` collapses a rich
9
10
  * failure — a task that exited non-zero, a runner that failed to spawn,
@@ -12,8 +13,50 @@
12
13
  * `.ref` rename-over-open can transiently fail). These helpers fold the
13
14
  * per-task diagnostics already carried in `result.tasks` into the
14
15
  * assertion message so the next failure is actionable instead of opaque.
16
+ *
17
+ * Every route of a workspace refuses a name no workspace can have before it
18
+ * takes a lock, as `invalid_name` of a workspace: a lock's name may hold the
19
+ * `#` and `~` that join its parts, so a route that took a lock first would
20
+ * refuse such a name as a lock's, if at all.
15
21
  */
16
22
  import assert from 'node:assert/strict';
23
+ import { equalFor, isValueOf, printFor } from '@elaraai/east';
24
+ import { InvalidNameErrorType } from '@elaraai/e3-types';
25
+ import { ApiError } from '@elaraai/e3-api-client';
26
+ /** Why no workspace's name may hold `c`: it joins the parts of a lock's name. */
27
+ const joinsLockNames = (c) => `holds ${JSON.stringify(c)}, which joins the parts of a lock's name`;
28
+ /**
29
+ * Names no workspace can have, each with why, as a refusal says it: a lock's
30
+ * name (`main#dataflow`, the lock a run of main's dataflow holds), the
31
+ * characters that join a lock's parts, and one a file name cannot hold.
32
+ */
33
+ export const MALFORMED_WORKSPACE_NAMES = [
34
+ ['main#dataflow', joinsLockNames('#')],
35
+ ['a#b', joinsLockNames('#')],
36
+ ['a~b', joinsLockNames('~')],
37
+ ['bad:name', `holds ":", which a file name cannot`],
38
+ ];
39
+ /**
40
+ * Checks an error is the API's refusal of `name` as no workspace's:
41
+ * `invalid_name`, whose details name the kind, the name and why.
42
+ *
43
+ * @param name - The name refused
44
+ * @param why - Why, as the refusal's message ends
45
+ * @returns An `assert.rejects` validator
46
+ */
47
+ export function refusedAsWorkspaceName(name, why) {
48
+ return (err) => {
49
+ assert.ok(err instanceof ApiError, `${name}: expected ApiError, got ${err}`);
50
+ assert.strictEqual(err.code, 'invalid_name');
51
+ assert.ok(isValueOf(err.details, InvalidNameErrorType), `${name}: the refusal names the name and why`);
52
+ const said = err.details;
53
+ const expected = {
54
+ kind: 'workspace', name, message: `the workspace name ${JSON.stringify(name)} ${why}`,
55
+ };
56
+ assert.ok(equalFor(InvalidNameErrorType)(said, expected), `${name}: refused as ${printFor(InvalidNameErrorType)(said)}`);
57
+ return true;
58
+ };
59
+ }
17
60
  /** Render one task's terminal state, surfacing exit code / error message. */
18
61
  function describeTask(task) {
19
62
  const { type, value } = task.state;
@@ -1 +1 @@
1
- {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../src/assertions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;GAUG;AAEH,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAoBxC,6EAA6E;AAC7E,SAAS,YAAY,CAAC,IAAoB;IACxC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;IACnC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,IAAI,KAAK,QAAQ,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;QACnF,MAAM,GAAG,oBAAoB,MAAM,CAAE,KAA+B,CAAC,QAAQ,CAAC,GAAG,CAAC;IACpF,CAAC;SAAM,IAAI,IAAI,KAAK,OAAO,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACxF,MAAM,GAAG,UAAU,MAAM,CAAE,KAA8B,CAAC,OAAO,CAAC,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;AACxE,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,sBAAsB,CAAC,MAA0B;IAC/D,MAAM,MAAM,GACV,YAAY,MAAM,CAAC,QAAQ,WAAW,MAAM,CAAC,MAAM,GAAG;QACtD,UAAU,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC;IACtD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,aAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAA0B,EAAE,OAAgB;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,EACd,IAAI,EACJ,GAAG,MAAM,gDAAgD,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAC1F,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../src/assertions.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,29 @@ export interface TestConfig {
22
22
  repoName?: string;
23
23
  /** Whether to clean up created resources (default: true) */
24
24
  cleanup?: boolean;
25
+ /**
26
+ * The `fetch` every request of the suites goes through: the client calls
27
+ * (`RequestOptions.fetch`), the suites' own requests ({@link TestContext.fetch})
28
+ * and e3's platform functions. Absent, the global `fetch`.
29
+ *
30
+ * @remarks
31
+ * A harness whose server answers requests in the process itself — e3
32
+ * running in a page — gives the `fetch` that reaches it.
33
+ */
34
+ fetch?: typeof globalThis.fetch;
35
+ /**
36
+ * Whether the server runs commands, such as a custom task's (default true).
37
+ * The dataflow suite's one command case runs a custom task whose command
38
+ * fails: a server that runs commands records it `failed`, exit code 1, and
39
+ * one that runs none records it `error`, with a message saying the server
40
+ * runs no commands.
41
+ *
42
+ * @remarks
43
+ * Every other task the suites run is East, which every server runs, their
44
+ * failing tasks included. A harness whose server runs no commands — e3
45
+ * running in a page — sets it false.
46
+ */
47
+ commands?: boolean;
25
48
  }
26
49
  /**
27
50
  * Context provided to each test suite.
@@ -38,6 +61,12 @@ export interface TestContext {
38
61
  /** Get request options with a reader's token for this repository
39
62
  * ({@link TestConfig.getReaderToken}) */
40
63
  readerOpts: () => Promise<RequestOptions>;
64
+ /** The `fetch` a suite's own requests go through: {@link TestConfig.fetch},
65
+ * or the global `fetch` when the harness gives none. */
66
+ fetch: typeof globalThis.fetch;
67
+ /** Whether the server runs commands: {@link TestConfig.commands}, or true
68
+ * when the harness does not say. */
69
+ commands: boolean;
41
70
  /** Create a test package and return path to zip file */
42
71
  createPackage: (name: string, version: string) => Promise<string>;
43
72
  /** Import a package from a zip file */
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,wBAAwB,CAAC;AAqB5E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAEhB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhC;;;;;OAKG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,MAAM,EAAE,UAAU,CAAC;IAEnB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IAEjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAEhB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAEpC;8CAC0C;IAC1C,UAAU,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAE1C,wDAAwD;IACxD,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAElE,uCAAuC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB;IACzB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,sCAAsC;IACtC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAgCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAuHhF"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,wBAAwB,CAAC;AAsB5E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAEhB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhC;;;;;OAKG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAEhC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,MAAM,EAAE,UAAU,CAAC;IAEnB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IAEjB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAEhB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAEpC;8CAC0C;IAC1C,UAAU,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;IAE1C;6DACyD;IACzD,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAE/B;yCACqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAElB,wDAAwD;IACxD,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAElE,uCAAuC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB;IACzB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,sCAAsC;IACtC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAgCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA8HhF"}
@@ -8,7 +8,7 @@
8
8
  import { mkdtempSync, rmSync, readFileSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
10
  import { tmpdir } from 'node:os';
11
- import { ApiError, repoCreate, repoRemove, packageImport, workspaceCreate, workspaceDeploy, workspaceList, workspaceRemove, dataflowCancel, } from '@elaraai/e3-api-client';
11
+ import { ApiError, requestFetch, repoCreate, repoRemove, packageImport, workspaceCreate, workspaceDeploy, workspaceList, workspaceRemove, dataflowCancel, } from '@elaraai/e3-api-client';
12
12
  import { createPackageZip } from './fixtures.js';
13
13
  /**
14
14
  * How long cleanup waits for a cancelled dataflow to release its workspace
@@ -57,10 +57,12 @@ export async function createTestContext(config) {
57
57
  let createdRepo = false;
58
58
  // Determine repo name - use provided or generate unique one
59
59
  const repoName = config.repoName ?? `test-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
60
+ /** Request options for a caller's token, through the harness's `fetch`. */
61
+ const requestOptions = (token) => (config.fetch === undefined ? { token } : { token, fetch: config.fetch });
60
62
  // Create repo if not using an existing one
61
63
  if (!config.repoName) {
62
64
  const token = await config.getToken();
63
- await repoCreate(config.baseUrl, repoName, { token });
65
+ await repoCreate(config.baseUrl, repoName, requestOptions(token));
64
66
  createdRepo = true;
65
67
  }
66
68
  /**
@@ -94,8 +96,10 @@ export async function createTestContext(config) {
94
96
  config,
95
97
  repoName,
96
98
  tempDir,
97
- opts: async () => ({ token: await config.getToken() }),
98
- readerOpts: async () => ({ token: await config.getReaderToken(repoName) }),
99
+ opts: async () => requestOptions(await config.getToken()),
100
+ readerOpts: async () => requestOptions(await config.getReaderToken(repoName)),
101
+ fetch: (input, init) => requestFetch(config)(input, init),
102
+ commands: config.commands ?? true,
99
103
  createPackage: async (name, version) => {
100
104
  const zipPath = await createPackageZip(tempDir, name, version);
101
105
  return zipPath;
@@ -103,24 +107,23 @@ export async function createTestContext(config) {
103
107
  importPackage: async (zipPath) => {
104
108
  const token = await config.getToken();
105
109
  const packageZip = readFileSync(zipPath);
106
- const result = await packageImport(config.baseUrl, repoName, packageZip, { token });
110
+ const result = await packageImport(config.baseUrl, repoName, packageZip, requestOptions(token));
107
111
  createdPackages.push({ name: result.name, version: result.version });
108
112
  },
109
113
  createWorkspace: async (name) => {
110
114
  const token = await config.getToken();
111
- await workspaceCreate(config.baseUrl, repoName, name, { token });
115
+ await workspaceCreate(config.baseUrl, repoName, name, requestOptions(token));
112
116
  createdWorkspaces.push(name);
113
117
  },
114
118
  deployPackage: async (workspace, pkgRef) => {
115
119
  const token = await config.getToken();
116
- await workspaceDeploy(config.baseUrl, repoName, workspace, pkgRef, { token });
120
+ await workspaceDeploy(config.baseUrl, repoName, workspace, pkgRef, requestOptions(token));
117
121
  },
118
122
  cleanup: async () => {
119
123
  if (config.cleanup === false) {
120
124
  return;
121
125
  }
122
- const token = await config.getToken();
123
- const opts = { token };
126
+ const opts = requestOptions(await config.getToken());
124
127
  try {
125
128
  if (createdRepo) {
126
129
  // Cancel running dataflows and delete all workspaces (required before repo deletion)
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"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"}
@@ -191,12 +191,38 @@ export declare function createStringPackageZip(tempDir: string, name: string, ve
191
191
  * @returns Path to the created zip file
192
192
  */
193
193
  export declare function createDiamondPackageZip(tempDir: string, name: string, version: string): Promise<string>;
194
+ /**
195
+ * Create a package whose task writes known lines to its stdout.
196
+ *
197
+ * Creates a package with:
198
+ * - Input: "lines" (Integer, default 3)
199
+ * - Task: "log" - writes `line 0` … `line <lines - 1>` to stdout, a line
200
+ * each, and returns how many it wrote
201
+ *
202
+ * With the default input its stdout log is {@link LOGGED_LINES}, every
203
+ * server's alike, which a read of the log by offset and limit is checked
204
+ * against.
205
+ *
206
+ * @param tempDir - Directory to write the zip file
207
+ * @param name - Package name
208
+ * @param version - Package version
209
+ * @returns Path to the created zip file
210
+ */
211
+ export declare function createLoggingPackageZip(tempDir: string, name: string, version: string): Promise<string>;
212
+ /** The stdout log of {@link createLoggingPackageZip}'s task, run on its
213
+ * default input. */
214
+ export declare const LOGGED_LINES = "line 0\nline 1\nline 2\n";
194
215
  /**
195
216
  * Create a package with a task that always fails.
196
217
  *
197
218
  * Creates a package with:
198
219
  * - Input: "value" (String, default "test")
199
- * - Task: "failing" - exits with code 1
220
+ * - Task: "failing" - fails in East as it runs, with the message "failing
221
+ * fails, given test"
222
+ *
223
+ * The failure is the East body's own, so every server runs it, one that runs
224
+ * no commands included. A server records it as the runner protocol does: the
225
+ * task `failed`, exit code 1, with the message in its stderr log.
200
226
  *
201
227
  * @param tempDir - Directory to write the zip file
202
228
  * @param name - Package name
@@ -204,6 +230,23 @@ export declare function createDiamondPackageZip(tempDir: string, name: string, v
204
230
  * @returns Path to the created zip file
205
231
  */
206
232
  export declare function createFailingPackageZip(tempDir: string, name: string, version: string): Promise<string>;
233
+ /**
234
+ * Create a package whose task runs a command, which fails.
235
+ *
236
+ * Creates a package with:
237
+ * - Input: "value" (String, default "test")
238
+ * - Task: "command" - a custom task whose command is `exit 1`
239
+ *
240
+ * The suites' one command task. A server that runs commands records it
241
+ * `failed`, exit code 1; one that runs none records it `error`, saying it runs
242
+ * no commands (`TestConfig.commands`).
243
+ *
244
+ * @param tempDir - Directory to write the zip file
245
+ * @param name - Package name
246
+ * @param version - Package version
247
+ * @returns Path to the created zip file
248
+ */
249
+ export declare function createCommandPackageZip(tempDir: string, name: string, version: string): Promise<string>;
207
250
  /**
208
251
  * Create a package with a slow task for testing concurrency/cancellation.
209
252
  *
@@ -226,10 +269,12 @@ export declare function createSlowPackageZip(tempDir: string, name: string, vers
226
269
  * - Input: "b" (Integer, default 4)
227
270
  * - Task: "succeed_a" - returns a + b (succeeds)
228
271
  * - Task: "succeed_b" - returns a * b (succeeds)
229
- * - Task: "fail_c" - exits with code 1 (always fails)
272
+ * - Task: "fail_c" - fails in East as it runs, with the message "fail_c fails,
273
+ * given 3" (always fails)
230
274
  *
231
275
  * All tasks are independent — dispatched in the same Map iteration.
232
- * Stresses apply-results serialization with mixed success/failure.
276
+ * Stresses apply-results serialization with mixed success/failure. Every task
277
+ * is East, so every server runs them.
233
278
  *
234
279
  * @param tempDir - Directory to write the zip file
235
280
  * @param name - Package name
@@ -244,10 +289,12 @@ export declare function createParallelMixedPackageZip(tempDir: string, name: str
244
289
  * - Input: "a" (Integer, default 10)
245
290
  * - Input: "b" (Integer, default 5)
246
291
  * - Task: "left" - returns a + b (succeeds)
247
- * - Task: "right" - exits with code 1 (always fails)
292
+ * - Task: "right" - fails in East as it runs, with the message "right fails,
293
+ * given 10" (always fails)
248
294
  * - Task: "merge" - depends on left.output + right.output (should be skipped)
249
295
  *
250
296
  * Tests that merge is properly skipped and the dataflow completes without stalling.
297
+ * Every task is East, so every server runs them.
251
298
  *
252
299
  * @param tempDir - Directory to write the zip file
253
300
  * @param name - Package name
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/fixtures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/fixtures.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ import { mkdirSync } from 'node:fs';
12
12
  import { join } from 'node:path';
13
13
  import e3 from '@elaraai/e3';
14
14
  import { ArrayType, DictType, FunctionType, IntegerType, NullType, StringType, StructType, East, variant } from '@elaraai/east';
15
- import { Time } from '@elaraai/east-node-std';
15
+ import { Console, Time } from '@elaraai/east-node-std';
16
16
  /**
17
17
  * Create a simple compute package for testing.
18
18
  *
@@ -313,12 +313,53 @@ export async function createDiamondPackageZip(tempDir, name, version) {
313
313
  await e3.export(pkg, zipPath);
314
314
  return zipPath;
315
315
  }
316
+ /**
317
+ * Create a package whose task writes known lines to its stdout.
318
+ *
319
+ * Creates a package with:
320
+ * - Input: "lines" (Integer, default 3)
321
+ * - Task: "log" - writes `line 0` … `line <lines - 1>` to stdout, a line
322
+ * each, and returns how many it wrote
323
+ *
324
+ * With the default input its stdout log is {@link LOGGED_LINES}, every
325
+ * server's alike, which a read of the log by offset and limit is checked
326
+ * against.
327
+ *
328
+ * @param tempDir - Directory to write the zip file
329
+ * @param name - Package name
330
+ * @param version - Package version
331
+ * @returns Path to the created zip file
332
+ */
333
+ export async function createLoggingPackageZip(tempDir, name, version) {
334
+ mkdirSync(tempDir, { recursive: true });
335
+ const lines = e3.input('lines', IntegerType, variant('value', 3n));
336
+ const task = e3.task('log', [lines], East.function([IntegerType], IntegerType, ($, n) => {
337
+ const i = $.let(0n);
338
+ $.while(East.less(i, n), ($) => {
339
+ $(Console.log(East.str `line ${i}`));
340
+ $.assign(i, i.add(1n));
341
+ });
342
+ return n;
343
+ }));
344
+ const pkg = e3.package(name, version, task);
345
+ const zipPath = join(tempDir, `${name}-${version}.zip`);
346
+ await e3.export(pkg, zipPath);
347
+ return zipPath;
348
+ }
349
+ /** The stdout log of {@link createLoggingPackageZip}'s task, run on its
350
+ * default input. */
351
+ export const LOGGED_LINES = 'line 0\nline 1\nline 2\n';
316
352
  /**
317
353
  * Create a package with a task that always fails.
318
354
  *
319
355
  * Creates a package with:
320
356
  * - Input: "value" (String, default "test")
321
- * - Task: "failing" - exits with code 1
357
+ * - Task: "failing" - fails in East as it runs, with the message "failing
358
+ * fails, given test"
359
+ *
360
+ * The failure is the East body's own, so every server runs it, one that runs
361
+ * no commands included. A server records it as the runner protocol does: the
362
+ * task `failed`, exit code 1, with the message in its stderr log.
322
363
  *
323
364
  * @param tempDir - Directory to write the zip file
324
365
  * @param name - Package name
@@ -328,7 +369,32 @@ export async function createDiamondPackageZip(tempDir, name, version) {
328
369
  export async function createFailingPackageZip(tempDir, name, version) {
329
370
  mkdirSync(tempDir, { recursive: true });
330
371
  const input = e3.input('value', StringType, variant('value', 'test'));
331
- const task = e3.customTask('failing', [input], StringType, ($, _inputs, _output) => East.str `exit 1`);
372
+ const task = e3.task('failing', [input], East.function([StringType], StringType, ($, value) => $.error(East.str `failing fails, given ${value}`)));
373
+ const pkg = e3.package(name, version, task);
374
+ const zipPath = join(tempDir, `${name}-${version}.zip`);
375
+ await e3.export(pkg, zipPath);
376
+ return zipPath;
377
+ }
378
+ /**
379
+ * Create a package whose task runs a command, which fails.
380
+ *
381
+ * Creates a package with:
382
+ * - Input: "value" (String, default "test")
383
+ * - Task: "command" - a custom task whose command is `exit 1`
384
+ *
385
+ * The suites' one command task. A server that runs commands records it
386
+ * `failed`, exit code 1; one that runs none records it `error`, saying it runs
387
+ * no commands (`TestConfig.commands`).
388
+ *
389
+ * @param tempDir - Directory to write the zip file
390
+ * @param name - Package name
391
+ * @param version - Package version
392
+ * @returns Path to the created zip file
393
+ */
394
+ export async function createCommandPackageZip(tempDir, name, version) {
395
+ mkdirSync(tempDir, { recursive: true });
396
+ const input = e3.input('value', StringType, variant('value', 'test'));
397
+ const task = e3.customTask('command', [input], StringType, ($, _inputs, _output) => East.str `exit 1`);
332
398
  const pkg = e3.package(name, version, task);
333
399
  const zipPath = join(tempDir, `${name}-${version}.zip`);
334
400
  await e3.export(pkg, zipPath);
@@ -367,10 +433,12 @@ export async function createSlowPackageZip(tempDir, name, version, sleepSeconds
367
433
  * - Input: "b" (Integer, default 4)
368
434
  * - Task: "succeed_a" - returns a + b (succeeds)
369
435
  * - Task: "succeed_b" - returns a * b (succeeds)
370
- * - Task: "fail_c" - exits with code 1 (always fails)
436
+ * - Task: "fail_c" - fails in East as it runs, with the message "fail_c fails,
437
+ * given 3" (always fails)
371
438
  *
372
439
  * All tasks are independent — dispatched in the same Map iteration.
373
- * Stresses apply-results serialization with mixed success/failure.
440
+ * Stresses apply-results serialization with mixed success/failure. Every task
441
+ * is East, so every server runs them.
374
442
  *
375
443
  * @param tempDir - Directory to write the zip file
376
444
  * @param name - Package name
@@ -383,7 +451,7 @@ export async function createParallelMixedPackageZip(tempDir, name, version) {
383
451
  const inputB = e3.input('b', IntegerType, variant('value', 4n));
384
452
  const succeedA = e3.task('succeed_a', [inputA, inputB], East.function([IntegerType, IntegerType], IntegerType, ($, a, b) => a.add(b)));
385
453
  const succeedB = e3.task('succeed_b', [inputA, inputB], East.function([IntegerType, IntegerType], IntegerType, ($, a, b) => a.multiply(b)));
386
- const failC = e3.customTask('fail_c', [inputA], StringType, ($, _inputs, _output) => East.str `exit 1`);
454
+ const failC = e3.task('fail_c', [inputA], East.function([IntegerType], StringType, ($, a) => $.error(East.str `fail_c fails, given ${a}`)));
387
455
  const pkg = e3.package(name, version, succeedA, succeedB, failC);
388
456
  const zipPath = join(tempDir, `${name}-${version}.zip`);
389
457
  await e3.export(pkg, zipPath);
@@ -396,10 +464,12 @@ export async function createParallelMixedPackageZip(tempDir, name, version) {
396
464
  * - Input: "a" (Integer, default 10)
397
465
  * - Input: "b" (Integer, default 5)
398
466
  * - Task: "left" - returns a + b (succeeds)
399
- * - Task: "right" - exits with code 1 (always fails)
467
+ * - Task: "right" - fails in East as it runs, with the message "right fails,
468
+ * given 10" (always fails)
400
469
  * - Task: "merge" - depends on left.output + right.output (should be skipped)
401
470
  *
402
471
  * Tests that merge is properly skipped and the dataflow completes without stalling.
472
+ * Every task is East, so every server runs them.
403
473
  *
404
474
  * @param tempDir - Directory to write the zip file
405
475
  * @param name - Package name
@@ -411,7 +481,7 @@ export async function createFailingDiamondPackageZip(tempDir, name, version) {
411
481
  const inputA = e3.input('a', IntegerType, variant('value', 10n));
412
482
  const inputB = e3.input('b', IntegerType, variant('value', 5n));
413
483
  const leftTask = e3.task('left', [inputA, inputB], East.function([IntegerType, IntegerType], IntegerType, ($, a, b) => a.add(b)));
414
- const rightTask = e3.customTask('right', [inputA], IntegerType, ($, _inputs, _output) => East.str `exit 1`);
484
+ const rightTask = e3.task('right', [inputA], East.function([IntegerType], IntegerType, ($, a) => $.error(East.str `right fails, given ${a}`)));
415
485
  const mergeTask = e3.task('merge', [leftTask.output, rightTask.output], East.function([IntegerType, IntegerType], IntegerType, ($, a, b) => a.add(b)));
416
486
  const pkg = e3.package(name, version, mergeTask);
417
487
  const zipPath = join(tempDir, `${name}-${version}.zip`);