4 Commits
Author SHA1 Message Date
cat 17383ab353 internal/rosa/package/gnu: disable flaky coreutils test
Test / Flake checks (push) Successful in 2m43s
Test / ShareFS (push) Successful in 57s
Test / Sandbox (push) Successful in 1m20s
Test / Sandbox (race detector) (push) Successful in 1m23s
Test / Hakurei (push) Successful in 1m26s
Test / Hakurei (race detector) (push) Successful in 1m31s
Test / Create distribution (push) Successful in 46s
Another flaky test, once disabled but removed during an upgrade.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-07-09 10:50:53 +09:00
cat 237e793895 internal/rosa: respect preferred loadavg target
Test / Create distribution (push) Successful in 56s
Test / Sandbox (push) Successful in 2m54s
Test / ShareFS (push) Successful in 3m57s
Test / Hakurei (push) Successful in 4m4s
Test / Sandbox (race detector) (push) Successful in 5m36s
Test / Hakurei (race detector) (push) Successful in 6m58s
Test / Flake checks (push) Successful in 1m11s
This generally improves build performance and system responsiveness.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-07-09 10:08:08 +09:00
cat 6cfd8fb934 internal/pkg: loadavg target in container environment
Test / Create distribution (push) Successful in 56s
Test / Sandbox (push) Successful in 3m2s
Test / ShareFS (push) Successful in 3m58s
Test / Hakurei (push) Successful in 4m5s
Test / Sandbox (race detector) (push) Successful in 5m29s
Test / Hakurei (race detector) (push) Successful in 6m40s
Test / Flake checks (push) Successful in 1m4s
This exposes preferred loadavg target to the container initial process.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-07-09 09:45:43 +09:00
cat 2f1534853a internal/pkg: consolidate cache attributes
Test / Create distribution (push) Successful in 54s
Test / Sandbox (push) Successful in 2m58s
Test / ShareFS (push) Successful in 3m56s
Test / Hakurei (push) Successful in 3m59s
Test / Sandbox (race detector) (push) Successful in 5m31s
Test / Hakurei (race detector) (push) Successful in 6m38s
Test / Flake checks (push) Successful in 1m5s
This makes the interface stable.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-07-09 09:34:27 +09:00
21 changed files with 146 additions and 103 deletions
+6 -9
View File
@@ -21,7 +21,7 @@ type cache struct {
// Should generally not be used directly. // Should generally not be used directly.
c *pkg.Cache c *pkg.Cache
cures, jobs int attr pkg.CacheAttr
// Primarily to work around missing landlock LSM. // Primarily to work around missing landlock LSM.
hostAbstract bool hostAbstract bool
// Set SCHED_IDLE. // Set SCHED_IDLE.
@@ -49,18 +49,17 @@ func (cache *cache) open() (err error) {
return return
} }
var flags int
if cache.idle { if cache.idle {
flags |= pkg.CSchedIdle cache.attr.Flags |= pkg.CSchedIdle
} }
if cache.hostAbstract { if cache.hostAbstract {
flags |= pkg.CHostAbstract cache.attr.Flags |= pkg.CHostAbstract
} }
if !cache.verboseInit { if !cache.verboseInit {
flags |= pkg.CSuppressInit cache.attr.Flags |= pkg.CSuppressInit
} }
if !cache.deep { if !cache.deep {
flags |= pkg.CExternShallow cache.attr.Flags |= pkg.CExternShallow
} }
done := make(chan struct{}) done := make(chan struct{})
@@ -82,10 +81,8 @@ func (cache *cache) open() (err error) {
cache.c, err = pkg.Open( cache.c, err = pkg.Open(
cache.ctx, cache.ctx,
cache.msg, cache.msg,
flags,
cache.cures,
cache.jobs,
base, base,
&cache.attr,
) )
if err != nil { if err != nil {
return return
+1 -1
View File
@@ -28,8 +28,8 @@ func TestNoReply(t *testing.T) {
c, err := pkg.Open( c, err := pkg.Open(
t.Context(), t.Context(),
message.New(log.New(os.Stderr, "cir: ", 0)), message.New(log.New(os.Stderr, "cir: ", 0)),
0, 0, 0,
check.MustAbs(t.TempDir()), check.MustAbs(t.TempDir()),
nil,
) )
if err != nil { if err != nil {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
+4 -4
View File
@@ -203,11 +203,11 @@ func main() {
"v", command.BoolFlag(false), "v", command.BoolFlag(false),
"Do not suppress verbose output from init", "Do not suppress verbose output from init",
).Flag( ).Flag(
&cm.cures, &cm.attr.Cures,
"cures", command.IntFlag(0), "cures", command.IntFlag(0),
"Maximum number of dependencies to cure at any given time", "Maximum number of dependencies to cure at any given time",
).Flag( ).Flag(
&cm.jobs, &cm.attr.Jobs,
"jobs", command.IntFlag(0), "jobs", command.IntFlag(0),
"Preferred number of jobs to run, when applicable", "Preferred number of jobs to run, when applicable",
).Flag( ).Flag(
@@ -934,8 +934,8 @@ func main() {
return fmt.Errorf("unknown artifact %q", args[1]) return fmt.Errorf("unknown artifact %q", args[1])
} }
if !a.IsExclusive() && cm.jobs < 1 { if !a.IsExclusive() && cm.attr.Jobs < 1 {
cm.jobs = runtime.NumCPU()/n + 1 cm.attr.Jobs = runtime.NumCPU()/n + 1
} }
res := make([]unique.Handle[pkg.Checksum], n) res := make([]unique.Handle[pkg.Checksum], n)
+1 -1
View File
@@ -238,7 +238,7 @@ func TestClean(t *testing.T) {
base := makeBase(t) base := makeBase(t)
msg := message.New(log.New(os.Stderr, "clean: ", 0)) msg := message.New(log.New(os.Stderr, "clean: ", 0))
msg.SwapVerbose(testing.Verbose()) msg.SwapVerbose(testing.Verbose())
c, err := pkg.Open(t.Context(), msg, 0, 0, 0, base) c, err := pkg.Open(t.Context(), msg, base, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
+19 -9
View File
@@ -30,10 +30,16 @@ import (
// AbsWork is the container pathname [TContext.GetWorkDir] is mounted on. // AbsWork is the container pathname [TContext.GetWorkDir] is mounted on.
var AbsWork = fhs.AbsRoot.Append("work/") var AbsWork = fhs.AbsRoot.Append("work/")
// EnvJobs is the name of the environment variable holding a decimal const (
// representation of the preferred job count. Its value must not affect cure // EnvJobs is the name of the environment variable holding a decimal
// outcome. // representation of the preferred job count. Its value must not affect cure
const EnvJobs = "CURE_JOBS" // outcome.
EnvJobs = "CURE_JOBS"
// EnvLoad is the name of the environment variable holding a decimal
// representation of the preferred loadavg target. Its value must not affect
// cure outcome.
EnvLoad = "CURE_LOAD"
)
// ExecPath is a slice of [Artifact] and the [check.Absolute] pathname to make // ExecPath is a slice of [Artifact] and the [check.Absolute] pathname to make
// it available at under in the container. // it available at under in the container.
@@ -471,7 +477,7 @@ const SeccompPresets = std.PresetStrict &
func (a *execArtifact) makeContainer( func (a *execArtifact) makeContainer(
ctx context.Context, ctx context.Context,
msg message.Msg, msg message.Msg,
flags, jobs int, flags, jobs, load int,
hostNet bool, hostNet bool,
temp, work *check.Absolute, temp, work *check.Absolute,
getArtifact GetArtifactFunc, getArtifact GetArtifactFunc,
@@ -508,7 +514,10 @@ func (a *execArtifact) makeContainer(
z.Quiet = flags&CSuppressInit != 0 z.Quiet = flags&CSuppressInit != 0
z.Uid, z.Gid = (1<<10)-1, (1<<10)-1 z.Uid, z.Gid = (1<<10)-1, (1<<10)-1
z.Dir, z.Path, z.Args = a.dir, a.path, a.args z.Dir, z.Path, z.Args = a.dir, a.path, a.args
z.Env = slices.Concat(a.env, []string{EnvJobs + "=" + strconv.Itoa(jobs)}) z.Env = slices.Concat(a.env, []string{
EnvJobs + "=" + strconv.Itoa(jobs),
EnvLoad + "=" + strconv.Itoa(load),
})
z.Grow(len(a.paths) + 4) z.Grow(len(a.paths) + 4)
if a.arch != runtime.GOARCH { if a.arch != runtime.GOARCH {
@@ -649,8 +658,9 @@ func (c *Cache) EnterExec(
var z *container.Container var z *container.Container
z, err = e.makeContainer( z, err = e.makeContainer(
ctx, c.msg, ctx, c.msg,
c.flags, c.attr.Flags,
c.jobs, c.attr.Jobs,
c.attr.Load,
hostNet, hostNet,
temp, work, temp, work,
func(a Artifact) (*check.Absolute, unique.Handle[Checksum]) { func(a Artifact) (*check.Absolute, unique.Handle[Checksum]) {
@@ -693,7 +703,7 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) {
msg := f.GetMessage() msg := f.GetMessage()
var z *container.Container var z *container.Container
if z, err = a.makeContainer( if z, err = a.makeContainer(
ctx, msg, f.cache.flags, f.GetJobs(), hostNet, ctx, msg, f.cache.attr.Flags, f.GetJobs(), f.GetLoad(), hostNet,
f.GetTempDir(), f.GetWorkDir(), f.GetTempDir(), f.GetWorkDir(),
f.GetArtifact, f.GetArtifact,
f.cache.Ident, f.cache.Ident,
+9 -1
View File
@@ -38,7 +38,15 @@ func main() {
} }
environ := slices.DeleteFunc(slices.Clone(os.Environ()), func(s string) bool { environ := slices.DeleteFunc(slices.Clone(os.Environ()), func(s string) bool {
return s == "CURE_JOBS="+strconv.Itoa(runtime.NumCPU()) for _, t := range []string{
"CURE_JOBS=" + strconv.Itoa(runtime.NumCPU()),
"CURE_LOAD=" + strconv.Itoa(runtime.NumCPU()+2),
} {
if s == t {
return true
}
}
return false
}) })
var hostNet, layers, promote bool var hostNet, layers, promote bool
+46 -33
View File
@@ -279,7 +279,11 @@ func (c *common) GetMessage() message.Msg { return c.cache.msg }
// GetJobs returns the preferred number of jobs to run, when applicable. Its // GetJobs returns the preferred number of jobs to run, when applicable. Its
// value must not affect cure outcome. // value must not affect cure outcome.
func (c *common) GetJobs() int { return c.cache.jobs } func (c *common) GetJobs() int { return c.cache.attr.Jobs }
// GetLoad returns the preferred load average target, when applicable. Its
// value must not affect cure outcome.
func (c *common) GetLoad() int { return c.cache.attr.Load }
// GetWorkDir returns a pathname to a directory which [Artifact] is expected to // GetWorkDir returns a pathname to a directory which [Artifact] is expected to
// write its output to. This is not the final resting place of the [Artifact] // write its output to. This is not the final resting place of the [Artifact]
@@ -741,10 +745,8 @@ type Cache struct {
// Directory where all [Cache] related files are placed. // Directory where all [Cache] related files are placed.
base *check.Absolute base *check.Absolute
// Immutable cure options set by [Open]. // Immutable [CacheAttr] populated by [Open].
flags int attr CacheAttr
// Immutable job count, when applicable.
jobs int
// Must not be exposed directly. // Must not be exposed directly.
irCache irCache
@@ -1449,7 +1451,7 @@ func (c *Cache) openFile(
ctx context.Context, ctx context.Context,
f FileArtifact, f FileArtifact,
) (r io.ReadCloser, err error) { ) (r io.ReadCloser, err error) {
if kc, ok := f.(KnownChecksum); c.flags&CAssumeChecksum != 0 && ok { if kc, ok := f.(KnownChecksum); c.attr.Flags&CAssumeChecksum != 0 && ok {
c.checksumMu.RLock() c.checksumMu.RLock()
r, err = os.Open(c.base.Append( r, err = os.Open(c.base.Append(
dirChecksum, dirChecksum,
@@ -2141,7 +2143,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
checksums, checksums,
) )
if c.flags&CAssumeChecksum != 0 { if c.attr.Flags&CAssumeChecksum != 0 {
c.checksumMu.RLock() c.checksumMu.RLock()
checksumFi, err = os.Stat(checksumPathname.String()) checksumFi, err = os.Stat(checksumPathname.String())
c.checksumMu.RUnlock() c.checksumMu.RUnlock()
@@ -2210,7 +2212,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
} }
r, err = f.Cure(&RContext{common{ctx, c}}) r, err = f.Cure(&RContext{common{ctx, c}})
if err == nil { if err == nil {
if checksumPathname == nil || c.flags&CValidateKnown != 0 { if checksumPathname == nil || c.attr.Flags&CValidateKnown != 0 {
h := sha512.New384() h := sha512.New384()
hbw := c.getWriter(h) hbw := c.getWriter(h)
_, err = io.Copy(w, io.TeeReader(r, hbw)) _, err = io.Copy(w, io.TeeReader(r, hbw))
@@ -2227,7 +2229,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
if checksumPathname == nil { if checksumPathname == nil {
checksum = unique.Make(Checksum(buf[:])) checksum = unique.Make(Checksum(buf[:]))
checksums = Encode(Checksum(buf[:])) checksums = Encode(Checksum(buf[:]))
} else if c.flags&CValidateKnown != 0 { } else if c.attr.Flags&CValidateKnown != 0 {
if got := Checksum(buf[:]); got != checksum.Value() { if got := Checksum(buf[:]); got != checksum.Value() {
err = &ChecksumMismatchError{ err = &ChecksumMismatchError{
Got: got, Got: got,
@@ -2319,7 +2321,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
return return
} }
extern := externChecksum != zeroChecksum extern := externChecksum != zeroChecksum
shallow := extern && c.flags&CExternShallow != 0 shallow := extern && c.attr.Flags&CExternShallow != 0
inputs := a.Inputs() inputs := a.Inputs()
f := FContext{t, make(map[Artifact]cureRes, len(inputs))} f := FContext{t, make(map[Artifact]cureRes, len(inputs))}
@@ -2383,7 +2385,7 @@ func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
substitutes, substitutes,
) )
if !rebuild && c.flags&CIgnoreSubstitutes == 0 { if !rebuild && c.attr.Flags&CIgnoreSubstitutes == 0 {
var substituteChecksum unique.Handle[Checksum] var substituteChecksum unique.Handle[Checksum]
substituteChecksum, err = c.loadSubstitute(substitute) substituteChecksum, err = c.loadSubstitute(substitute)
if err != nil { if err != nil {
@@ -2677,6 +2679,22 @@ var (
ErrWouldPromote = errors.New("operation would promote unextended cache") ErrWouldPromote = errors.New("operation would promote unextended cache")
) )
// CacheAttr holds the attributes that will be applied to a new [Cache] opened
// by [Open].
type CacheAttr struct {
// Concurrent cures of a [FloodArtifact] dependency graph.
Cures int
// Options affecting [Cache] behaviour.
Flags int
// Preferred job count, when applicable.
Jobs int
// Preferred loadavg target, when applicable.
Load int
// Omit the [lockedfile] lock.
skipLock bool
}
// Open returns the address of a newly opened instance of [Cache]. // Open returns the address of a newly opened instance of [Cache].
// //
// Concurrent cures of a [FloodArtifact] dependency graph is limited to the // Concurrent cures of a [FloodArtifact] dependency graph is limited to the
@@ -2693,20 +2711,8 @@ var (
func Open( func Open(
ctx context.Context, ctx context.Context,
msg message.Msg, msg message.Msg,
flags, cures, jobs int,
base *check.Absolute, base *check.Absolute,
) (*Cache, error) { attr *CacheAttr,
return open(ctx, msg, flags, cures, jobs, base, true)
}
// open implements Open but allows omitting the [lockedfile] lock when called
// from a test. This is used to simulate invalid states in the test suite.
func open(
ctx context.Context,
msg message.Msg,
flags, cures, jobs int,
base *check.Absolute,
lock bool,
) (*Cache, error) { ) (*Cache, error) {
openMu.Lock() openMu.Lock()
defer openMu.Unlock() defer openMu.Unlock()
@@ -2716,11 +2722,19 @@ func open(
panic("attempting to open cache with incomplete variant setup") panic("attempting to open cache with incomplete variant setup")
} }
if cures < 1 { var a CacheAttr
cures = runtime.NumCPU() if attr != nil {
a = *attr
} }
if jobs < 1 {
jobs = runtime.NumCPU() if a.Cures < 1 {
a.Cures = runtime.NumCPU()
}
if a.Jobs < 1 {
a.Jobs = runtime.NumCPU()
}
if a.Load < 1 {
a.Load = runtime.NumCPU() + 2
} }
for _, name := range []string{ for _, name := range []string{
@@ -2742,9 +2756,8 @@ func open(
c := Cache{ c := Cache{
parent: ctx, parent: ctx,
cures: make(chan struct{}, cures), cures: make(chan struct{}, a.Cures),
flags: flags, attr: a,
jobs: jobs,
msg: msg, msg: msg,
base: base, base: base,
@@ -2761,7 +2774,7 @@ func open(
} }
c.toplevel.Store(newToplevel(ctx)) c.toplevel.Store(newToplevel(ctx))
if lock || !testing.Testing() { if !a.skipLock || !testing.Testing() {
if unlock, err := lockedfile.MutexAt( if unlock, err := lockedfile.MutexAt(
base.Append(fileLock).String(), base.Append(fileLock).String(),
).Lock(); err != nil { ).Lock(); err != nil {
@@ -2822,7 +2835,7 @@ func open(
} }
} else if s := string(p); s == "" { } else if s := string(p); s == "" {
if extension != "" { if extension != "" {
if flags&CPromoteVariant == 0 { if a.Flags&CPromoteVariant == 0 {
c.unlock() c.unlock()
return nil, ErrWouldPromote return nil, ErrWouldPromote
} }
+33 -35
View File
@@ -35,14 +35,14 @@ import (
"hakurei.app/message" "hakurei.app/message"
) )
//go:linkname unsafeOpen hakurei.app/internal/pkg.open var skipLock = func() pkg.CacheAttr {
func unsafeOpen( var attr pkg.CacheAttr
ctx context.Context, *(*bool)(unsafe.Pointer(reflect.ValueOf(&attr).
msg message.Msg, Elem().
flags, cures, jobs int, FieldByName("skipLock").
base *check.Absolute, UnsafeAddr())) = true
lock bool, return attr
) (*pkg.Cache, error) }()
var ( var (
// extension is a string uniquely identifying a set of custom [Artifact] // extension is a string uniquely identifying a set of custom [Artifact]
@@ -339,7 +339,7 @@ func TestIdent(t *testing.T) {
var cache *pkg.Cache var cache *pkg.Cache
if a, err := check.NewAbs(t.TempDir()); err != nil { if a, err := check.NewAbs(t.TempDir()); err != nil {
t.Fatal(err) t.Fatal(err)
} else if cache, err = pkg.Open(t.Context(), msg, 0, 0, 0, a); err != nil { } else if cache, err = pkg.Open(t.Context(), msg, a, nil); err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Cleanup(cache.Close) t.Cleanup(cache.Close)
@@ -519,7 +519,10 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
} }
var scrubFunc func() error // scrub after hashing var scrubFunc func() error // scrub after hashing
if c, err := pkg.Open(t.Context(), msg, flags, 1<<4, 0, base); err != nil { if c, err := pkg.Open(t.Context(), msg, base, &pkg.CacheAttr{
Cures: 1 << 4,
Flags: flags,
}); err != nil {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
} else { } else {
t.Cleanup(c.Close) t.Cleanup(c.Close)
@@ -867,10 +870,10 @@ func TestCache(t *testing.T) {
}}, }},
}) })
if c0, err := unsafeOpen( if c0, err := pkg.Open(
t.Context(), t.Context(),
message.New(nil), message.New(nil),
0, 0, 0, base, false, base, &skipLock,
); err != nil { ); err != nil {
t.Fatalf("open: error = %v", err) t.Fatalf("open: error = %v", err)
} else { } else {
@@ -1141,10 +1144,10 @@ func TestCache(t *testing.T) {
), want, pkg.WSubstitute, nil}, ), want, pkg.WSubstitute, nil},
}) })
if c0, err := unsafeOpen( if c0, err := pkg.Open(
t.Context(), t.Context(),
message.New(nil), message.New(nil),
0, 0, 0, base, false, base, &skipLock,
); err != nil { ); err != nil {
t.Fatalf("open: error = %v", err) t.Fatalf("open: error = %v", err)
} else { } else {
@@ -2050,7 +2053,7 @@ func (a earlyFailureF) Cure(*pkg.FContext) error {
func BenchmarkEarlyDCE(b *testing.B) { func BenchmarkEarlyDCE(b *testing.B) {
msg := message.New(log.New(os.Stderr, "dce: ", 0)) msg := message.New(log.New(os.Stderr, "dce: ", 0))
msg.SwapVerbose(testing.Verbose()) msg.SwapVerbose(testing.Verbose())
c, err := pkg.Open(b.Context(), msg, 0, 0, 0, check.MustAbs(b.TempDir())) c, err := pkg.Open(b.Context(), msg, check.MustAbs(b.TempDir()), nil)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
@@ -2099,7 +2102,8 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), t.Context(),
message.New(nil), message.New(nil),
0, 0, 0, check.MustAbs(container.Nonexistent), check.MustAbs(container.Nonexistent),
nil,
); !reflect.DeepEqual(err, wantErr) { ); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr) t.Errorf("Open: error = %#v, want %#v", err, wantErr)
} }
@@ -2127,7 +2131,8 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), t.Context(),
message.New(nil), message.New(nil),
0, 0, 0, tempDir.Append("cache"), tempDir.Append("cache"),
nil,
); !reflect.DeepEqual(err, wantErr) { ); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr) t.Errorf("Open: error = %#v, want %#v", err, wantErr)
} }
@@ -2149,7 +2154,8 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), t.Context(),
message.New(nil), message.New(nil),
0, 0, 0, tempDir.Append("cache"), tempDir.Append("cache"),
nil,
); !reflect.DeepEqual(err, wantErr) { ); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr) t.Errorf("Open: error = %#v, want %#v", err, wantErr)
} }
@@ -2170,7 +2176,7 @@ func TestOpen(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), t.Context(),
message.New(nil), message.New(nil),
0, 0, 0, tempDir.Append("cache"), tempDir.Append("cache"), nil,
); !reflect.DeepEqual(err, wantErr) { ); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr) t.Errorf("Open: error = %#v, want %#v", err, wantErr)
} }
@@ -2223,8 +2229,8 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), t.Context(),
message.New(log.Default()), message.New(log.Default()),
0, 0, 0,
check.MustAbs(container.Nonexistent), check.MustAbs(container.Nonexistent),
nil,
); !errors.Is(err, os.ErrNotExist) { ); !errors.Is(err, os.ErrNotExist) {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
} }
@@ -2262,7 +2268,7 @@ func TestExtensionRegister(t *testing.T) {
pkg.Register(pkg.KindCustomOffset, nil) pkg.Register(pkg.KindCustomOffset, nil)
t.Cleanup(func() { opened = false }) t.Cleanup(func() { opened = false })
_, _ = pkg.Open(nil, nil, 0, 0, 0, nil) _, _ = pkg.Open(nil, nil, nil, nil)
panic("unreachable") panic("unreachable")
}) })
@@ -2273,11 +2279,7 @@ func TestExtensionRegister(t *testing.T) {
base := check.MustAbs(t.TempDir()) base := check.MustAbs(t.TempDir())
t.Cleanup(func() { opened = false }) t.Cleanup(func() { opened = false })
if c, err := pkg.Open( if c, err := pkg.Open(t.Context(), nil, base, nil); err != nil {
t.Context(), nil,
0, 0, 0,
base,
); err != nil {
t.Fatal(err) t.Fatal(err)
} else { } else {
c.Close() c.Close()
@@ -2305,8 +2307,7 @@ func TestExtensionRegister(t *testing.T) {
} }
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), nil, t.Context(), nil,
0, 0, 0, base, nil,
base,
); !reflect.DeepEqual(err, wantErr) { ); !reflect.DeepEqual(err, wantErr) {
t.Fatalf("Open: error = %v, want %v", err, wantErr) t.Fatalf("Open: error = %v, want %v", err, wantErr)
} }
@@ -2327,8 +2328,8 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), nil, t.Context(), nil,
0, 0, 0,
base, base,
nil,
); !reflect.DeepEqual(err, pkg.ErrWouldPromote) { ); !reflect.DeepEqual(err, pkg.ErrWouldPromote) {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
} }
@@ -2341,8 +2342,7 @@ func TestExtensionRegister(t *testing.T) {
if c, err := pkg.Open( if c, err := pkg.Open(
t.Context(), nil, t.Context(), nil,
pkg.CPromoteVariant, 0, 0, base, &pkg.CacheAttr{Flags: pkg.CPromoteVariant},
base,
); err != nil { ); err != nil {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
} else { } else {
@@ -2367,8 +2367,7 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), nil, t.Context(), nil,
0, 0, 0, base, nil,
base,
); !reflect.DeepEqual(err, pkg.ErrInvalidExtension) { ); !reflect.DeepEqual(err, pkg.ErrInvalidExtension) {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
} }
@@ -2385,8 +2384,7 @@ func TestExtensionRegister(t *testing.T) {
if _, err := pkg.Open( if _, err := pkg.Open(
t.Context(), nil, t.Context(), nil,
0, 0, 0, base, nil,
base,
); !reflect.DeepEqual(err, pkg.UnsupportedVariantError("rosa")) { ); !reflect.DeepEqual(err, pkg.UnsupportedVariantError("rosa")) {
t.Fatalf("Open: error = %v", err) t.Fatalf("Open: error = %v", err)
} }
+5
View File
@@ -18,6 +18,11 @@ const (
jobsLE = `"$(expr ` + jobsE + ` '*' 2)"` jobsLE = `"$(expr ` + jobsE + ` '*' 2)"`
// jobsLFlagE is expression for flag with double of preferred job count. // jobsLFlagE is expression for flag with double of preferred job count.
jobsLFlagE = `"-j$(expr ` + jobsE + ` '*' 2)"` jobsLFlagE = `"-j$(expr ` + jobsE + ` '*' 2)"`
// loadE is expression for preferred loadavg target set by [pkg].
loadE = `"$` + pkg.EnvLoad + `"`
// loadFlagE is expression for flag with preferred loadavg target.
loadFlagE = `"-l$` + pkg.EnvLoad + `"`
) )
// newTar wraps [pkg.NewHTTPGetTar] with a simpler function signature. // newTar wraps [pkg.NewHTTPGetTar] with a simpler function signature.
+3 -3
View File
@@ -61,10 +61,10 @@ func (attr *CMakeHelper) script(t Toolchain, name string) string {
} }
generate := "Ninja" generate := "Ninja"
test := "ninja " + jobsFlagE + " test" test := "ninja " + jobsFlagE + " " + loadFlagE + " test"
if attr.Make { if attr.Make {
generate = "'Unix Makefiles'" generate = "'Unix Makefiles'"
test = "make " + jobsFlagE + " test" test = "make " + jobsFlagE + " " + loadFlagE + " test"
} }
if attr.Test != "" { if attr.Test != "" {
test = attr.Test test = attr.Test
@@ -97,7 +97,7 @@ cmake -G ` + generate + ` \
}), " \\\n\t") + ` \ }), " \\\n\t") + ` \
-DCMAKE_INSTALL_PREFIX=/system \ -DCMAKE_INSTALL_PREFIX=/system \
'/usr/src/` + name + `/` + filepath.Join(attr.Append...) + `' '/usr/src/` + name + `/` + filepath.Join(attr.Append...) + `'
cmake --build . --parallel=` + jobsE + ` cmake --build . --parallel=` + jobsE + ` -- ` + loadFlagE + `
DESTDIR=/work cmake --install . DESTDIR=/work cmake --install .
` + script ` + script
} }
+1 -1
View File
@@ -365,7 +365,7 @@ ln -s clang++ /work/system/bin/c++
// on 3-stage determinism to test later stages. // on 3-stage determinism to test later stages.
SkipTest: t.stage.isStage0(), SkipTest: t.stage.isStage0(),
Test: "ninja " + jobsFlagE + " check-all", Test: "ninja " + jobsFlagE + " " + loadFlagE + " check-all",
}, },
_python, _python,
_perl, _perl,
+3 -1
View File
@@ -160,7 +160,8 @@ func (attr *MakeHelper) script(t Toolchain, name string) string {
scriptMake := ` scriptMake := `
make \ make \
` + jobsFlagE ` + jobsFlagE + ` \
` + loadFlagE
if len(attr.Make) > 0 { if len(attr.Make) > 0 {
scriptMake += " \\\n\t" + strings.Join(attr.Make, " \\\n\t") scriptMake += " \\\n\t" + strings.Join(attr.Make, " \\\n\t")
} }
@@ -170,6 +171,7 @@ make \
(!attr.SkipCheckEarly || !t.stage.isStage0()) { (!attr.SkipCheckEarly || !t.stage.isStage0()) {
scriptMake += attr.ScriptCheckEarly + `make \ scriptMake += attr.ScriptCheckEarly + `make \
` + jobsFlagE + ` \ ` + jobsFlagE + ` \
` + loadFlagE + ` \
` `
if len(attr.Check) > 0 { if len(attr.Check) > 0 {
scriptMake += strings.Join(attr.Check, " \\\n\t") scriptMake += strings.Join(attr.Check, " \\\n\t")
+1 -1
View File
@@ -31,7 +31,7 @@ func TestMirror(t *testing.T) {
msg.SwapVerbose(testing.Verbose()) msg.SwapVerbose(testing.Verbose())
var c *pkg.Cache var c *pkg.Cache
c, err = pkg.Open(t.Context(), msg, 0, 0, 0, base) c, err = pkg.Open(t.Context(), msg, base, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
+1 -1
View File
@@ -34,7 +34,7 @@ package firmware {
// requires pre-commit // requires pre-commit
skipCheck = true; skipCheck = true;
install = "make " + jobsFlagE + " DESTDIR=/work/system dedup"; install = "make " + jobsFlagE + " " + loadFlagE + " DESTDIR=/work/system dedup";
}; };
inputs = [ inputs = [
+1
View File
@@ -70,6 +70,7 @@ disable_test t5515-fetch-merge-logic
install = `make \ install = `make \
` + jobsFlagE + ` \ ` + jobsFlagE + ` \
` + loadFlagE + ` \
DESTDIR=/work \ DESTDIR=/work \
NO_INSTALL_HARDLINKS=1 \ NO_INSTALL_HARDLINKS=1 \
install`; install`;
+1
View File
@@ -372,6 +372,7 @@ test_disable '#!/bin/sh' tests/ls/hyperlink.sh
test_disable '#!/bin/sh' tests/misc/user.sh test_disable '#!/bin/sh' tests/misc/user.sh
test_disable '#!/bin/sh' tests/split/line-bytes.sh test_disable '#!/bin/sh' tests/split/line-bytes.sh
test_disable '#!/bin/sh' tests/ls/stat-vs-dirent.sh test_disable '#!/bin/sh' tests/ls/stat-vs-dirent.sh
test_disable '#!/bin/sh' tests/dd/sparse.sh
test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c test_disable 'int main(){return 0;}' gnulib-tests/test-chown.c
test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c test_disable 'int main(){return 0;}' gnulib-tests/test-fchownat.c
test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c test_disable 'int main(){return 0;}' gnulib-tests/test-lchown.c
+1
View File
@@ -111,6 +111,7 @@ install -Dm0500 \
make \ make \
` + jobsFlagE + ` \ ` + jobsFlagE + ` \
` + loadFlagE + ` \
-f /usr/src/kernel/Makefile \ -f /usr/src/kernel/Makefile \
O=/tmp/kbuild \ O=/tmp/kbuild \
LLVM=1 \ LLVM=1 \
+1 -1
View File
@@ -23,7 +23,7 @@ python3 /usr/src/ninja/configure.py \
--bootstrap --bootstrap
python3 /usr/src/ninja/configure.py \ python3 /usr/src/ninja/configure.py \
--gtest-source-dir=/usr/src/extra/googletest --gtest-source-dir=/usr/src/extra/googletest
./ninja ` + jobsFlagE + ` all ./ninja ` + jobsFlagE + ` ` + loadFlagE + ` all
`; `;
check = "./ninja_test"; check = "./ninja_test";
+3 -1
View File
@@ -32,11 +32,13 @@ func (attr *MakeMakerHelper) script(t Toolchain, _ string) string {
script := `perl Makefile.PL \ script := `perl Makefile.PL \
PREFIX=/system PREFIX=/system
make \ make \
` + jobsFlagE ` + jobsFlagE + ` \
` + loadFlagE
if !attr.SkipCheck && t.opts&OptSkipCheck == 0 { if !attr.SkipCheck && t.opts&OptSkipCheck == 0 {
script += ` script += `
make \ make \
` + jobsFlagE + ` \ ` + jobsFlagE + ` \
` + loadFlagE + ` \
test test
` `
} }
+3 -1
View File
@@ -61,7 +61,9 @@ func getCache(t *testing.T) *pkg.Cache {
msg := message.New(log.New(os.Stderr, "rosa: ", 0)) msg := message.New(log.New(os.Stderr, "rosa: ", 0))
msg.SwapVerbose(true) msg.SwapVerbose(true)
if buildTestCache, err = pkg.Open(ctx, msg, pkg.CSuppressInit, 0, 0, a); err != nil { if buildTestCache, err = pkg.Open(ctx, msg, a, &pkg.CacheAttr{
Flags: pkg.CSuppressInit,
}); err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
+3
View File
@@ -499,6 +499,9 @@ func (s *S) getFrame() azalea.Frame {
k("jobsLE"): jobsLE, k("jobsLE"): jobsLE,
k("jobsLFlagE"): jobsLFlagE, k("jobsLFlagE"): jobsLFlagE,
k("loadE"): loadE,
k("loadFlagE"): loadFlagE,
k("anityaFallback"): (*Versions).getStable, k("anityaFallback"): (*Versions).getStable,
k("anityaLegacyCPAN"): func(v *Versions) string { k("anityaLegacyCPAN"): func(v *Versions) string {
for _, e := range v.Stable { for _, e := range v.Stable {