Skip the Node build module's toolchain tests by name where no Node toolchain is installed, instead of installing one from the registry in a level that has no network; merge three tests that share one fixture
mesh/delivery merged: source.main moved to novox/mesh-catalog@f96704fa0ff4
mesh/check checking a01715ddf508 on 565d0a848a85
mesh/delivery merged: source.main moved to novox/mesh-catalog@f96704fa0ff4
mesh/check checking a01715ddf508 on 565d0a848a85
On ace, which holds no Node build module, five integration tests each spent 70 s in npm's network retries and failed every mesh-catalog check run there (five verdicts since 00:07). The tests now copy the node's installed toolchain or are skipped as NOT RUN; the registry is never reached. Three tests sharing the fixture are one, so the toolchain is copied three times instead of five (10 integration tests in the module, now 8).
This commit is contained in:
@@ -17,11 +17,11 @@ import (
|
||||
"git.novox.be/novox/mesh-sdk/go/forgekey"
|
||||
)
|
||||
|
||||
// realMachine gives the tests the real toolchain of the module's own lock and makes two workspaces holding one fixture
|
||||
// bundle. The toolchain is the one this node's installed Node build module keeps (ADR 0533 §1): the integration level
|
||||
// is given its toolchains read-only and no network, so it is copied into the test's own cache from there. Only where
|
||||
// no toolchain is installed (a desk) is it installed with `npm ci --ignore-scripts` from the mesh's registry, as the
|
||||
// module does, which needs the network.
|
||||
// realMachine gives the tests the real toolchain of the module's own lock and makes three workspaces holding one fixture
|
||||
// bundle. The toolchain is the one this node's installed Node build module keeps (ADR 0533 §1), copied into the test's
|
||||
// own cache: the integration level is given its toolchains read-only and no network, so it is never installed from the
|
||||
// registry here. Where no Node build module has installed one (a node without it, a desk), the test is skipped by
|
||||
// name: an install from the public registry inside a shut-off level only fails, after 70 s of npm's retries.
|
||||
func realMachine(t *testing.T) (*Module, string) {
|
||||
t.Helper()
|
||||
for _, p := range []string{"node", "npm", "bwrap"} { // bwrap: tsc, esbuild and the scripts run shut off (1309)
|
||||
@@ -44,16 +44,19 @@ func realMachine(t *testing.T) (*Module, string) {
|
||||
run := forgekey.ExecRunnerFor(0)
|
||||
m := &Module{Node: "ace", Recipe: lock, Work: work, Run: run, Ctx: context.Background(),
|
||||
Toolchain: &Toolchain{Paths: Paths{Home: home, Cache: cache}, Run: run, Registry: func() (Registry, error) {
|
||||
return Registry{URL: "https://git.novox.be/api/packages/novox/npm/"}, nil
|
||||
return Registry{}, fmt.Errorf("the integration test installs no toolchain from a registry: it has no network")
|
||||
}}}
|
||||
withStore(t, m)
|
||||
if from := installedToolchain(t, filepath.Join(CacheDir, "toolchain"), filepath.Join(home, "toolchain", "package-lock.json")); from != "" {
|
||||
copyToolchain(t, from, m.Toolchain.Paths.Dir(m.Recipe.Version()))
|
||||
from := installedToolchain(t, filepath.Join(CacheDir, "toolchain"), filepath.Join(home, "toolchain", "package-lock.json"))
|
||||
if from == "" {
|
||||
t.Skipf("NOT RUN: no Node toolchain is installed under %s for this account to read (no Node build module on this node); "+
|
||||
"the integration level has no network to install one, so this runs on a node that holds the Node build module", filepath.Join(CacheDir, "toolchain"))
|
||||
}
|
||||
if err := m.Toolchain.Ensure(context.Background(), m.Recipe.Version()); err != nil {
|
||||
t.Fatalf("no toolchain of this lock is installed under %s, and installing it from the registry failed: %v", filepath.Join(CacheDir, "toolchain"), err)
|
||||
copyToolchain(t, from, m.Toolchain.Paths.Dir(m.Recipe.Version()))
|
||||
if err := m.Toolchain.Ensure(context.Background(), m.Recipe.Version()); err != nil { // present: opens it, installs nothing
|
||||
t.Fatalf("the toolchain copied from %s cannot be used: %v", from, err)
|
||||
}
|
||||
for _, id := range []string{"w1", "w2"} {
|
||||
for _, id := range []string{"w1", "w2", "w3"} {
|
||||
for p, body := range map[string]string{
|
||||
"modules/m/module.json": `{"module":"m","build":{"artifacts":[{"name":"tools","kind":"bundle","language":"typescript","entrypoints":["tools/index.js"]}]}}`,
|
||||
"modules/m/package.json": `{"name":"m","type":"module","scripts":{"test":"node -e \"process.exit(0)\""}}`,
|
||||
@@ -65,10 +68,36 @@ func realMachine(t *testing.T) (*Module, string) {
|
||||
return m, work
|
||||
}
|
||||
|
||||
// 1490/AC2: a fixture TypeScript bundle importing @novox/mesh-sdk, built twice by the real tsc and esbuild, has equal
|
||||
// digests, and its archive holds the bundled .js, the .serve.mjs launcher and package.json.
|
||||
func TestAFixtureBundleBuiltTwiceHasOneDigest(t *testing.T) {
|
||||
// 1490/AC2, 1491 and issue 1869, in one test so the toolchain is copied once: the real type-check and test script of the
|
||||
// fixture pass the unit level; a package whose test imports its own build output (as mesh-sdk's do) passes the unit level,
|
||||
// the test step emitting it with the real tsc, shut off, before the test script runs; and the fixture TypeScript bundle
|
||||
// importing @novox/mesh-sdk, built twice by the real tsc and esbuild, has equal digests, its archive holding the bundled
|
||||
// .js, the .serve.mjs launcher and package.json. The unit levels run in w3, so the two builds' workspaces stay alike.
|
||||
func TestTheFixturePassesTheUnitLevelAndBuildsTwiceToOneDigest(t *testing.T) {
|
||||
m, work := realMachine(t)
|
||||
out, err := m.test(context.Background(), map[string]any{"workspace": "w3", "module": "modules/m", "level": "unit"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r := out.(*TestResult); !r.Passed || r.NoTests || len(r.Ran) != 2 {
|
||||
t.Errorf("the fixture's unit level: result = %+v", r)
|
||||
}
|
||||
for p, body := range map[string]string{
|
||||
"modules/p/package.json": `{"name":"p","type":"module","scripts":{"build":"tsc","test":"node --test test/a.test.mjs","prepare":"tsc"}}`,
|
||||
"modules/p/tsconfig.json": `{"compilerOptions":{"module":"NodeNext","moduleResolution":"NodeNext","target":"ES2022","outDir":"dist","rootDir":"src"},"include":["src"]}`,
|
||||
"modules/p/src/index.ts": "export const answer: number = 42;\n",
|
||||
"modules/p/test/a.test.mjs": "import { test } from 'node:test';\nimport assert from 'node:assert';\nimport { answer } from '../dist/index.js';\n" +
|
||||
"test('the build is there', () => assert.equal(answer, 42));\n",
|
||||
} {
|
||||
write(t, filepath.Join(work, "w3", "tree", filepath.FromSlash(p)), body, 0o644)
|
||||
}
|
||||
out, err = m.test(context.Background(), map[string]any{"workspace": "w3", "module": "modules/p", "level": "unit"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r := out.(*TestResult); !r.Passed || !slices.Equal(r.Ran, []string{"build", "test"}) {
|
||||
t.Errorf("the package importing its build: result = %+v", r)
|
||||
}
|
||||
var digests []string
|
||||
for _, id := range []string{"w1", "w2"} {
|
||||
out, err := m.build(context.Background(), map[string]any{"workspace": id, "module": "modules/m", "artifact": "tools"})
|
||||
@@ -89,43 +118,6 @@ func TestAFixtureBundleBuiltTwiceHasOneDigest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 1491: the real type-check and test script of the same fixture pass the unit level.
|
||||
func TestTheFixturePassesTheUnitLevel(t *testing.T) {
|
||||
m, _ := realMachine(t)
|
||||
out, err := m.test(context.Background(), map[string]any{"workspace": "w1", "module": "modules/m", "level": "unit"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r := out.(*TestResult); !r.Passed || r.NoTests || len(r.Ran) != 2 {
|
||||
t.Errorf("result = %+v", r)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 1869: a package whose test imports its own build output (as mesh-sdk's do) passes the unit level: the test step
|
||||
// emits it with the real tsc, shut off, before the test script runs.
|
||||
func TestAPackageWhoseTestsImportItsBuildPassesTheUnitLevel(t *testing.T) {
|
||||
if _, err := exec.LookPath("bwrap"); err != nil {
|
||||
t.Skip("NOT RUN: no bubblewrap installed where this check runs; every build node has it (the module declares it)")
|
||||
}
|
||||
m, work := realMachine(t)
|
||||
for p, body := range map[string]string{
|
||||
"modules/p/package.json": `{"name":"p","type":"module","scripts":{"build":"tsc","test":"node --test test/a.test.mjs","prepare":"tsc"}}`,
|
||||
"modules/p/tsconfig.json": `{"compilerOptions":{"module":"NodeNext","moduleResolution":"NodeNext","target":"ES2022","outDir":"dist","rootDir":"src"},"include":["src"]}`,
|
||||
"modules/p/src/index.ts": "export const answer: number = 42;\n",
|
||||
"modules/p/test/a.test.mjs": "import { test } from 'node:test';\nimport assert from 'node:assert';\nimport { answer } from '../dist/index.js';\n" +
|
||||
"test('the build is there', () => assert.equal(answer, 42));\n",
|
||||
} {
|
||||
write(t, filepath.Join(work, "w1", "tree", filepath.FromSlash(p)), body, 0o644)
|
||||
}
|
||||
out, err := m.test(context.Background(), map[string]any{"workspace": "w1", "module": "modules/p", "level": "unit"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r := out.(*TestResult); !r.Passed || !slices.Equal(r.Ran, []string{"build", "test"}) {
|
||||
t.Errorf("result = %+v", r)
|
||||
}
|
||||
}
|
||||
|
||||
// installedToolchain is the toolchain directory under toolchains that this node's Node build module installed: the
|
||||
// one installed from the lock at lockPath, byte for byte, or, when the change carries a lock no delivered release has
|
||||
// installed yet, the one installed last, said in the test's log (ADR 0533 §3: a new lock is proven by the module that
|
||||
|
||||
Reference in New Issue
Block a user