fix9-1: the teller, view and watchman manifest tests' reader takes requires, and hold the findings as requires
Builds: design 47 G §383, §387; A-30
This commit is contained in:
@@ -55,6 +55,7 @@ type manifest struct {
|
||||
OwnSecrets map[string]string `json:"own-secrets"`
|
||||
SecretsOwner string `json:"secrets-owner"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Requires []require `json:"requires"`
|
||||
Build struct {
|
||||
Artifacts []artifact `json:"artifacts"`
|
||||
} `json:"build"`
|
||||
@@ -93,7 +94,7 @@ func TestManifestDeclarations(t *testing.T) { // 1240/AC1
|
||||
// answers is the teller's answer to each ask; asked is what it asked of the router, which condition it raised and which
|
||||
// gate key and revision each ask was made at (issue 1343); ends is the ends asked by hand with teller_end_ask (issue 774).
|
||||
// first-views is where its first view of the assigner's asks stands and findings its condition past the bound (ADR 0615).
|
||||
if want := []state{{Name: "answers", History: 5}, {Name: "asked", History: 1}, {Name: "ends", History: 1}, {Name: "first-views", History: 1}, {Name: "findings", History: 1}}; !reflect.DeepEqual(m.State, want) {
|
||||
if want := []state{{Name: "answers", History: 5}, {Name: "asked", History: 1}, {Name: "ends", History: 1}, {Name: "first-views", History: 1}}; !reflect.DeepEqual(m.State, want) {
|
||||
t.Errorf("state = %+v, want %+v", m.State, want)
|
||||
}
|
||||
// The view's answers to the assigner's asks are read so the view's answer fills an ask that needs no proof (1297/B10); the
|
||||
@@ -133,14 +134,17 @@ func TestManifestDeclarations(t *testing.T) { // 1240/AC1
|
||||
t.Errorf("emits = %v, want %v", m.Emits, want)
|
||||
}
|
||||
// design 47 G §383, §387: the stream <module>-findings, 7 days and 16 MiB; §368: version is MAJOR.MINOR.
|
||||
if want := []stream{{Name: "mesh-delivery-teller-findings", Events: []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, MaxAgeDays: 7, MaxMiB: 16}}; !reflect.DeepEqual(m.Streams, want) {
|
||||
t.Errorf("streams = %+v, want %+v", m.Streams, want)
|
||||
if len(m.Streams) != 0 {
|
||||
t.Errorf("streams = %+v: the finding stream is a require now", m.Streams)
|
||||
}
|
||||
if want := findingRequires(1); !reflect.DeepEqual(m.Requires, want) {
|
||||
t.Errorf("requires = %+v, want %+v", m.Requires, want)
|
||||
}
|
||||
if m.Version != "0.1" {
|
||||
t.Errorf("version = %q, want 0.1", m.Version)
|
||||
}
|
||||
// No bus or seat (ADR 0437 §4).
|
||||
for _, k := range []string{"logs", "claims", "provides", "requires", "defines-seats", "seat", "seats", "bus"} {
|
||||
for _, k := range []string{"logs", "claims", "provides", "defines-seats", "seat", "seats", "bus"} {
|
||||
if _, ok := top[k]; ok {
|
||||
t.Errorf("the manifest declares %q: the teller has none", k)
|
||||
}
|
||||
@@ -243,3 +247,22 @@ func TestNoPartHandWritesItsBusConnection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// require is one entry of the manifest's requires: a provision the module asks for by a template (ADR 0595), which the
|
||||
// controller's reader takes.
|
||||
type require struct {
|
||||
Name string `json:"name"`
|
||||
Storage string `json:"storage"`
|
||||
Template string `json:"template"`
|
||||
Options map[string]any `json:"options"`
|
||||
}
|
||||
|
||||
// findingRequires is the findings state and the finding stream a module asks for by their templates (design 47 G
|
||||
// §383, §387; A-30): 7 days and 16 MiB, the findings state keeping the given history.
|
||||
func findingRequires(history float64) []require {
|
||||
return []require{
|
||||
{Name: "findings", Storage: "key-value", Template: "state", Options: map[string]any{"history": history}},
|
||||
{Name: "finding-events", Storage: "stream", Template: "events", Options: map[string]any{
|
||||
"events": []any{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, "max-age-days": float64(7), "max-mib": float64(16)}},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ type manifest struct {
|
||||
OwnSecrets map[string]string `json:"own-secrets"`
|
||||
SecretsOwner string `json:"secrets-owner"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Requires []require `json:"requires"`
|
||||
Items []item `json:"items"`
|
||||
Build struct {
|
||||
Artifacts []artifact `json:"artifacts"`
|
||||
@@ -128,8 +129,11 @@ func TestManifestIsTakenAndReadsOnly(t *testing.T) { // 1134/AC7
|
||||
t.Errorf("invokes = %v, want %v", m.Invokes, want)
|
||||
}
|
||||
// design 47 G §387: the keeper's ask for the findings is heard, the finding stream declared (§383), and §368: version is MAJOR.MINOR.
|
||||
if want := []stream{{Name: "mesh-delivery-view-findings", Events: []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, MaxAgeDays: 7, MaxMiB: 16}}; !reflect.DeepEqual(m.Streams, want) {
|
||||
t.Errorf("streams = %+v, want %+v", m.Streams, want)
|
||||
if len(m.Streams) != 0 {
|
||||
t.Errorf("streams = %+v: the finding stream is a require now", m.Streams)
|
||||
}
|
||||
if want := findingRequires(1); !reflect.DeepEqual(m.Requires, want) {
|
||||
t.Errorf("requires = %+v, want %+v", m.Requires, want)
|
||||
}
|
||||
if m.Version != "0.1" {
|
||||
t.Errorf("version = %q, want 0.1", m.Version)
|
||||
@@ -149,7 +153,7 @@ func TestManifestIsTakenAndReadsOnly(t *testing.T) { // 1134/AC7
|
||||
// The states the view writes: the operator's answers to the asks that need no proof (ADR 0528 clause 6, 1297/B9), which the
|
||||
// teller reads, and how far each repository reached (ADR 0556 clause 2, issue 1280), which the gate reads.
|
||||
// Its first views of the owners' states and the finding of one unanswered past its bound (ADR 0615 §6).
|
||||
if want := []state{{Name: "answers", History: 5}, {Name: "reach", History: 1}, {Name: "first-views", History: 1}, {Name: "findings", History: 1}}; !reflect.DeepEqual(m.State, want) {
|
||||
if want := []state{{Name: "answers", History: 5}, {Name: "reach", History: 1}, {Name: "first-views", History: 1}}; !reflect.DeepEqual(m.State, want) {
|
||||
t.Errorf("state = %+v, want %+v", m.State, want)
|
||||
}
|
||||
if _, ok := m.OwnSecrets["broker"]; !ok || len(m.OwnSecrets) != 1 {
|
||||
@@ -430,3 +434,22 @@ func TestEveryStateTheCommandsReadIsIssued(t *testing.T) {
|
||||
t.Fatal("no stdio.State literal found under cmd/: the scan reads nothing")
|
||||
}
|
||||
}
|
||||
|
||||
// require is one entry of the manifest's requires: a provision the module asks for by a template (ADR 0595), which the
|
||||
// controller's reader takes.
|
||||
type require struct {
|
||||
Name string `json:"name"`
|
||||
Storage string `json:"storage"`
|
||||
Template string `json:"template"`
|
||||
Options map[string]any `json:"options"`
|
||||
}
|
||||
|
||||
// findingRequires is the findings state and the finding stream a module asks for by their templates (design 47 G
|
||||
// §383, §387; A-30): 7 days and 16 MiB, the findings state keeping the given history.
|
||||
func findingRequires(history float64) []require {
|
||||
return []require{
|
||||
{Name: "findings", Storage: "key-value", Template: "state", Options: map[string]any{"history": history}},
|
||||
{Name: "finding-events", Storage: "stream", Template: "events", Options: map[string]any{
|
||||
"events": []any{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, "max-age-days": float64(7), "max-mib": float64(16)}},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ type manifest struct {
|
||||
OwnSecrets map[string]string `json:"own-secrets"`
|
||||
SecretsOwner string `json:"secrets-owner"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Requires []require `json:"requires"`
|
||||
Build struct {
|
||||
Artifacts []artifact `json:"artifacts"`
|
||||
} `json:"build"`
|
||||
@@ -95,7 +96,7 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6
|
||||
if m.Module != "mesh-delivery-watchman" || m.Moved || m.Slug != "watchman" {
|
||||
t.Errorf("module %q moved %v (it has no template, so it is not moved) slug %q", m.Module, m.Moved, m.Slug)
|
||||
}
|
||||
want := []state{{Name: "presence", History: 20}, {Name: "pulse", KeyTTL: true}, {Name: "stuck", History: 20}, {Name: "findings", History: 5}, {Name: "first-views", History: 1}}
|
||||
want := []state{{Name: "presence", History: 20}, {Name: "pulse", KeyTTL: true}, {Name: "stuck", History: 20}, {Name: "first-views", History: 1}}
|
||||
if !reflect.DeepEqual(m.State, want) {
|
||||
t.Errorf("state = %+v, want %+v", m.State, want)
|
||||
}
|
||||
@@ -110,9 +111,11 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6
|
||||
t.Errorf("version = %q, want MAJOR.MINOR", m.Version)
|
||||
}
|
||||
// Design 47 G §387: the finding stream, 7 days and 16 MiB, and the keeper's ask.
|
||||
if len(m.Streams) != 1 || m.Streams[0].Name != "mesh-delivery-watchman-findings" || m.Streams[0].MaxAgeDays != 7 || m.Streams[0].MaxMiB != 16 ||
|
||||
!reflect.DeepEqual(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) {
|
||||
t.Errorf("streams = %+v, want the finding stream", m.Streams)
|
||||
if len(m.Streams) != 0 {
|
||||
t.Errorf("streams = %+v: the finding stream is a require now", m.Streams)
|
||||
}
|
||||
if want := findingRequires(5); !reflect.DeepEqual(m.Requires, want) {
|
||||
t.Errorf("requires = %+v, want %+v", m.Requires, want)
|
||||
}
|
||||
// DLV-M5 (ADR 0615 §1): the assigner's wants and the indexer's modules are their owners' states, asked by their read
|
||||
// tools and followed by their views families, never read.
|
||||
@@ -266,3 +269,22 @@ func TestNoTickerTimerOrSleep(t *testing.T) { // 1135/AC7
|
||||
t.Fatalf("read %d source files, want the program's", files)
|
||||
}
|
||||
}
|
||||
|
||||
// require is one entry of the manifest's requires: a provision the module asks for by a template (ADR 0595), which the
|
||||
// controller's reader takes.
|
||||
type require struct {
|
||||
Name string `json:"name"`
|
||||
Storage string `json:"storage"`
|
||||
Template string `json:"template"`
|
||||
Options map[string]any `json:"options"`
|
||||
}
|
||||
|
||||
// findingRequires is the findings state and the finding stream a module asks for by their templates (design 47 G
|
||||
// §383, §387; A-30): 7 days and 16 MiB, the findings state keeping the given history.
|
||||
func findingRequires(history float64) []require {
|
||||
return []require{
|
||||
{Name: "findings", Storage: "key-value", Template: "state", Options: map[string]any{"history": history}},
|
||||
{Name: "finding-events", Storage: "stream", Template: "events", Options: map[string]any{
|
||||
"events": []any{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, "max-age-days": float64(7), "max-mib": float64(16)}},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user