asus-zephyrus-g14's g14 is the model in adopted paths, so the module declares it in particulars and it is no finding there only. The forge rule hid a node after a word's @ (database@novox/postgres) and any novox/<x>; now only git.novox.be/novox/<repo>, novox/hq ADR|issue|design|to-be|research and the npm scope are blanked (1838/AC2). merge-check.sh's comment no longer names the removed covered list.
268 lines
9.3 KiB
Go
268 lines
9.3 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
var names = []string{"novox", "ace", "shanks", "g14"}
|
|
|
|
func TestANodeNameIsRefusedWhereItIsWritten(t *testing.T) {
|
|
cases := map[string]struct{ file, src string }{
|
|
"manifest string": {"modules/kernel/module.json", "{\n \"description\": \"as on Shanks\"\n}\n"},
|
|
"file line": {"modules/kernel/files/boot.sh", "#!/bin/sh\necho run on g14\n"},
|
|
"go identifier": {"modules/kernel/cmd/x/a.go", "package main\n\nfunc novox() {}\n"},
|
|
"test name": {"modules/kernel/cmd/x/a_test.go", "package main\n\nfunc TestAce(t *testing.T) {}\n\nfunc TestOnAce_x(t *testing.T) {}\n"},
|
|
}
|
|
for name, c := range cases {
|
|
if got := scan(c.file, c.src, names); len(got) == 0 {
|
|
t.Errorf("%s: %q not refused", name, c.src)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTheFindingNamesTheLineAndTheWord(t *testing.T) {
|
|
got := scan("f.sh", "a\nb\nrun on ACE now\n", names)
|
|
if len(got) != 1 || !strings.HasPrefix(got[0], "f.sh:3:") || !strings.Contains(got[0], "ace") {
|
|
t.Errorf("got %v", got)
|
|
}
|
|
}
|
|
|
|
func TestTheForgeIsNotANodeName(t *testing.T) {
|
|
for _, s := range []string{
|
|
"see novox/hq issue 5",
|
|
"module git.novox.be/novox/mesh-sdk/go v1.2.3",
|
|
"https://git.novox.be/novox/mesh-catalog",
|
|
"space trace surface grace g14x",
|
|
} {
|
|
if got := scan("f", s, names); len(got) != 0 {
|
|
t.Errorf("%q refused: %v", s, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestANodeNameInAPathOrJoinedIsRefused(t *testing.T) {
|
|
for _, s := range []string{
|
|
"modules/kernel/testdata/novox/meminfo",
|
|
"/srv/novox/data",
|
|
"testdata/shanks-meminfo.txt",
|
|
"on-shanks",
|
|
"shanks-desktop",
|
|
"mesh-novox",
|
|
"func novoxTree() {}",
|
|
"aceFiles := 1",
|
|
"g14Meminfo := 2",
|
|
"novox_tree := 3",
|
|
} {
|
|
if got := scan("f", s, names); len(got) == 0 {
|
|
t.Errorf("%q not refused", s)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestANodeNamedPathIsRefusedThroughRun(t *testing.T) {
|
|
root := t.TempDir()
|
|
p := filepath.Join(root, "modules/kernel/testdata/ace/x")
|
|
os.MkdirAll(filepath.Dir(p), 0o755)
|
|
os.WriteFile(p, []byte("clean\n"), 0o644)
|
|
got, err := run(root, names, []string{"kernel"}, nil)
|
|
if err != nil || len(got) != 1 || !strings.HasPrefix(got[0], "modules/kernel/testdata/ace/x:0: ") {
|
|
t.Errorf("got %v, %v", got, err)
|
|
}
|
|
}
|
|
|
|
func TestCheckReturnsOneOnAFindingAndTwoOnAnUnreadableList(t *testing.T) {
|
|
root := t.TempDir()
|
|
write := func(p, s string) {
|
|
p = filepath.Join(root, p)
|
|
os.MkdirAll(filepath.Dir(p), 0o755)
|
|
os.WriteFile(p, []byte(s), 0o644)
|
|
}
|
|
write("particulars", "ace\n")
|
|
write("modules/kernel/a", "clean\n")
|
|
if got := check(root); got != 0 {
|
|
t.Errorf("clean = %d, want 0", got)
|
|
}
|
|
write("modules/kernel/a", "on ace\n")
|
|
if got := check(root); got != 1 {
|
|
t.Errorf("finding = %d, want 1", got)
|
|
}
|
|
os.Remove(filepath.Join(root, "particulars"))
|
|
if got := check(root); got != 2 {
|
|
t.Errorf("no list = %d, want 2", got)
|
|
}
|
|
}
|
|
|
|
func TestRunReadsOnlyTheModulesItIsGiven(t *testing.T) {
|
|
root := t.TempDir()
|
|
write := func(p, s string) {
|
|
p = filepath.Join(root, p)
|
|
os.MkdirAll(filepath.Dir(p), 0o755)
|
|
os.WriteFile(p, []byte(s), 0o644)
|
|
}
|
|
write("modules/kernel/files/a", "on novox\n")
|
|
write("modules/other/files/a", "on novox\n")
|
|
got, err := run(root, names, []string{"kernel"}, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got) != 1 || !strings.Contains(got[0], "modules/kernel/files/a:1") {
|
|
t.Errorf("got %v", got)
|
|
}
|
|
}
|
|
|
|
// 1838/AC1: the check reads every directory under modules/ and no list of covered modules, so a module is
|
|
// covered from its first commit.
|
|
func TestEveryModuleIsReadWithoutAList(t *testing.T) {
|
|
root := t.TempDir()
|
|
write := func(p, s string) {
|
|
p = filepath.Join(root, p)
|
|
os.MkdirAll(filepath.Dir(p), 0o755)
|
|
os.WriteFile(p, []byte(s), 0o644)
|
|
}
|
|
write("particulars", "novox\n")
|
|
write("modules/kernel/files/a", "clean\n")
|
|
if got := check(root); got != 0 {
|
|
t.Errorf("clean, no covered list = %d, want 0", got)
|
|
}
|
|
write("modules/new-module/files/a", "on novox\n")
|
|
if got := check(root); got != 1 {
|
|
t.Errorf("a finding in a module no list names = %d, want 1", got)
|
|
}
|
|
}
|
|
|
|
// 1838/AC2: the hardware model's own name and the software's own name are not node names.
|
|
func TestTheHardwareModelAndTheSoftwareAreNotNodeNames(t *testing.T) {
|
|
for _, s := range []string{
|
|
"modules/asus-zephyrus-g14/README.md",
|
|
"the asus-zephyrus-g14 module",
|
|
"ASUS_ZEPHYRUS_G14=1",
|
|
"product_family: ROG Zephyrus G14",
|
|
"# This machine is a node of a Novox mesh",
|
|
"Novox Mesh turns a handful of personal machines into one system",
|
|
"<!-- novox mesh: this file was changed on two nodes",
|
|
`const sealInfo = "novox-mesh sealed box v1"`,
|
|
"module git.novox.be/novox/mesh-catalog/modules/kernel",
|
|
} {
|
|
if got := scan("f", s, names); len(got) != 0 {
|
|
t.Errorf("%q refused: %v", s, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 1838/AC2: a node name standing alone is still one, beside the hardware's or the software's name too.
|
|
func TestANodeNameBesideTheHardwareOrTheSoftwareIsRefused(t *testing.T) {
|
|
cases := map[string]string{
|
|
"g14": "the asus-zephyrus-g14 module on g14",
|
|
"shanks": "Novox Mesh on shanks",
|
|
"novox": "resolves under novox.internal",
|
|
"ace": "ROG Zephyrus G14 beside ace",
|
|
"novox mesh-ish": "mesh.mod.gitea.call.x.novox-mesh-vault",
|
|
}
|
|
for want, s := range cases {
|
|
got := scan("modules/m/a.go", s, names)
|
|
if len(got) != 1 || !strings.HasPrefix(got[0], "modules/m/a.go:1: ") {
|
|
t.Errorf("%s: %q gave %v, want one finding naming file:line", want, s, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 1838/AC2: the software's npm scope (@novox/mesh-sdk, @novox:registry=) is its package path, as the Go module
|
|
// path is; a session's who@node naming a node is still a node name.
|
|
func TestTheSoftwaresNpmScopeIsNotANodeName(t *testing.T) {
|
|
for _, s := range []string{
|
|
"printf '%s\\n' ${shellQuote(`@novox:registry=${registry}`)}",
|
|
"const url = `${asked}@novox%2fmesh-sdk`;",
|
|
"# The @novox scope resolves from the mesh's own package registry",
|
|
`"dependencies": { "@novox/mesh-sdk": "^0.1.0" }`,
|
|
} {
|
|
if got := scan("f", s, names); len(got) != 0 {
|
|
t.Errorf("%q refused: %v", s, got)
|
|
}
|
|
}
|
|
for _, s := range []string{"by fix-1@novox", "jochen@novox:"} {
|
|
if got := scan("f", s, names); len(got) != 1 {
|
|
t.Errorf("%q gave %v, want one finding", s, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 1838/AC1: reading every module, the check compiles its matchers once, not once a line: a line read costs a
|
|
// few allocations, not a regexp compiled per name (the whole catalogue took 41 s with one per line).
|
|
func TestALineIsReadWithoutCompilingAMatcher(t *testing.T) {
|
|
line := "a line of code that names nothing at all, with git.novox.be/novox/mesh-sdk in it"
|
|
if n := testing.AllocsPerRun(100, func() { hits(line, names) }); n > 20 {
|
|
t.Errorf("a line costs %.0f allocations, want at most 20", n)
|
|
}
|
|
}
|
|
|
|
// 1838/AC2: a module may declare its hardware model's word in `particulars` (model <module> <word>); the word is
|
|
// then no finding in that module, and still one in every other.
|
|
func TestAModelsWordIsAllowedInItsModuleOnly(t *testing.T) {
|
|
root := t.TempDir()
|
|
write := func(p, s string) {
|
|
p = filepath.Join(root, p)
|
|
os.MkdirAll(filepath.Dir(p), 0o755)
|
|
os.WriteFile(p, []byte(s), 0o644)
|
|
}
|
|
write("particulars", "ace\ng14\nmodel asus-zephyrus-g14 g14\n")
|
|
write("modules/asus-zephyrus-g14/README.md", "the adopted /etc/modprobe.d/g14-nvidia-power.conf; a second G14\n")
|
|
write("modules/kernel/a", "clean\n")
|
|
if got := check(root); got != 0 {
|
|
t.Errorf("the model's word in its own module = %d, want 0", got)
|
|
}
|
|
write("modules/asus-zephyrus-g14/a", "on ace\n")
|
|
if got := check(root); got != 1 {
|
|
t.Errorf("another node name in the model's module = %d, want 1", got)
|
|
}
|
|
write("modules/asus-zephyrus-g14/a", "clean\n")
|
|
write("modules/kernel/a", "i3's 20-g14.conf\n")
|
|
if got := check(root); got != 1 {
|
|
t.Errorf("the model's word in another module = %d, want 1", got)
|
|
}
|
|
write("modules/kernel/a", "clean\n")
|
|
write("particulars", "ace\ng14\nmodel no-such-module g14\n")
|
|
if got := check(root); got != 2 {
|
|
t.Errorf("a model of a module that does not exist = %d, want 2", got)
|
|
}
|
|
write("particulars", "ace\ng14\nmodel asus-zephyrus-g14 shanks\n")
|
|
if got := check(root); got != 2 {
|
|
t.Errorf("a model's word that is no listed name = %d, want 2", got)
|
|
}
|
|
}
|
|
|
|
// 1838/AC2: only the module path git.novox.be/novox/<repo>, a package name or scope with nothing before its @, and
|
|
// the exact record citation novox/hq ADR|issue|design|to-be|research are the forge's or the software's; any
|
|
// other novox/<x>, the forge's host alone, and a node after a word's @ are findings.
|
|
func TestOnlyTheModulePathThePackageAndTheCitationAreNotNodeNames(t *testing.T) {
|
|
for _, s := range []string{
|
|
"module git.novox.be/novox/mesh-sdk/go v1.2.3",
|
|
"https://git.novox.be/novox/mesh-catalog",
|
|
`import { registerModuleTools } from "@novox/mesh-sdk/tools";`,
|
|
`"dependencies": { "@novox/ui": "^2.0.0" }`,
|
|
"// novox/hq ADR 0507 §9",
|
|
"(novox/hq issue 1838)",
|
|
"novox/hq design 47 and novox/hq to-be 53, novox/hq research 12",
|
|
} {
|
|
if got := scan("f", s, names); len(got) != 0 {
|
|
t.Errorf("%q refused: %v", s, got)
|
|
}
|
|
}
|
|
for _, s := range []string{
|
|
`handedWith("node-b", "gitea", "postgres-database@novox/postgres+pair")`,
|
|
"delivery.novox/mesh-controller",
|
|
"git.anchor.internal:222/novox/hq.git",
|
|
"see novox/mesh-catalog #441",
|
|
"novox/hq review round 2",
|
|
"novox/hq issues 3 and 4",
|
|
"repository: novox/hq",
|
|
"git.novox.be",
|
|
} {
|
|
if got := scan("f", s, names); len(got) != 1 {
|
|
t.Errorf("%q gave %v, want one finding", s, got)
|
|
}
|
|
}
|
|
}
|