textmachine/backend/internal/lang/embedded_test.go

48 lines
1.6 KiB
Go

package lang
import (
"strings"
"testing"
)
// TestEmbeddedVersionMutation is the П0 acceptance test (D39.60 §6.1, "bytes ARE version" for the embed
// plane): a byte edit of an embedded data file MUST move EmbeddedVersion — so, once it is folded into the
// snapshot, an edit is a loud --resnapshot, never a silent verdict/wire change. It also pins the format and
// reproducibility (the same bytes always hash the same).
func TestEmbeddedVersionMutation(t *testing.T) {
got := EmbeddedVersion()
if !strings.HasPrefix(got, embedAlgoVersion+"-") {
t.Fatalf("EmbeddedVersion() = %q, want %s-<hash>", got, embedAlgoVersion)
}
files := embeddedDataFiles()
if len(files) == 0 {
t.Fatal("no embedded data files")
}
if base := hashEmbeddedFiles(files); base != got {
t.Fatalf("EmbeddedVersion not reproducible from embeddedDataFiles(): %s != %s", base, got)
}
// Mutate ONE byte of a verdict-bearing file (target-ru.txt drives the sanitizer) and a wire-bearing file
// (injection.txt rides the request) — each must diverge the hash on its own.
for _, target := range []string{"target-ru.txt", "injection.txt"} {
mutated := make([]embeddedFile, len(files))
copy(mutated, files)
var found bool
for i := range mutated {
if mutated[i].name == target {
b := append([]byte(nil), mutated[i].data...)
b[len(b)/2] ^= 0x01 // flip a content byte
mutated[i].data = b
found = true
break
}
}
if !found {
t.Fatalf("%s is not embedded", target)
}
if mut := hashEmbeddedFiles(mutated); mut == got {
t.Errorf("a byte edit of %s did NOT move EmbeddedVersion (%s) — the embed plane would drift silently", target, mut)
}
}
}