Skip to content

Commit

Permalink
starlark: fix flaky Example of parallel loading (google#13)
Browse files Browse the repository at this point in the history
...by turning it into a Test and asserting for either of the two valid outcomes.
  • Loading branch information
adonovan authored Nov 20, 2018
1 parent f4938bd commit 4765c97
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions starlark/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ package starlark_test
import (
"fmt"
"log"
"reflect"
"sort"
"strings"
"sync"
"sync/atomic"
"testing"
"unsafe"

"go.starlark.net/starlark"
Expand Down Expand Up @@ -146,9 +148,9 @@ func ExampleThread_Load_parallel() {
// c = 2
}

// ExampleThread_Load_parallelCycle demonstrates detection
// TestThread_Load_parallelCycle demonstrates detection
// of cycles during parallel loading.
func ExampleThread_Load_parallelCycle() {
func TestThreadLoad_ParallelCycle(t *testing.T) {
cache := &cache{
cache: make(map[string]*entry),
fakeFilesystem: map[string]string{
Expand All @@ -171,11 +173,24 @@ func ExampleThread_Load_parallelCycle() {
}
got := []string{<-ch, <-ch}
sort.Strings(got)
fmt.Println(strings.Join(got, "\n"))

// Output:
// cannot load a.star: cannot load c.star: cycle in load graph
// cannot load b.star: cannot load a.star: cannot load c.star: cycle in load graph
// Typically, the c goroutine quickly blocks behind b;
// b loads a, and a then fails to load c because it forms a cycle.
// The errors observed by the two goroutines are:
want1 := []string{
"cannot load a.star: cannot load c.star: cycle in load graph", // from b
"cannot load b.star: cannot load a.star: cannot load c.star: cycle in load graph", // from c
}
// But if the c goroutine is slow to start, b loads a,
// and a loads c; then c fails to load b because it forms a cycle.
// The errors this time are:
want2 := []string{
"cannot load a.star: cannot load c.star: cannot load b.star: cycle in load graph", // from b
"cannot load b.star: cycle in load graph", // from c
}
if !reflect.DeepEqual(got, want1) && !reflect.DeepEqual(got, want2) {
t.Error(got)
}
}

// cache is a concurrency-safe, duplicate-suppressing,
Expand Down

0 comments on commit 4765c97

Please sign in to comment.