Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
],
"version": "0.3.2-alpha.3",
"publisher": "latticenet",
"signature_ed25519": "cGr0AcT5LYLuaYxNIYfwL4jWZtYA04wgGjkhJGkbrk49uBDDqcKcIBT132BfJhhoNlKlb6+n8mokEDQJuAf5Cw==",
"signature_ed25519": "YW8Lzw9MqK7M0PzM5viOuJP4BiujmMHqGOJrIPdDd549zjrG9qIF0UVOsBlTNnnmtPltdDCeE57LQs/3RDQtAA==",
"bundle": {
"format": "tar+gzip",
"digest_sha256": "8e6445836caf38fc7c58582601a98faf6b756587535c2c7e355e97a99de5756f"
Expand Down Expand Up @@ -86,7 +86,8 @@
"base_url"
]
}
]
],
"backing": "runtime"
}
]
}
111 changes: 111 additions & 0 deletions system-go/conformance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package main

import (
"encoding/json"
"os"
"strings"
"testing"
)

// A manifest declares which methods a plugin exposes and — since `backing` — who
// actually serves each one. This test holds the artifact to that promise.
//
// It exists because the promise used to go unchecked. Official plugins shipped signed
// manifests declaring interface methods their own artifacts could not answer, and
// lattice-server quietly answered them from an in-core handler instead. Nothing caught
// it: every suite covered what the artifact DOES, never what the manifest CLAIMS. A
// contract nobody verifies is a contract that drifts, and this is the gate that turns
// that drift into a red build.
//
// Sub-Store is genuinely runtime-backed: its own artifact serves every method it
// declares. This test is what keeps that true.
func TestManifestInterfacesAreServedAsDeclared(t *testing.T) {
for _, iface := range loadManifestInterfaces(t) {
for _, method := range iface.Methods {
// An empty payload is rejected before any host call is attempted, so probing
// the dispatcher cannot reach the broker or the network. The stub host proves
// it: it fails the test if anything tries to call out.
rt := &runtime{host: refuseHostCalls{t}}
payload, err := json.Marshal(map[string]any{
"service": iface.Service,
"method": method.Name,
"payload": map[string]any{},
})
if err != nil {
t.Fatalf("marshal call payload: %v", err)
}
resp := rt.handle(request{Action: "call", Payload: payload})
served := !refusedAsUnknown(resp)

switch iface.Backing {
case "runtime":
// This artifact is the declared owner, so it must at least recognise the
// method. Rejecting an empty payload is a real answer; not knowing the
// method at all is a broken promise.
if !served {
t.Errorf("%s/%s is declared runtime-backed, but this artifact does not serve it: %s",
iface.Service, method.Name, resp.Error)
}
case "core":
// The engine would live in lattice-server. If the artifact answers as well,
// the manifest names two owners for one method and the host has to guess.
if served {
t.Errorf("%s/%s is declared core-backed, but this artifact answers it too; backing must name exactly one owner",
iface.Service, method.Name)
}
case "":
t.Errorf("%s/%s declares no backing, so who serves it is left to inference",
iface.Service, method.Name)
default:
t.Errorf("%s/%s declares unknown backing %q", iface.Service, method.Name, iface.Backing)
}
}
}
}

// refuseHostCalls fails the test if the dispatcher reaches for the host. Probing which
// methods exist must never have a side effect.
type refuseHostCalls struct{ t *testing.T }

func (h refuseHostCalls) call(method string, _ any) (json.RawMessage, error) {
h.t.Fatalf("conformance probe must not reach the host, but it called %q", method)
return nil, nil
}

// refusedAsUnknown separates "I do not implement this" from "I implement this and your
// payload is wrong". Only the former means the artifact cannot serve the method — a
// validation error proves the method is wired up.
func refusedAsUnknown(resp response) bool {
if resp.OK {
return false
}
return strings.Contains(resp.Error, "unsupported action") ||
strings.Contains(resp.Error, "unsupported service") ||
strings.Contains(resp.Error, "unsupported method")
}

type manifestInterface struct {
Service string `json:"service"`
Backing string `json:"backing"`
Methods []struct {
Name string `json:"name"`
} `json:"methods"`
}

func loadManifestInterfaces(t *testing.T) []manifestInterface {
t.Helper()
raw, err := os.ReadFile("../manifest.json")
if err != nil {
t.Fatalf("read manifest: %v", err)
}
var m struct {
Interfaces []manifestInterface `json:"interfaces"`
}
if err := json.Unmarshal(raw, &m); err != nil {
t.Fatalf("parse manifest: %v", err)
}
if len(m.Interfaces) == 0 {
t.Fatal("manifest declares no interfaces to verify")
}
return m.Interfaces
}