SHA-256 over raw asset bytes and over the canonical JSON form of metadata (encoding/json already sorts map keys and preserves struct field order deterministically, so no separate canonicalization library is needed for our own fixed types). A Timestamper interface stands in for the RFC-3161 timestamp step — no concrete implementation yet, since which TSA to use is an open decision (CLAUDE.md "Offene Punkte") that directly affects the archive's evidentiary weight, not a purely technical choice to make silently. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package evidence_test
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
|
|
"github.com/netcell-it/deklarix/internal/evidence"
|
|
)
|
|
|
|
func TestHashBytesIsDeterministic(t *testing.T) {
|
|
data := []byte("ein beispiel-asset")
|
|
a := evidence.HashBytes(data)
|
|
b := evidence.HashBytes(data)
|
|
if !bytes.Equal(a, b) {
|
|
t.Fatalf("HashBytes ist nicht deterministisch: %x != %x", a, b)
|
|
}
|
|
if len(a) != 32 {
|
|
t.Fatalf("expected 32-byte SHA-256 digest, got %d bytes", len(a))
|
|
}
|
|
}
|
|
|
|
func TestHashBytesDiffersForDifferentInput(t *testing.T) {
|
|
a := evidence.HashBytes([]byte("foo"))
|
|
b := evidence.HashBytes([]byte("bar"))
|
|
if bytes.Equal(a, b) {
|
|
t.Fatal("expected different hashes for different input, got the same")
|
|
}
|
|
}
|
|
|
|
func TestHashMetadataIsStableAcrossMapKeyOrder(t *testing.T) {
|
|
m1 := map[string]any{"a": 1, "b": 2, "c": 3}
|
|
m2 := map[string]any{"c": 3, "a": 1, "b": 2}
|
|
|
|
h1, err := evidence.HashMetadata(m1)
|
|
if err != nil {
|
|
t.Fatalf("HashMetadata(m1): %v", err)
|
|
}
|
|
h2, err := evidence.HashMetadata(m2)
|
|
if err != nil {
|
|
t.Fatalf("HashMetadata(m2): %v", err)
|
|
}
|
|
if !bytes.Equal(h1, h2) {
|
|
t.Fatal("HashMetadata should be stable across map key insertion order")
|
|
}
|
|
}
|
|
|
|
func TestHashMetadataDiffersForDifferentContent(t *testing.T) {
|
|
h1, err := evidence.HashMetadata(map[string]any{"a": 1})
|
|
if err != nil {
|
|
t.Fatalf("HashMetadata: %v", err)
|
|
}
|
|
h2, err := evidence.HashMetadata(map[string]any{"a": 2})
|
|
if err != nil {
|
|
t.Fatalf("HashMetadata: %v", err)
|
|
}
|
|
if bytes.Equal(h1, h2) {
|
|
t.Fatal("expected different hashes for different metadata content")
|
|
}
|
|
}
|
|
|
|
func TestHashMetadataRejectsUnmarshalableValue(t *testing.T) {
|
|
// Kanäle können nicht als JSON serialisiert werden — muss einen
|
|
// Fehler liefern statt still einen falschen Hash zurückzugeben.
|
|
if _, err := evidence.HashMetadata(make(chan int)); err == nil {
|
|
t.Fatal("expected error for unmarshalable value, got nil")
|
|
}
|
|
}
|