Delete merge-check.sh; tests that launch bundles skip with their reason (issue 1295, S2; ADR 0529)
The checker runs node-tools' Go level and its npm test; what the script said was NOT TESTED HERE is a skip naming the missing node or @novox/mesh-sdk.
This commit is contained in:
@@ -39,6 +39,7 @@ func call(t *testing.T, endpoint, tool string, args map[string]any) (string, boo
|
||||
// novox/hq ADR 0195 and ADR 0367: the console announces seven tools, and everything the mesh answers is reached
|
||||
// through them by one address per layer.
|
||||
func TestTheMeshsToolsAreFoundByAddress(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
was := IndexKept
|
||||
IndexKept = 0 // every discovery asks the mesh, so a module arriving mid-test is found
|
||||
t.Cleanup(func() { IndexKept = was })
|
||||
|
||||
@@ -42,6 +42,7 @@ func post(t *testing.T, endpoint string, body string) map[string]any {
|
||||
// As node-tools, the runtime serves the bundles and is the console on loopback: the listing is what
|
||||
// the modules and the mesh's records answered, and a call reaches the module on the machine named.
|
||||
func TestTheConsoleListsAndCallsOverHTTP(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
mesh.Issue(t, mt.MembershipOf("alpha", "desk", true, nil))
|
||||
mesh.Issue(t, mt.MembershipOf("beta", "desk", false, map[string][]string{"node-shelf": {"list", "clear"}}))
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package meshtest
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// bundlesWhy returns the reason bundles cannot be launched from a checkout rooted at root, or "" when they can: the
|
||||
// TypeScript and Python bundles the runtime and the console launch need node and the package
|
||||
// @novox/mesh-sdk, which comes from the package registry and is installed beside node-tools/package.json
|
||||
// (novox/hq ADR 0529 clause 1: what merge-check.sh said "NOT TESTED HERE" about is a skip with its reason).
|
||||
func bundlesWhy(root string, haveNode bool) string {
|
||||
if !haveNode {
|
||||
return "node is not installed"
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(root, "node_modules", "@novox", "mesh-sdk")); err != nil {
|
||||
return "@novox/mesh-sdk is not installed in " + filepath.Join(root, "node_modules")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// NeedBundles skips the test, saying why, where the bundles it launches cannot run here.
|
||||
func NeedBundles(t *testing.T) {
|
||||
t.Helper()
|
||||
_, err := exec.LookPath("node")
|
||||
if why := bundlesWhy(moduleRoot(), err == nil); why != "" {
|
||||
t.Skip("NOT TESTED HERE: this test launches bundles, and " + why)
|
||||
}
|
||||
}
|
||||
|
||||
// moduleRoot is node-tools/, where package.json and node_modules are.
|
||||
func moduleRoot() string {
|
||||
_, here, _, _ := runtime.Caller(0)
|
||||
return filepath.Join(filepath.Dir(here), "..", "..")
|
||||
}
|
||||
@@ -73,3 +73,20 @@ func TestEachTestHasABusOfItsOwn(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// What merge-check.sh said was "NOT TESTED HERE" is a skip with its reason: no node, or no package, each says so.
|
||||
func TestBundlesCannotBeLaunchedWithoutNodeOrTheSDKAndTheSkipSaysWhy(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
if why := bundlesWhy(root, false); !strings.Contains(why, "node is not installed") {
|
||||
t.Errorf("no node said %q", why)
|
||||
}
|
||||
if why := bundlesWhy(root, true); !strings.Contains(why, "@novox/mesh-sdk") {
|
||||
t.Errorf("no package said %q", why)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(root, "node_modules", "@novox", "mesh-sdk"), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if why := bundlesWhy(root, true); why != "" {
|
||||
t.Errorf("node and the package present said %q", why)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
// read here with NATS's own types, each endpoint a subject actually served — and the announcement
|
||||
// follows a re-issued membership.
|
||||
func TestTheRuntimeAnnouncesWhatItServesInTheServicesProtocol(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
mesh.Issue(t, mt.MembershipOf("alpha", "anchor", false, nil))
|
||||
mesh.Issue(t, mt.MembershipOf("beta", "anchor", false, map[string][]string{"node-shelf": {"list", "clear"}}))
|
||||
|
||||
@@ -50,6 +50,7 @@ func countLines(t *testing.T, path, want string) int {
|
||||
// is its bus — it binds the module's own consumer, hands each event to the bundle, and acknowledges it
|
||||
// only when the bundle has taken it; one the bundle failed or died on is offered again.
|
||||
func TestTheRuntimeHandsAModulesEventsToItsBundleAndAcknowledgesThemOnlyWhenTaken(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
restore := bus.NakDelay
|
||||
bus.NakDelay = 300 * time.Millisecond
|
||||
@@ -128,6 +129,7 @@ func TestTheRuntimeHandsAModulesEventsToItsBundleAndAcknowledgesThemOnlyWhenTake
|
||||
|
||||
// A long-running bundle that exits is started again, without waiting for a call (ADR 0198).
|
||||
func TestALongRunningBundleThatExitsIsStartedAgain(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
firstPause := launch.RestartFirst
|
||||
launch.RestartFirst = 100 * time.Millisecond
|
||||
|
||||
@@ -46,6 +46,7 @@ func same(t *testing.T, got, want string) {
|
||||
// The node's runtime serves five modules' bundles on one credential — two TypeScript, one broken,
|
||||
// one Python, one written against the protocol — and follows a re-issued membership (ADR 0175, 0193).
|
||||
func TestTheNodesRuntimeServesFiveModulesAndFollowsAReissuedMembership(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
mesh.Issue(t, mt.MembershipOf("alpha", "anchor", true, nil))
|
||||
mesh.Issue(t, mt.MembershipOf("beta", "anchor", false, map[string][]string{"node-shelf": {"list", "clear"}}))
|
||||
@@ -152,6 +153,7 @@ func TestTheNodesRuntimeServesFiveModulesAndFollowsAReissuedMembership(t *testin
|
||||
// Each bundle is given its own environment and none of another's (ADR 0192), and the composed
|
||||
// environments are not left in the runtime's.
|
||||
func TestEachBundleIsGivenItsOwnEnvironment(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
for _, m := range []string{"gamma", "delta", "zeta"} {
|
||||
mesh.Issue(t, mt.MembershipOf(m, "anchor", false, nil))
|
||||
@@ -192,6 +194,7 @@ func TestEachBundleIsGivenItsOwnEnvironment(t *testing.T) {
|
||||
|
||||
// An entrypoint that is not executable is refused by name, and the others serve (ADR 0193).
|
||||
func TestAnEntrypointThatIsNotExecutableIsRefused(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
mesh.Issue(t, mt.MembershipOf("alpha", "anchor", false, nil))
|
||||
mesh.Issue(t, mt.MembershipOf("plain", "anchor", false, nil))
|
||||
@@ -218,6 +221,7 @@ func TestAnEntrypointThatIsNotExecutableIsRefused(t *testing.T) {
|
||||
|
||||
// A launched bundle is told the module it serves, so its seat's verbs stay the seat's (ADR 0193).
|
||||
func TestALaunchedBundleRegisteringItsSeatFirstServesTheSeat(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
mesh.Issue(t, mt.MembershipOf("theta", "anchor", false, map[string][]string{"node-shelf": {"list"}}))
|
||||
nodeTools := connect(t, "node-tools", "anchor")
|
||||
|
||||
@@ -139,6 +139,7 @@ func waitFor(t *testing.T, path, line string) {
|
||||
// The TypeScript SDK against the runtime (ADR 0201): two watches of one state, each handed only its
|
||||
// own changes, the current values handled before the module's import goes on.
|
||||
func TestTheSDKsStateReachesTheRuntime(t *testing.T) {
|
||||
mt.NeedBundles(t)
|
||||
mesh := mt.New(t)
|
||||
kv := mesh.Bucket(t, "sdkkeeper_servers")
|
||||
if _, err := kv.Put("all.one", []byte(`{"url":"http://one"}`)); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user