J3 (A2i finding 2): a build's end names the generated files its test step found out of step
delivery.BuildLogEntry gains out-of-step, an end's alone, as the build module's test step answers it, so the indexer reads the field from the entry, not the raw message, and its trunk finding can be raised once the builder writes it. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -179,6 +179,10 @@ type BuildLogEntry struct {
|
||||
// sorted and each once, as the build module answered them (BuildAnswer.Imports; novox/hq ADR 0593 §2): the indexer
|
||||
// keeps them on the module (KeptInputs2.Imports) when the build's fingerprint is the module's.
|
||||
Imports []string `json:"imports,omitempty"`
|
||||
// OutOfStep are, at a build's end, the generated files its test step found out of step with what their generator
|
||||
// writes, as the build module answered them (its test step's `out-of-step`): the indexer raises a finding naming them
|
||||
// for a trunk build, and only a clean build of the same module clears it. A start or a narration names none.
|
||||
OutOfStep []string `json:"out-of-step,omitempty"`
|
||||
// Line is a narration's words, Why what it narrates (asked, waiting, stored, refused): a build.said entry's alone.
|
||||
Line string `json:"line,omitempty"`
|
||||
Why string `json:"why,omitempty"`
|
||||
@@ -225,8 +229,8 @@ func EncodeBuildLogEntry(e BuildLogEntry) ([]byte, error) {
|
||||
switch {
|
||||
case e.Module == "" || e.FP == "" || e.At.IsZero() || e.Line == "":
|
||||
return nil, fmt.Errorf("delivery: a build's narration names its module, fingerprint, line and time")
|
||||
case e.Outcome != "" || len(e.Made) > 0 || e.Manifest != "" || len(e.Against) > 0 || len(e.Imports) > 0:
|
||||
return nil, fmt.Errorf("delivery: a build's narration names no outcome, manifest, base, artifact or import")
|
||||
case e.Outcome != "" || len(e.Made) > 0 || e.Manifest != "" || len(e.Against) > 0 || len(e.Imports) > 0 || len(e.OutOfStep) > 0:
|
||||
return nil, fmt.Errorf("delivery: a build's narration names no outcome, manifest, base, artifact, import or file out of step")
|
||||
}
|
||||
return json.Marshal(e)
|
||||
case e.Event != BuildStartedEvent && e.Event != BuildEndedEvent:
|
||||
@@ -237,8 +241,9 @@ func EncodeBuildLogEntry(e BuildLogEntry) ([]byte, error) {
|
||||
return nil, fmt.Errorf("delivery: a build log entry names its module, fingerprint, repository, commit, node and time")
|
||||
case e.Event == BuildEndedEvent && e.Outcome == "":
|
||||
return nil, fmt.Errorf("delivery: a build's end names its outcome")
|
||||
case e.Event == BuildStartedEvent && (e.Outcome != "" || len(e.Made) > 0 || e.Manifest != "" || len(e.Against) > 0 || len(e.Imports) > 0):
|
||||
return nil, fmt.Errorf("delivery: a build's start names no outcome, manifest, base, artifact or import")
|
||||
case e.Event == BuildStartedEvent && (e.Outcome != "" || len(e.Made) > 0 || e.Manifest != "" || len(e.Against) > 0 || len(e.Imports) > 0 ||
|
||||
len(e.OutOfStep) > 0):
|
||||
return nil, fmt.Errorf("delivery: a build's start names no outcome, manifest, base, artifact, import or file out of step")
|
||||
}
|
||||
if err := CheckImports(e.Imports); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -57,17 +57,23 @@ func TestPublishedPackagesAndImportsRoundTripAndRefuse(t *testing.T) {
|
||||
}
|
||||
|
||||
imports := []string{sdk, sdk + "/announce"}
|
||||
outOfStep := []string{"go/seats/meshbroker/contract.go", "ts/seats/meshbroker/src/index.ts"}
|
||||
end := BuildLogEntry{Event: BuildEndedEvent, Module: "netcheck", FP: "src2:x", Repository: "novox/mesh-catalog", Commit: commit,
|
||||
Node: "ace", At: good.At, Outcome: "done", Imports: imports}
|
||||
Node: "ace", At: good.At, Outcome: "done", Imports: imports, OutOfStep: outOfStep}
|
||||
raw, err = EncodeBuildLogEntry(end)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if e, err := DecodeBuildLogEntry(raw); err != nil || !reflect.DeepEqual(e.Imports, imports) {
|
||||
t.Fatalf("build end round trip: %v, %v", err, e.Imports)
|
||||
if e, err := DecodeBuildLogEntry(raw); err != nil || !reflect.DeepEqual(e.Imports, imports) || !reflect.DeepEqual(e.OutOfStep, outOfStep) ||
|
||||
!strings.Contains(string(raw), `"out-of-step":["go/seats/meshbroker/contract.go",`) {
|
||||
t.Fatalf("build end round trip: %v, %v, %v in %s", err, e.Imports, e.OutOfStep, raw)
|
||||
}
|
||||
start := end
|
||||
start.Event, start.Outcome = BuildStartedEvent, ""
|
||||
start.Event, start.Outcome, start.Imports = BuildStartedEvent, "", nil
|
||||
if _, err := EncodeBuildLogEntry(start); err == nil {
|
||||
t.Error("a build's start with files out of step encoded")
|
||||
}
|
||||
start.Imports, start.OutOfStep = imports, nil
|
||||
if _, err := EncodeBuildLogEntry(start); err == nil {
|
||||
t.Error("a build's start with imports encoded")
|
||||
}
|
||||
@@ -87,6 +93,7 @@ func TestPublishedPackagesAndImportsRoundTripAndRefuse(t *testing.T) {
|
||||
for name, mutate := range map[string]func(e *BuildLogEntry){
|
||||
"a narration with no line": func(e *BuildLogEntry) { e.Line = "" },
|
||||
"a narration with an outcome": func(e *BuildLogEntry) { e.Outcome = "done" },
|
||||
"a narration out of step": func(e *BuildLogEntry) { e.OutOfStep = outOfStep },
|
||||
"an end with a line": func(e *BuildLogEntry) {
|
||||
e.Event, e.Outcome, e.Node, e.Repository, e.Commit = BuildEndedEvent, "done", "ace", "novox/mesh-catalog", commit
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user