Let a module that builds no artifact have a done key that can be delivered (issue 1613, the lead's request for the builder lane)
A done key needs its manifest digest, no longer an artifact; Referenced answers ok for it, since no artifact lacks a reference.
This commit is contained in:
@@ -125,14 +125,15 @@ func (a BuiltArtifact) referenceProblem() string {
|
||||
}
|
||||
|
||||
// Referenced says whether b is done and every artifact names where it is, which the controller delivers from (novox/hq
|
||||
// ADR 0498 clause 8), and names the artifacts that name no reference.
|
||||
// ADR 0498 clause 8), and names the artifacts that name no reference. A done key with no artifact (a module that builds
|
||||
// none, issue 1613) is referenced.
|
||||
func (b BuilderBuild) Referenced() (ok bool, missing []string) {
|
||||
for _, a := range b.Artifacts {
|
||||
if a.Reference == "" {
|
||||
missing = append(missing, a.Name)
|
||||
}
|
||||
}
|
||||
return b.State == BuildDone && len(b.Artifacts) > 0 && len(missing) == 0, missing
|
||||
return b.State == BuildDone && len(missing) == 0, missing
|
||||
}
|
||||
|
||||
// The prefixes of a failed key's error that a build module answers (novox/hq ADR 0498 clauses 2, 4 and 5; ADR 0478
|
||||
@@ -226,9 +227,7 @@ func (b BuilderBuild) check() error {
|
||||
return fmt.Errorf("delivery: a %s build carries no artifact and no error", b.State)
|
||||
}
|
||||
case BuildDone:
|
||||
if len(b.Artifacts) == 0 {
|
||||
return fmt.Errorf("delivery: a done build names no artifact")
|
||||
}
|
||||
// A module that builds no artifact gets a done key too, and is delivered from it (issue 1613).
|
||||
if b.Manifest == "" {
|
||||
return fmt.Errorf("delivery: a done build names no manifest digest")
|
||||
}
|
||||
@@ -243,8 +242,8 @@ func (b BuilderBuild) check() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeBuilderBuild is b as JSON at Version; it refuses a build its state does not allow (done without artifacts or a
|
||||
// manifest digest, failed without an error, an artifact without a name or digest, a toolchain without a version or a
|
||||
// EncodeBuilderBuild is b as JSON at Version; it refuses a build its state does not allow (done without a manifest
|
||||
// digest, failed without an error, an artifact without a name or digest, a toolchain without a version or a
|
||||
// recipe version).
|
||||
func EncodeBuilderBuild(b BuilderBuild) ([]byte, error) {
|
||||
if err := b.check(); err != nil {
|
||||
|
||||
@@ -116,3 +116,20 @@ func TestAKeyWaitsQueuedForAPackageVersion(t *testing.T) {
|
||||
t.Fatal("a wait naming no version was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
// A module that builds no artifact gets a done key too (issue 1613), and it is delivered: Referenced is ok for a done
|
||||
// key with no artifact, since no artifact lacks a reference; a queued one with none still is not.
|
||||
func TestADoneKeyWithNoArtifactIsReferenced(t *testing.T) {
|
||||
b := BuilderBuild{State: BuildDone, Manifest: digestOf('4')}
|
||||
data, err := EncodeBuilderBuild(b)
|
||||
if err != nil {
|
||||
t.Fatalf("a done key with no artifact was refused: %v", err)
|
||||
}
|
||||
back, err := DecodeBuilderBuild(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ok, missing := back.Referenced(); !ok || len(missing) != 0 {
|
||||
t.Fatalf("Referenced = %v, %v; want true", ok, missing)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,14 +83,13 @@ func TestBuilderBuildRoundTrip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 1358/AC3: done without artifacts or without a manifest digest, failed without an error, an artifact without a digest
|
||||
// 1358/AC3: done without a manifest digest, failed without an error, an artifact without a digest
|
||||
// and an unknown state are refused.
|
||||
func TestBuilderBuildChecked(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
edit func(*BuilderBuild)
|
||||
words []string
|
||||
}{
|
||||
"done without artifacts": {func(b *BuilderBuild) { b.Artifacts = nil }, []string{"artifact"}},
|
||||
"done without a manifest": {func(b *BuilderBuild) { b.Manifest = "" }, []string{"manifest"}},
|
||||
"a malformed manifest": {func(b *BuilderBuild) { b.Manifest = "abc" }, []string{"abc"}},
|
||||
"an artifact without a digest": {func(b *BuilderBuild) { b.Artifacts[1].Digest = "" }, []string{"digest", "server"}},
|
||||
@@ -125,8 +124,8 @@ func TestBuilderBuildChecked(t *testing.T) {
|
||||
t.Error("a queued build with artifacts accepted")
|
||||
}
|
||||
// decode refuses what encode refuses
|
||||
if _, err := DecodeBuilderBuild([]byte(`{"v":1,"state":"done","manifest":"` + digestOf('4') + `"}`)); err == nil {
|
||||
t.Error("decoded a done build without artifacts")
|
||||
if _, err := DecodeBuilderBuild([]byte(`{"v":1,"state":"done"}`)); err == nil {
|
||||
t.Error("decoded a done build without a manifest digest")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user