niko_trust/internal/tce/id_test.go
Niko Marmeladkov 9d66003689
Initial commit: signed-object trust relay, verifier, and docs
- server: relay storing signed objects (PUT/GET), per-IP rate limiting,
  per-subject quota (1000), one-response-per-request, pagination,
  /v1/healthz /v1/readyz /v1/metrics
- verify: signature-verifying trust evaluator; every object is checked via
  env.Verify(), approvals via VerifyApprovalResponse, revocations via
  VerifyRevocationOf; k-of-n approval quorum
- docs: TRUST-MODEL.md and API.md describing issuer-anchored signatures and
  the endpoint/status-code contract
- tests: server, verify, and ratelimit packages
2026-08-12 22:36:49 +03:00

114 lines
2.9 KiB
Go

package tce_test
import (
"testing"
"git.n1ko.dev/Niko/niko_trust/internal/tce"
)
func TestIDAccessors(t *testing.T) {
// ComputeID is SHA-256 over the canonical bytes.
id := tce.ComputeID([]byte("trust.n1ko.dev/tce/1"))
if id.IsZero() {
t.Fatal("a computed ID must not be zero")
}
if !id.Equal(id) {
t.Fatal("an ID must equal itself")
}
if len(id.String()) != 64 {
t.Fatalf("ID hex must be 64 chars, got %d", len(id.String()))
}
if len(id.Bytes()) != 32 {
t.Fatalf("ID bytes must be 32, got %d", len(id.Bytes()))
}
// Bytes is a copy: mutating it must not change the ID.
raw := id.Bytes()
raw[0] ^= 0xff
if id.Bytes()[0] == raw[0] {
t.Fatal("Bytes did not return an independent copy")
}
zero := tce.ID{}
if !zero.IsZero() {
t.Fatal("zero ID must report IsZero")
}
if id.IsZero() {
t.Fatal("non-zero ID must not report IsZero")
}
}
func TestParseID(t *testing.T) {
// accurate 64-char lowercase hex
good := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
id, err := tce.ParseID(good)
if err != nil {
t.Fatalf("ParseID good: %v", err)
}
if id.String() != good {
t.Fatalf("round-trip mismatch: %s != %s", id.String(), good)
}
bad := []string{
good[:63], // too short
good + "0", // too long
good[:63] + "G", // non-hex
good[:63] + "A", // uppercase rejected
}
for _, b := range bad {
if _, err := tce.ParseID(b); err == nil {
t.Errorf("ParseID(%q): expected error", b)
}
}
}
func TestIDFromBytes(t *testing.T) {
b := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
id, err := tce.IDFromBytes(b)
if err != nil {
t.Fatalf("IDFromBytes: %v", err)
}
if id.Bytes()[0] != 0 || id.Bytes()[31] != 31 {
t.Fatal("IDFromBytes copied incorrectly")
}
if _, err := tce.IDFromBytes(b[:31]); err == nil {
t.Fatal("IDFromBytes wrong length must error")
}
}
func TestIDText(t *testing.T) {
good := "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
id, err := tce.ParseID(good)
if err != nil {
t.Fatal(err)
}
text, err := id.MarshalText()
if err != nil {
t.Fatalf("MarshalText: %v", err)
}
if string(text) != good {
t.Fatalf("MarshalText = %q, want %q", text, good)
}
var back tce.ID
if err := back.UnmarshalText(text); err != nil {
t.Fatalf("UnmarshalText: %v", err)
}
if !back.Equal(id) {
t.Fatal("UnmarshalText did not reconstruct the ID")
}
if err := back.UnmarshalText([]byte("zz")); err == nil {
t.Fatal("UnmarshalText must reject bad hex")
}
}
func TestComputeIDStable(t *testing.T) {
a := tce.ComputeID([]byte("abc"))
b := tce.ComputeID([]byte("abc"))
c := tce.ComputeID([]byte("abd"))
if !a.Equal(b) {
t.Fatal("same input must yield equal IDs")
}
if a.Equal(c) {
t.Fatal("different input must yield different IDs")
}
}