f31a76f788
B3: Lookup re-reads the append-only store once on a miss (cross-process coherence with the one-shot provisioner; size short-circuit bounds the cost; behind the TokenAuthority seam). B2: fenced mkdir -p /var/lib/vz/snippets before the snippet install + the one narrow sudoers grant. Both red-proofed; drill findings DRILL-day0-cleanroom-2026-07-03 B3/B2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
255 lines
7.6 KiB
Go
255 lines
7.6 KiB
Go
package localapi
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestTokenStore_MintLookup(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
s, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
defer s.Close()
|
|
|
|
tok, err := s.Mint(8200)
|
|
if err != nil {
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
if tok == "" {
|
|
t.Fatal("mint returned empty token")
|
|
}
|
|
if vmid, ok := s.Lookup(tok); !ok || vmid != 8200 {
|
|
t.Fatalf("lookup: got (%d,%v), want (8200,true)", vmid, ok)
|
|
}
|
|
if _, ok := s.Lookup("not-a-real-token"); ok {
|
|
t.Fatal("lookup of unknown token succeeded")
|
|
}
|
|
if _, ok := s.Lookup(""); ok {
|
|
t.Fatal("lookup of empty token succeeded")
|
|
}
|
|
}
|
|
|
|
// The persisted file must contain only the HASH, never the plaintext token.
|
|
func TestTokenStore_PlaintextNeverPersisted(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
s, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
tok, err := s.Mint(101)
|
|
if err != nil {
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
s.Close()
|
|
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("read store: %v", err)
|
|
}
|
|
if strings.Contains(string(b), tok) {
|
|
t.Fatal("plaintext token found in the persisted store — must store only the hash")
|
|
}
|
|
if !strings.Contains(string(b), hashToken(tok)) {
|
|
t.Fatal("token hash not found in the persisted store")
|
|
}
|
|
}
|
|
|
|
// A re-mint for the same guest revokes the previous token (last-write-wins).
|
|
func TestTokenStore_RemintRevokesOld(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
s, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
defer s.Close()
|
|
|
|
old, _ := s.Mint(7)
|
|
fresh, _ := s.Mint(7)
|
|
if old == fresh {
|
|
t.Fatal("re-mint produced the same token")
|
|
}
|
|
if _, ok := s.Lookup(old); ok {
|
|
t.Fatal("old token still valid after re-mint")
|
|
}
|
|
if vmid, ok := s.Lookup(fresh); !ok || vmid != 7 {
|
|
t.Fatalf("fresh token lookup: got (%d,%v), want (7,true)", vmid, ok)
|
|
}
|
|
}
|
|
|
|
// Durability: tokens survive a store reopen (replay).
|
|
func TestTokenStore_SurvivesReopen(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
s1, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
a, _ := s1.Mint(1)
|
|
b, _ := s1.Mint(2)
|
|
// rotate guest 1
|
|
a2, _ := s1.Mint(1)
|
|
s1.Close()
|
|
|
|
s2, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("reopen: %v", err)
|
|
}
|
|
defer s2.Close()
|
|
|
|
if _, ok := s2.Lookup(a); ok {
|
|
t.Fatal("rotated-out token survived reopen")
|
|
}
|
|
if vmid, ok := s2.Lookup(a2); !ok || vmid != 1 {
|
|
t.Fatalf("guest1 current token lost across reopen: (%d,%v)", vmid, ok)
|
|
}
|
|
if vmid, ok := s2.Lookup(b); !ok || vmid != 2 {
|
|
t.Fatalf("guest2 token lost across reopen: (%d,%v)", vmid, ok)
|
|
}
|
|
}
|
|
|
|
// B3 Scenario A (DRILL-day0-cleanroom-2026-07-03): the provisioner is a SEPARATE one-shot process
|
|
// that Mints into the SAME file the long-lived daemon serves Lookup from. A token minted after the
|
|
// daemon built its index must authorize WITHOUT a restart — the reload-on-miss re-reads the file.
|
|
// Pre-fix wrong outcome: (0,false) — the fresh-install 401 the drill hit on /controller/swap.
|
|
func TestTokenStore_ReloadOnMiss_CrossProcessMint(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
daemon, err := OpenTokenStore(path) // index built now (empty file)
|
|
if err != nil {
|
|
t.Fatalf("open daemon store: %v", err)
|
|
}
|
|
defer daemon.Close()
|
|
|
|
minter, err := OpenTokenStore(path) // the --selftest=provision process
|
|
if err != nil {
|
|
t.Fatalf("open minter store: %v", err)
|
|
}
|
|
defer minter.Close()
|
|
tok, err := minter.Mint(120)
|
|
if err != nil {
|
|
t.Fatalf("cross-process mint: %v", err)
|
|
}
|
|
|
|
vmid, ok := daemon.Lookup(tok)
|
|
if !ok || vmid != 120 {
|
|
t.Fatalf("daemon.Lookup(token minted after daemon start) = (%d,%v), want (120,true) — the B3 fresh-install 401", vmid, ok)
|
|
}
|
|
}
|
|
|
|
// B3 Scenario B: a genuinely unknown token still returns (0,false), and the miss path re-reads the
|
|
// file AT MOST once per Lookup — and not at all when the append-only log has not grown (the size
|
|
// short-circuit). Guards against a reload loop / per-candidate re-read.
|
|
func TestTokenStore_ReloadOnMiss_BoundedReloads(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
daemon, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open daemon store: %v", err)
|
|
}
|
|
defer daemon.Close()
|
|
minter, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open minter store: %v", err)
|
|
}
|
|
defer minter.Close()
|
|
if _, err := minter.Mint(5); err != nil { // grow the file behind the daemon's back
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
|
|
base := daemon.reloads
|
|
if vmid, ok := daemon.Lookup("garbage-never-minted"); ok {
|
|
t.Fatalf("unknown token authorized: (%d,%v)", vmid, ok)
|
|
}
|
|
if got := daemon.reloads - base; got != 1 {
|
|
t.Fatalf("first miss after an external append: %d reloads, want exactly 1", got)
|
|
}
|
|
if vmid, ok := daemon.Lookup("garbage-never-minted"); ok {
|
|
t.Fatalf("unknown token authorized on retry: (%d,%v)", vmid, ok)
|
|
}
|
|
if got := daemon.reloads - base; got != 1 {
|
|
t.Fatalf("second miss on an UNCHANGED store re-read the file: %d reloads total, want still 1 (size short-circuit)", got)
|
|
}
|
|
}
|
|
|
|
// B3 Scenario C: a cross-process re-mint (rotation) stays coherent through a reload — apply's
|
|
// last-write-wins holds after the full re-read: the new hash resolves, the rotated-out one 401s,
|
|
// and the indexes agree.
|
|
func TestTokenStore_ReloadOnMiss_RemintCoherence(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
daemon, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open daemon store: %v", err)
|
|
}
|
|
defer daemon.Close()
|
|
minter, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open minter store: %v", err)
|
|
}
|
|
defer minter.Close()
|
|
|
|
tok1, _ := minter.Mint(120)
|
|
if vmid, ok := daemon.Lookup(tok1); !ok || vmid != 120 { // daemon absorbs tok1 via miss-reload
|
|
t.Fatalf("tok1 lookup: (%d,%v), want (120,true)", vmid, ok)
|
|
}
|
|
tok2, _ := minter.Mint(120) // rotation, appended externally
|
|
|
|
if vmid, ok := daemon.Lookup(tok2); !ok || vmid != 120 {
|
|
t.Fatalf("rotated token lookup: (%d,%v), want (120,true)", vmid, ok)
|
|
}
|
|
if vmid, ok := daemon.Lookup(tok1); ok {
|
|
t.Fatalf("rotated-OUT token still authorizes vmid %d after reload — last-write-wins broken", vmid)
|
|
}
|
|
daemon.mu.Lock()
|
|
gotHash, gotVMID := daemon.byVMID[120], daemon.byHash[hashToken(tok2)]
|
|
oldGone := daemon.byHash[hashToken(tok1)]
|
|
daemon.mu.Unlock()
|
|
if gotHash != hashToken(tok2) || gotVMID != 120 || oldGone != 0 {
|
|
t.Fatalf("index incoherent after reload: byVMID[120]=%.8s byHash[tok2]=%d byHash[tok1]=%d", gotHash, gotVMID, oldGone)
|
|
}
|
|
}
|
|
|
|
// §8 edge: the store file deleted between open and a miss — reload treats it as empty; Lookup
|
|
// fails closed, no crash.
|
|
func TestTokenStore_ReloadOnMiss_MissingFile(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("windows cannot unlink the store while its O_APPEND handle is open; production target is linux")
|
|
}
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
s, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
defer s.Close()
|
|
if _, err := s.Mint(1); err != nil {
|
|
t.Fatalf("mint: %v", err)
|
|
}
|
|
if err := os.Remove(path); err != nil {
|
|
t.Fatalf("remove store: %v", err)
|
|
}
|
|
if vmid, ok := s.Lookup("garbage-never-minted"); ok {
|
|
t.Fatalf("lookup on a deleted store authorized (%d,%v)", vmid, ok)
|
|
}
|
|
}
|
|
|
|
func TestTokenStore_Uniqueness(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "tokens.log")
|
|
s, err := OpenTokenStore(path)
|
|
if err != nil {
|
|
t.Fatalf("open: %v", err)
|
|
}
|
|
defer s.Close()
|
|
seen := map[string]bool{}
|
|
for i := 1; i <= 200; i++ {
|
|
tok, err := s.Mint(i)
|
|
if err != nil {
|
|
t.Fatalf("mint %d: %v", i, err)
|
|
}
|
|
if seen[tok] {
|
|
t.Fatalf("duplicate token at %d", i)
|
|
}
|
|
seen[tok] = true
|
|
}
|
|
}
|