FLEX-WP-0035-T04: application-readback pin values; lifecycle pin to v2 image
- values/application-readback.yaml: serve-readback, enforce, readback caller user-engine, ingress from user-engine only - chart: readback.enabled renders --readback-caller instead of --caller-binding - lifecycle pin to e8c57c18 (main-b5da745, lifecycle v2); previous bdac62bc - TestReadbackPinMatchesParticipantPins: same image digest and package path Founder go 2026-10-10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 735967@bnt-lap001 Assistant-Session: 5971967f-77f8-4ced-9e02-c6ef67040ffc
This commit is contained in:
parent
cb48d0702c
commit
bb14ec679c
5 changed files with 126 additions and 2 deletions
72
cmd/flex-auth/readback_pin_test.go
Normal file
72
cmd/flex-auth/readback_pin_test.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type pinValues struct {
|
||||
Image struct {
|
||||
Digest string `yaml:"digest"`
|
||||
} `yaml:"image"`
|
||||
Args []string `yaml:"args"`
|
||||
}
|
||||
|
||||
func loadPinValues(t *testing.T, name string) pinValues {
|
||||
t.Helper()
|
||||
raw, err := os.ReadFile(filepath.Join("..", "..", "values", name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var v pinValues
|
||||
if err := yaml.Unmarshal(raw, &v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func argAfter(args []string, flag string) []string {
|
||||
var out []string
|
||||
for i := 0; i+1 < len(args); i++ {
|
||||
if args[i] == flag {
|
||||
out = append(out, args[i+1])
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// FLEX-WP-0035-T04, contract §4: the readback pin runs each participant's
|
||||
// package at the same digest its own pin runs. The package is baked into the
|
||||
// image, so same image digest and same path is the same package digest.
|
||||
func TestReadbackPinMatchesParticipantPins(t *testing.T) {
|
||||
readback := loadPinValues(t, "application-readback.yaml")
|
||||
if len(readback.Args) == 0 || readback.Args[0] != "serve-readback" {
|
||||
t.Fatal("readback pin must run serve-readback, which mounts no /v1/check")
|
||||
}
|
||||
participants := map[string]string{"informed-decision": "informed-decision-lifecycle.yaml"}
|
||||
packages := argAfter(readback.Args, "--package")
|
||||
if len(packages) != len(participants) {
|
||||
t.Fatalf("readback packages %v, want one per participant %v", packages, participants)
|
||||
}
|
||||
for _, pkg := range packages {
|
||||
system, path, _ := strings.Cut(pkg, "=")
|
||||
file, ok := participants[system]
|
||||
if !ok {
|
||||
t.Fatalf("readback package for %q has no participant pin", system)
|
||||
}
|
||||
own := loadPinValues(t, file)
|
||||
if own.Image.Digest != readback.Image.Digest {
|
||||
t.Errorf("%s: readback image %s, own pin %s", system, readback.Image.Digest, own.Image.Digest)
|
||||
}
|
||||
if policies := argAfter(own.Args, "--policy"); len(policies) != 1 || policies[0] != path {
|
||||
t.Errorf("%s: readback package %s, own pin %v", system, path, policies)
|
||||
}
|
||||
if !strings.Contains(strings.Join(argAfter(readback.Args, "--registry"), " "), strings.Join(argAfter(own.Args, "--registry"), " ")) {
|
||||
t.Errorf("%s: readback pin does not load its registry", system)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue