Files
mesh-delivery/modules/mesh-delivery-checker/internal/check/kept.go
T

91 lines
2.8 KiB
Go

package check
import (
"context"
"errors"
"fmt"
"sort"
"time"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// Kept is the checker's bucket of kept verdicts (ADR 0444, ADR 0484 clause 13): a passing verdict per package and level,
// under the digest the language's build module named for it. A key is written once, by a create that fails when it
// exists, from the result the checker read from the test step and never from anything the code under test wrote; nothing
// changes it afterwards.
type Kept struct{ Store KV }
// Lookup is the kept verdict of a level under a digest, or none.
func (k Kept) Lookup(ctx context.Context, level, digest string) (delivery.Kept, bool, error) {
key, err := delivery.KeptKey(level, digest)
if err != nil {
return delivery.Kept{}, false, err
}
value, _, found, err := k.Store.Get(ctx, key)
if err != nil || !found {
return delivery.Kept{}, false, err
}
v, err := delivery.DecodeKept(value)
if err != nil {
return delivery.Kept{}, false, fmt.Errorf("%s holds what is not a kept verdict: %w", key, err)
}
return v, true, nil
}
// Keep writes v under level and digest by a create. It answers false, and writes nothing, when the key exists: the first
// value stands.
func (k Kept) Keep(ctx context.Context, level, digest string, v delivery.Kept) (bool, error) {
key, err := delivery.KeptKey(level, digest)
if err != nil {
return false, err
}
v.Level = level
data, err := delivery.EncodeKept(v)
if err != nil {
return false, err
}
if _, err := k.Store.Create(ctx, key, data); err != nil {
if errors.Is(err, ErrConflict) {
return false, nil
}
return false, fmt.Errorf("%s: %w", key, err)
}
return true, nil
}
// KeepPasses keeps, for the packages of a test result that passed with tests, a verdict under the digest the build module
// named for the package at the level. A package that failed, has no tests or has no digest is never kept (ADR 0444 clause
// 1): it runs every check. It answers the packages it kept now.
func (k Kept) KeepPasses(ctx context.Context, repository, level, toolchain string, res Tested, digests map[string]string, at time.Time) ([]string, error) {
var kept []string
for _, p := range res.Packages {
digest, ok := digests[p.Package]
if !ok || !p.Passed || p.NoTests || p.Tests == 0 {
continue
}
if failedIn(res, p.Package) {
continue
}
made, err := k.Keep(ctx, level, digest, delivery.Kept{State: delivery.VerdictPass, Repository: repository, Package: p.Package,
Level: level, Tests: p.Tests, Took: int64(p.Elapsed * 1000), Toolchain: toolchain, At: at})
if err != nil {
return kept, err
}
if made {
kept = append(kept, p.Package)
}
}
sort.Strings(kept)
return kept, nil
}
func failedIn(res Tested, pkg string) bool {
for _, f := range res.Failed {
if f.Package == pkg {
return true
}
}
return false
}