Checker client: the codecs of the verdicts, kept and previews states the checker writes and others read (ruling 17:4x; ADR 0634 §2; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -149,3 +149,46 @@ func TestVerdictKeyAsGoDeliveryWroteIt(t *testing.T) {
|
||||
t.Error("a short hash keys")
|
||||
}
|
||||
}
|
||||
|
||||
// The codecs write a value at the kept values' version after its rules and read it back through them.
|
||||
func TestTheCodecsWriteAtTheVersionAndReadBackThroughTheRules(t *testing.T) {
|
||||
raw, err := EncodeVerdict(passing())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, err := DecodeVerdict(raw); err != nil || got.V == 0 || got.Group != "g" {
|
||||
t.Errorf("verdict read back = %+v, %v", got, err)
|
||||
}
|
||||
bad := passing()
|
||||
bad.Heads = "x"
|
||||
if _, err := EncodeVerdict(bad); err == nil {
|
||||
t.Error("a verdict whose heads are no hash is written")
|
||||
}
|
||||
if _, err := DecodeVerdict([]byte(`{"v":99,"group":"g","heads":"0123456789ab","state":"running"}`)); err == nil {
|
||||
t.Error("a verdict of an unknown version is read")
|
||||
}
|
||||
k := checker.KeptByLevelDigestValue{State: VerdictPass, Repository: "novox/mesh-sdk", Package: "./go/keys", Level: LevelUnit, Toolchain: "1.26.0", At: "2026-11-05T10:00:00Z"}
|
||||
raw, err = EncodeKept(k)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, err := DecodeKept(raw); err != nil || got.Package != k.Package {
|
||||
t.Errorf("kept read back = %+v, %v", got, err)
|
||||
}
|
||||
k.State = VerdictFail
|
||||
if _, err := EncodeKept(k); err == nil {
|
||||
t.Error("a failure is kept")
|
||||
}
|
||||
p := checker.PreviewsByRepositoryHeadTrunkValue{Repository: "novox/a", Head: "h1", Trunk: "t1", Conflicts: []string{"f.go"}}
|
||||
raw, err = EncodePreview(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got, err := DecodePreview(raw); err != nil || got.Head != "h1" {
|
||||
t.Errorf("preview read back = %+v, %v", got, err)
|
||||
}
|
||||
p.Conflicts = nil
|
||||
if _, err := EncodePreview(p); err == nil {
|
||||
t.Error("a preview with no merge commit and no conflict is written")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package meshdeliverycheckerclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
checker "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdeliverychecker"
|
||||
"git.novox.be/novox/mesh-sdk/go/keys"
|
||||
)
|
||||
|
||||
// The codecs of the three states the checker writes and others read (the view and the gate read verdicts, the indexer reads
|
||||
// previews, the checker and the tools read kept verdicts): a value is written at the version of the kept values after its rules
|
||||
// (CheckVerdict, CheckKept, CheckPreview) and read back through the same rules. The checker's owed state is read by no other
|
||||
// part and keeps its own codec.
|
||||
|
||||
// EncodeVerdict is v as JSON at the kept values' version, refused by CheckVerdict's rules.
|
||||
func EncodeVerdict(v checker.VerdictsByGroupHeadsValue) ([]byte, error) {
|
||||
if err := CheckVerdict(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.V = keys.Version
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// DecodeVerdict reads a `verdicts` value; it refuses an unknown version (keys.ErrUnknownVersion) and what EncodeVerdict refuses.
|
||||
func DecodeVerdict(data []byte) (checker.VerdictsByGroupHeadsValue, error) {
|
||||
var v checker.VerdictsByGroupHeadsValue
|
||||
if err := decode(data, &v); err != nil {
|
||||
return v, err
|
||||
}
|
||||
if err := CheckVerdict(v); err != nil {
|
||||
return checker.VerdictsByGroupHeadsValue{}, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// EncodeKept is k as JSON at the kept values' version, refused by CheckKept's rules.
|
||||
func EncodeKept(k checker.KeptByLevelDigestValue) ([]byte, error) {
|
||||
if err := CheckKept(k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k.V = keys.Version
|
||||
return json.Marshal(k)
|
||||
}
|
||||
|
||||
// DecodeKept reads a `kept` value; it refuses an unknown version and what EncodeKept refuses.
|
||||
func DecodeKept(data []byte) (checker.KeptByLevelDigestValue, error) {
|
||||
var k checker.KeptByLevelDigestValue
|
||||
if err := decode(data, &k); err != nil {
|
||||
return k, err
|
||||
}
|
||||
if err := CheckKept(k); err != nil {
|
||||
return checker.KeptByLevelDigestValue{}, err
|
||||
}
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// EncodePreview is p as JSON at the kept values' version, refused by CheckPreview's rules.
|
||||
func EncodePreview(p checker.PreviewsByRepositoryHeadTrunkValue) ([]byte, error) {
|
||||
if err := CheckPreview(p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.V = keys.Version
|
||||
return json.Marshal(p)
|
||||
}
|
||||
|
||||
// DecodePreview reads a `previews` value; it refuses an unknown version and what EncodePreview refuses.
|
||||
func DecodePreview(data []byte) (checker.PreviewsByRepositoryHeadTrunkValue, error) {
|
||||
var p checker.PreviewsByRepositoryHeadTrunkValue
|
||||
if err := decode(data, &p); err != nil {
|
||||
return p, err
|
||||
}
|
||||
if err := CheckPreview(p); err != nil {
|
||||
return checker.PreviewsByRepositoryHeadTrunkValue{}, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func decode(data []byte, into any) error {
|
||||
if err := keys.CheckVersion(data); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, into); err != nil {
|
||||
return fmt.Errorf("meshdeliverycheckerclient: value does not fit its shape: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user