Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ jobs:
go vet ./...
go vet -C tools ./...

# The third-party notices link the licence text this bundle copies into
# docs/assets/landing, which is generated rather than tracked.
- run:
name: Build the landing-page diagram
command: make docs-landing-assets

- run:
name: Check documentation links
command: python3 scripts/check-doc-links.py
Expand Down Expand Up @@ -416,7 +422,10 @@ jobs:
- install-fmpy

# One scripts/race-shard.sh shard per node: internal/exec/runtime alone peaks near
# 6.5 GB under -race, so it shares its 8 GB node only sequentially (tests/wasm, tools).
# 8.5 GB under -race, so it shares its 8 GB node only sequentially (tests/wasm, tools).
# The race detector's memory is per process and the corpus-wide exploration alone
# accounts for half of that peak, so the package runs as two processes: the
# exploration, then everything else (4 GB each).
- run:
name: Run Go race tests
command: |
Expand All @@ -429,10 +438,14 @@ jobs:
shard=${shards[$CIRCLE_NODE_INDEX]}
pkgs=$(scripts/race-shard.sh "$shard")
echo "shard $shard:"; echo "$pkgs"
go test -v -race -pgo=off -timeout 30m $pkgs
if [ "$shard" = runtime ]; then
exploration='^TestExploreWithIsExploreOverTheConformanceCorpus$'
go test -v -race -pgo=off -timeout 30m -run "$exploration" $pkgs
go test -v -race -pgo=off -timeout 30m -skip "$exploration" $pkgs
go test -v -race -pgo=off -timeout 30m ./tests/wasm
go test -C tools -v -race -pgo=off -timeout 30m ./...
else
go test -v -race -pgo=off -timeout 30m $pkgs
fi
no_output_timeout: 30m
environment:
Expand Down
32 changes: 27 additions & 5 deletions internal/exec/runtime/sweep_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,32 @@ func TestRunSweepWithKeepsEachRowsWritesToItself(t *testing.T) {
}
}

// metDeadline is a context whose deadline is met when the test says so rather than when a
// clock does, so a slow machine cannot meet it before every job has taken its first row.
type metDeadline struct {
context.Context
done chan struct{}
once sync.Once
}

func (d *metDeadline) Done() <-chan struct{} { return d.done }

func (d *metDeadline) Err() error {
select {
case <-d.done:
return context.DeadlineExceeded
default:
return nil
}
}

func (d *metDeadline) meet() { d.once.Do(func() { close(d.done) }) }

// A deadline met mid-sweep ends the sweep with context.DeadlineExceeded and no table: no row
// starts once the deadline is visible, the rows in flight finish and are discarded — an
// absence, never a partial answer — as one job reports when it meets the deadline between
// two rows. The rows the jobs take first wait out the deadline, so on any job count the
// rows started are exactly the jobs' first ones.
// two rows. The rows the jobs take first wait out the deadline, which the last of them to
// start meets, so on any job count the rows started are exactly the jobs' first ones.
func TestRunSweepWithStopsAtTheDeadline(t *testing.T) {
fresh, scope := sweepJobsFixture(t)
first := firstOf(t, fresh)
Expand All @@ -225,13 +246,15 @@ func TestRunSweepWithStopsAtTheDeadline(t *testing.T) {
}
double := sweepCalcRun(sym, scope)
for _, jobs := range []int{1, sweepJobs} {
stop, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
stop := &metDeadline{Context: context.Background(), done: make(chan struct{})}
var started, finished, late atomic.Int64
waiting := func(ctx *Context, bindings []SweepBinding) (SweepRunResult, error) {
started.Add(1)
if stop.Err() != nil {
late.Add(1)
}
if started.Add(1) == int64(jobs) {
stop.meet()
}
if bindings[0].Value.Const.Int <= int64(sweepJobs) {
<-stop.Done()
}
Expand All @@ -240,7 +263,6 @@ func TestRunSweepWithStopsAtTheDeadline(t *testing.T) {
return result, err
}
table, err := RunSweepWith(stop, SweepWorkers{First: firstOf(t, fresh), Jobs: jobs, Fresh: fresh}, "test::Fib", plan, 0, waiting)
cancel()
if !errors.Is(err, context.DeadlineExceeded) || len(table.Rows) != 0 || table.Target != "" {
t.Fatalf("on %d jobs: table of %d rows and %v, want no table and context.DeadlineExceeded", jobs, len(table.Rows), err)
}
Expand Down
Loading