better convert
This commit is contained in:
1 parent
2a66754f9e
commit
b128608316
7 files changed
+591
-20
No files matched your search
@@ -0,0 +1,114 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestKeyHashing_LongKeyRoundTrips — a key well over the 32-byte raw ceiling
|
||||
// (a query string / page path) is accepted in hashed mode and Get finds it.
|
||||
func TestKeyHashing_LongKeyRoundTrips(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
longKey := "/kategori/" + strings.Repeat("hem-hushall-tradgard/", 5) + "?q=" + strings.Repeat("x", 80)
|
||||
if len(longKey) <= maxSKULen {
|
||||
t.Fatalf("test bug: key is only %d bytes, not over the ceiling", len(longKey))
|
||||
}
|
||||
|
||||
w := NewSnapshotWriter[tProj]().WithKeyHashing()
|
||||
// The value carries the original key — the id/sku stays the link even though
|
||||
// the index key is a digest.
|
||||
if err := w.Append(longKey, tProj{SKU: longKey, PriceIncVat: 42}); err != nil {
|
||||
t.Fatalf("Append long key in hashed mode: %v", err)
|
||||
}
|
||||
if _, err := w.Write(dir, "hashed.bin"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r, err := ReadSnapshotFile[tProj](filepath.Join(dir, "hashed.bin"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
got, ok := r.Get(longKey)
|
||||
if !ok {
|
||||
t.Fatal("Get(longKey) miss — hashed lookup did not match the stored digest")
|
||||
}
|
||||
if got.PriceIncVat != 42 || got.SKU != longKey {
|
||||
t.Fatalf("got %+v, want price 42 and original key in value", got)
|
||||
}
|
||||
// Scan yields the digest, not the original — caller recovers it from the value.
|
||||
r.Scan(func(key string, v tProj) bool {
|
||||
if key == longKey {
|
||||
t.Error("Scan key should be the digest in hashed mode, got the original")
|
||||
}
|
||||
if len(key) != 32 {
|
||||
t.Errorf("digest key len = %d, want 32 hex chars", len(key))
|
||||
}
|
||||
if v.SKU != longKey {
|
||||
t.Errorf("value lost the original key: %q", v.SKU)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
// TestKeyHashing_RawModeStillRejectsLongKeys — default (raw) mode is unchanged:
|
||||
// an over-long key still errors, so catalog's contract is untouched.
|
||||
func TestKeyHashing_RawModeStillRejectsLongKeys(t *testing.T) {
|
||||
w := NewSnapshotWriter[tProj]() // raw
|
||||
long := strings.Repeat("x", 33)
|
||||
if err := w.Append(long, tProj{SKU: long}); err == nil {
|
||||
t.Fatal("raw mode should still reject a 33-byte key")
|
||||
}
|
||||
}
|
||||
|
||||
// TestKeyHashing_RawFileHeaderUnchanged — a raw-mode file sets keyEnc=0 at
|
||||
// offset 12, i.e. byte-identical header to a pre-hashing v2 file. Guards the
|
||||
// back-compat claim for catalog's existing .bin files.
|
||||
func TestKeyHashing_RawFileHeaderUnchanged(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
w := NewSnapshotWriter[tProj]()
|
||||
if err := appendP(w, makeProjection("A", 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := w.Write(dir, "raw.bin"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := ReadSnapshotFile[tProj](filepath.Join(dir, "raw.bin"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer r.Close()
|
||||
if r.raw.keyEnc != keyEncRaw {
|
||||
t.Fatalf("raw file keyEnc = %d, want 0", r.raw.keyEnc)
|
||||
}
|
||||
if _, ok := r.Get("A"); !ok {
|
||||
t.Error("raw-mode Get still works")
|
||||
}
|
||||
}
|
||||
|
||||
// TestKeyHashing_UnknownEncodingRejected — a header carrying an unknown key
|
||||
// encoding is rejected rather than silently mis-looked-up.
|
||||
func TestKeyHashing_UnknownEncodingRejected(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
w := NewSnapshotWriter[tProj]()
|
||||
if err := appendP(w, makeProjection("A", 1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
path := filepath.Join(dir, "tamper.bin")
|
||||
if _, err := w.Write(dir, "tamper.bin"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
data, err := os2ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
data[12] = 0x09 // keyEnc = 9, unknown
|
||||
if err := os2WriteFile(path, data, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := ReadSnapshotFile[tProj](path); err == nil {
|
||||
t.Fatal("unknown key encoding should be rejected")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user