Data.Clone() was a full JSON marshal/unmarshal round trip (with a per-record map dance for unknown fields): 6.3ms and ~13.8k allocs per call on sandbox hardware, and every admin GET paid it at least twice (RequireAdmin's user lookup + the handler). Clone is now a reflective deep copy of the plain data graph — byte-identical output, proven against the JSON clone on the real seed database by TestCloneEquivalence — at 0.37ms / 538 allocs. CurrentAdmin resolves the session user under a read-only store View and no longer clones at all, so an admin GET takes exactly one snapshot. Sandbox benchmarks (11 servers / 26 customers / 25 nodes): overview 17.2ms -> 0.38ms, servers 13.3 -> 0.85ms, customers 20.5 -> 1.54ms, nodes 15.8 -> 3.45ms, jobs 13.0 -> 0.39ms per request.
93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package main
|
|
|
|
// Item 22: the reflective Clone must be a perfect substitute for the
|
|
// JSON round-trip clone — byte-identical serialization on the real
|
|
// seed database, and fully independent of the original afterwards.
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestCloneEquivalenceOnSeed(t *testing.T) {
|
|
raw, err := os.ReadFile("difftest/seed.json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var d Data
|
|
if err := unmarshalJSONUseNumber(raw, &d); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
fast := d.Clone()
|
|
slow := d.cloneViaJSON()
|
|
fastJSON, err := marshalJSON(fast)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
slowJSON, err := marshalJSON(slow)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(fastJSON, slowJSON) {
|
|
t.Fatalf("clone mismatch:\nfast: %.400s\nslow: %.400s", fastJSON, slowJSON)
|
|
}
|
|
origJSON, err := marshalJSON(&d)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(fastJSON, origJSON) {
|
|
t.Fatal("clone must serialize identically to the source data")
|
|
}
|
|
// Deep independence: mutating the clone at several depths must not
|
|
// leak into the source.
|
|
if len(fast.Customers) > 0 {
|
|
fast.Customers[0].Name = "MUTATED"
|
|
if fast.Customers[0].Credentials != nil {
|
|
fast.Customers[0].Credentials.RelayPassword = "MUTATED"
|
|
}
|
|
}
|
|
if len(fast.Nodes) > 0 {
|
|
fast.Nodes[0].Name = "MUTATED"
|
|
}
|
|
for key := range fast.KeyStore {
|
|
fast.KeyStore[key].PrivateKey = "MUTATED"
|
|
break
|
|
}
|
|
afterJSON, err := marshalJSON(&d)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(afterJSON, origJSON) {
|
|
t.Fatal("clone mutation leaked into the source data")
|
|
}
|
|
}
|
|
|
|
func TestCloneEquivalenceSynthetic(t *testing.T) {
|
|
d := perfSeedData()
|
|
// Add the shapes the perf seed lacks: activity detail with nested
|
|
// generic values, keyStore entries, unknown (Extra) fields.
|
|
d.Activity = []*Activity{{ID: "act_1", At: NowISO(), Actor: "admin", Action: "x", Target: "y",
|
|
Detail: map[string]any{"n": json.Number("42"), "nested": map[string]any{"list": []any{"a", json.Number("1.5"), true, nil}}}}}
|
|
d.KeyStore["reality-nod_0"] = &KeyEntry{PrivateKey: "priv", PublicKey: "pub", UpdatedAt: NowISO()}
|
|
fastJSON, err := marshalJSON(d.Clone())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
slowJSON, err := marshalJSON(d.cloneViaJSON())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(fastJSON, slowJSON) {
|
|
t.Fatalf("synthetic clone mismatch:\nfast: %.300s\nslow: %.300s", fastJSON, slowJSON)
|
|
}
|
|
if d.Clone() == nil || EmptyData().Clone() == nil {
|
|
t.Fatal("clone of empty data must be non-nil")
|
|
}
|
|
var nilData *Data
|
|
if nilData.Clone() != nil {
|
|
t.Fatal("clone of nil must be nil")
|
|
}
|
|
}
|