test(ec): pin .ecsum sidecar bytes for cross-binary interop

Deterministic EcBitrotProtection -> exact on-disk bytes, asserted against a
canonical constant on BOTH sides (this test and ec_bitrot.rs), so a format drift
in either binary fails its own suite rather than silently desyncing a Go-written
.ecsum from a Rust-written one.

Claude-Session: https://claude.ai/code/session_015EE9Sc9EvNp8BCVva4RKdo
This commit is contained in:
Chris Lu
2026-06-30 10:41:28 -07:00
parent ddab5ac403
commit 4bd0b0c5a6
@@ -0,0 +1,60 @@
package erasure_coding
import (
"encoding/hex"
"os"
"path/filepath"
"testing"
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
)
// interopSample is the fully-deterministic sidecar shared with the Rust port's
// ec_bitrot.rs `sample()`. Both binaries must serialize it to identical bytes.
func interopSample() *volume_server_pb.EcBitrotProtection {
return &volume_server_pb.EcBitrotProtection{
Algorithm: volume_server_pb.ChecksumAlgorithm_CHECKSUM_CRC32C,
BlockSize: uint32(DefaultBitrotBlockSize),
EcShardConfig: &volume_server_pb.EcShardConfig{
DataShards: 10,
ParityShards: 4,
},
Shards: []*volume_server_pb.EcShardChecksums{
{ShardId: 0, CoveredSize: 1024 * 1024, BlockCrc32C: packUint32LE([]uint32{0x01020304})},
{ShardId: 1, CoveredSize: 1024 * 1024, BlockCrc32C: packUint32LE([]uint32{0x05060708})},
},
EncodeUuid: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
}
}
// canonicalInteropHex is the exact on-disk bytes of interopSample(). The Rust
// port's ec_bitrot.rs test_byte_exact_go_interop pins the SAME constant, so a
// format change in EITHER binary (new always-serialized field, renumber,
// EcShardConfig default flip, protobuf canonicalization change) fails that
// binary's test instead of silently desyncing a Go-written sidecar from a
// Rust-written one. If you intentionally change the format, regenerate this
// (run with -v to print the hex) and update the Rust constant in lock-step.
const canonicalInteropHex = "45435355000100000039cc1b826a080110808080082204080a10042a0a108080401a04040302012a0c0801108080401a04080706053210000102030405060708090a0b0c0d0e0f"
// TestBitrotSidecarBytes_RustInterop pins the on-disk bytes so a Go-side format
// drift fails here, and the Rust port asserts the same constant (cross-binary
// sidecar interop).
func TestBitrotSidecarBytes_RustInterop(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "v1.ecsum")
if err := SaveBitrotSidecar(path, interopSample()); err != nil {
t.Fatalf("save: %v", err)
}
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read: %v", err)
}
if got := hex.EncodeToString(data); got != canonicalInteropHex {
t.Fatalf("bitrot sidecar bytes drifted from the cross-binary canonical form;\n got=%s\nwant=%s\n(regenerate and update the Rust constant in lock-step)", got, canonicalInteropHex)
}
// Round-trips through the loader.
if _, err := LoadBitrotSidecar(path); err != nil {
t.Fatalf("load: %v", err)
}
}