ref/test/testutil: make use of the rand generator explicit.
Before this change, testutil would implicitly initialize a
random number generator and print out the seed used. This
was mildly annoying because every test binary would print
out this seed as the first thing, but otherwise fine. However,
we'd like to move away from using a global singleton for
logging at which point logging out the seed in an init
function before other intialization has occurred becomes
problematic. This change makes it so that the random number
generator must be initialized explicitly and that this
initialization returns a function to be deferred that prints
out the seed if the test failed.
Change-Id: I0b57ea47d8eaaf45be2a5eeecba2fa1732ae85fd
diff --git a/lib/security/serialization/serialization_test.go b/lib/security/serialization/serialization_test.go
index 9f7fc96..2de7519 100644
--- a/lib/security/serialization/serialization_test.go
+++ b/lib/security/serialization/serialization_test.go
@@ -83,6 +83,7 @@
}
func TestRoundTrip(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
signer := newSigner()
d, s := &bufferCloser{}, &bufferCloser{}
diff --git a/runtime/internal/lib/deque/deque_test.go b/runtime/internal/lib/deque/deque_test.go
index 0e89896..9cac8e0 100644
--- a/runtime/internal/lib/deque/deque_test.go
+++ b/runtime/internal/lib/deque/deque_test.go
@@ -136,16 +136,17 @@
}
func TestRandom(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
var q T
var contents []int
for i := 0; i != 1000; i++ {
- switch testutil.Intn(4) {
+ switch testutil.RandomIntn(4) {
case 0:
- i := testutil.Int()
+ i := testutil.RandomInt()
contents = append([]int{i}, contents...)
q.PushFront(i)
case 1:
- i := testutil.Int()
+ i := testutil.RandomInt()
contents = append(contents, i)
q.PushBack(i)
case 2:
diff --git a/runtime/internal/lib/sync/wait_group_test.go b/runtime/internal/lib/sync/wait_group_test.go
index ff250b3..859b323 100644
--- a/runtime/internal/lib/sync/wait_group_test.go
+++ b/runtime/internal/lib/sync/wait_group_test.go
@@ -15,12 +15,13 @@
// TestRandom tests Wait after a random sequence of TryAdd's and Done's that
// leaves the counter at 0.
func TestRandom(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
var w WaitGroup
N := 100
count := 0
for n := 0; n < N; n++ {
- if count == 0 || testutil.Intn(2) == 0 {
+ if count == 0 || testutil.RandomIntn(2) == 0 {
if !w.TryAdd() {
t.Fatal("TryAdd failed")
}
diff --git a/runtime/internal/rpc/results_store_test.go b/runtime/internal/rpc/results_store_test.go
index b0ee8eb..b38b652 100644
--- a/runtime/internal/rpc/results_store_test.go
+++ b/runtime/internal/rpc/results_store_test.go
@@ -13,10 +13,10 @@
)
func randomKeys() []uint64 {
- n := (testutil.Intn(256*10) / 10) + 256
+ n := (testutil.RandomIntn(256*10) / 10) + 256
k := make([]uint64, n)
for i := 0; i < n; i++ {
- k[i] = uint64(testutil.Int63())
+ k[i] = uint64(testutil.RandomInt63())
}
return k
}
@@ -29,6 +29,7 @@
func (p keySlice) Sort() { sort.Sort(p) }
func TestStoreRandom(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
store := newStore()
keys := randomKeys()
@@ -50,6 +51,7 @@
}
func TestStoreOrdered(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
store := newStore()
keys := randomKeys()
@@ -94,6 +96,7 @@
}
func TestStoreWaitForEntryRandom(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
store := newStore()
keys := randomKeys()
var wg sync.WaitGroup
@@ -115,6 +118,7 @@
}
func TestStoreWaitForRemovedEntry(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
store := newStore()
keys := randomKeys()
var wg sync.WaitGroup
diff --git a/runtime/internal/rpc/stream/manager/manager_test.go b/runtime/internal/rpc/stream/manager/manager_test.go
index b2a5cad..6fe2ddd 100644
--- a/runtime/internal/rpc/stream/manager/manager_test.go
+++ b/runtime/internal/rpc/stream/manager/manager_test.go
@@ -917,6 +917,7 @@
}
var stderr bytes.Buffer
if err := h.Shutdown(nil, &stderr); err != nil {
+ t.Logf("%s", stderr.String())
t.Fatal(err)
}
if log := expect.NewSession(t, bytes.NewReader(stderr.Bytes()), time.Minute).ExpectSetEventuallyRE("listener.go.*Killing [1-9][0-9]* Conns"); len(log) == 0 {
diff --git a/runtime/internal/rpc/stream/vc/vc_test.go b/runtime/internal/rpc/stream/vc/vc_test.go
index 1c08719..e42c385 100644
--- a/runtime/internal/rpc/stream/vc/vc_test.go
+++ b/runtime/internal/rpc/stream/vc/vc_test.go
@@ -62,12 +62,13 @@
// testFlowEcho writes a random string of 'size' bytes on the flow and then
// ensures that the same string is read back.
func testFlowEcho(t *testing.T, flow stream.Flow, size int) {
+ defer testutil.InitRandGenerator(t.Logf)()
defer flow.Close()
wrote := testutil.RandomBytes(size)
go func() {
buf := wrote
for len(buf) > 0 {
- limit := 1 + testutil.Intn(len(buf)) // Random number in [1, n]
+ limit := 1 + testutil.RandomIntn(len(buf)) // Random number in [1, n]
n, err := flow.Write(buf[:limit])
if n != limit || err != nil {
t.Errorf("Write returned (%d, %v) want (%d, nil)", n, err, limit)
diff --git a/runtime/internal/rpc/stream/vif/vif_test.go b/runtime/internal/rpc/stream/vif/vif_test.go
index 1a6aa24..101258b 100644
--- a/runtime/internal/rpc/stream/vif/vif_test.go
+++ b/runtime/internal/rpc/stream/vif/vif_test.go
@@ -85,6 +85,7 @@
}
func testMultipleVCsAndMultipleFlows(t *testing.T, gomaxprocs int) {
+ defer testutil.InitRandGenerator(t.Logf)()
// This test dials multiple VCs from the client to the server.
// On each VC, it creates multiple flows, writes to them and verifies
// that the other process received what was written.
@@ -143,7 +144,7 @@
buf := []byte(data)
// Split into a random number of Write calls.
for len(buf) > 0 {
- size := 1 + testutil.Intn(len(buf)) // Random number in [1, len(buf)]
+ size := 1 + testutil.RandomIntn(len(buf)) // Random number in [1, len(buf)]
n, err := flow.Write(buf[:size])
if err != nil {
t.Errorf("Write failed: (%d, %v)", n, err)
@@ -159,7 +160,7 @@
var buf bytes.Buffer
var tmp [1024]byte
for {
- n, err := flow.Read(tmp[:testutil.Intn(len(tmp))])
+ n, err := flow.Read(tmp[:testutil.RandomIntn(len(tmp))])
buf.Write(tmp[:n])
if err == io.EOF {
break
diff --git a/runtime/internal/testing/concurrency/clock_test.go b/runtime/internal/testing/concurrency/clock_test.go
index 58c2cbc..dcbd6fc 100644
--- a/runtime/internal/testing/concurrency/clock_test.go
+++ b/runtime/internal/testing/concurrency/clock_test.go
@@ -14,8 +14,9 @@
// TestClone checks the clone() method of a clock.
func TestClone(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
c1 := newClock()
- c1[0] = testutil.Intn(100)
+ c1[0] = testutil.RandomIntn(100)
c2 := c1.clone()
c1[0]++
if c2[0] != c1[0]-1 {
@@ -27,7 +28,7 @@
func TestEquality(t *testing.T) {
c1, c2 := newClock(), newClock()
for i := TID(0); i < TID(10); i++ {
- c1[i] = testutil.Intn(100)
+ c1[i] = testutil.RandomIntn(100)
c2[i] = c1[i]
}
if !c1.equals(c2) {
@@ -39,7 +40,7 @@
func TestHappensBefore(t *testing.T) {
c1, c2, c3 := newClock(), newClock(), newClock()
for i := TID(0); i < TID(10); i++ {
- c1[i] = testutil.Intn(100)
+ c1[i] = testutil.RandomIntn(100)
if i%2 == 0 {
c2[i] = c1[i] + 1
c3[i] = c1[i] + 1
@@ -69,8 +70,8 @@
func TestMerge(t *testing.T) {
c1, c2 := newClock(), newClock()
for i := TID(0); i < TID(10); i++ {
- c1[i] = testutil.Intn(100)
- c2[i] = testutil.Intn(100)
+ c1[i] = testutil.RandomIntn(100)
+ c2[i] = testutil.RandomIntn(100)
}
c1.merge(c2)
for i := TID(0); i < TID(10); i++ {
diff --git a/services/binary/binaryd/binaryd_v23_test.go b/services/binary/binaryd/binaryd_v23_test.go
index e0611a6..0a3c05a 100644
--- a/services/binary/binaryd/binaryd_v23_test.go
+++ b/services/binary/binaryd/binaryd_v23_test.go
@@ -96,6 +96,7 @@
}
func V23TestBinaryRepositoryIntegration(i *v23tests.T) {
+ defer testutil.InitRandGenerator(i.Logf)()
v23tests.RunRootMT(i, "--v23.tcp.address=127.0.0.1:0")
// Build the required binaries.
diff --git a/services/device/internal/impl/globsuid/signature_match_test.go b/services/device/internal/impl/globsuid/signature_match_test.go
index f746394..5aabcbc 100644
--- a/services/device/internal/impl/globsuid/signature_match_test.go
+++ b/services/device/internal/impl/globsuid/signature_match_test.go
@@ -27,6 +27,7 @@
)
func TestDownloadSignatureMatch(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
ctx, shutdown := utiltest.V23Init()
defer shutdown()
@@ -37,7 +38,7 @@
pkgVON := naming.Join(binaryVON, "testpkg")
defer utiltest.StartRealBinaryRepository(t, ctx, binaryVON)()
- up := testutil.RandomBytes(testutil.Intn(5 << 20))
+ up := testutil.RandomBytes(testutil.RandomIntn(5 << 20))
mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
sig, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo)
if err != nil {
@@ -50,7 +51,7 @@
t.Fatalf("ioutil.TempDir failed: %v", err)
}
defer os.RemoveAll(tmpdir)
- pkgContents := testutil.RandomBytes(testutil.Intn(5 << 20))
+ pkgContents := testutil.RandomBytes(testutil.RandomIntn(5 << 20))
if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
t.Fatalf("ioutil.WriteFile failed: %v", err)
}
diff --git a/services/internal/binarylib/client_test.go b/services/internal/binarylib/client_test.go
index cd76fd6..7cd2435 100644
--- a/services/internal/binarylib/client_test.go
+++ b/services/internal/binarylib/client_test.go
@@ -83,6 +83,7 @@
// TestBufferAPI tests the binary repository client-side library
// interface using buffers.
func TestBufferAPI(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
ctx, shutdown := test.V23Init()
defer shutdown()
@@ -90,7 +91,7 @@
von, cleanup := setupRepository(t, ctx)
defer cleanup()
- data := testutil.RandomBytes(testutil.Intn(10 << 20))
+ data := testutil.RandomBytes(testutil.RandomIntn(10 << 20))
mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
sig, err := Upload(ctx, von, data, mediaInfo)
if err != nil {
@@ -136,6 +137,7 @@
// TestFileAPI tests the binary repository client-side library
// interface using files.
func TestFileAPI(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
ctx, shutdown := test.V23Init()
defer shutdown()
@@ -144,7 +146,7 @@
von, cleanup := setupRepository(t, ctx)
defer cleanup()
// Create up to 10MB of random bytes.
- data := testutil.RandomBytes(testutil.Intn(10 << 20))
+ data := testutil.RandomBytes(testutil.RandomIntn(10 << 20))
dir, prefix := "", ""
src, err := ioutil.TempFile(dir, prefix)
if err != nil {
diff --git a/services/internal/binarylib/http_test.go b/services/internal/binarylib/http_test.go
index 77f0f2d..5e11215 100644
--- a/services/internal/binarylib/http_test.go
+++ b/services/internal/binarylib/http_test.go
@@ -23,6 +23,7 @@
// TestHTTP checks that HTTP download works.
func TestHTTP(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
ctx, shutdown := test.V23Init()
defer shutdown()
@@ -37,7 +38,7 @@
data := make([][]byte, length)
for i := 0; i < length; i++ {
// Random size, but at least 1 (avoid empty parts).
- size := testutil.Intn(1000*binarylib.BufferLength) + 1
+ size := testutil.RandomIntn(1000*binarylib.BufferLength) + 1
data[i] = testutil.RandomBytes(size)
}
mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
diff --git a/services/internal/binarylib/impl_test.go b/services/internal/binarylib/impl_test.go
index 93bbb35..6ce83b0 100644
--- a/services/internal/binarylib/impl_test.go
+++ b/services/internal/binarylib/impl_test.go
@@ -185,6 +185,7 @@
// resumption ranging the number of parts the uploaded binary consists
// of.
func TestResumption(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
ctx, shutdown := test.V23Init()
defer shutdown()
@@ -216,7 +217,7 @@
break
}
for i := 0; i < length; i++ {
- fail := testutil.Intn(2)
+ fail := testutil.RandomIntn(2)
if parts[i] == binarylib.MissingPart && fail != 0 {
if streamErr, err := invokeUpload(t, ctx, binary, data[i], int32(i)); streamErr != nil || err != nil {
t.FailNow()
@@ -232,6 +233,7 @@
// TestErrors checks that the binary interface correctly reports errors.
func TestErrors(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
ctx, shutdown := test.V23Init()
defer shutdown()
@@ -244,7 +246,7 @@
for i := 0; i < length; i++ {
data[i] = testData()
for j := 0; j < len(data[i]); j++ {
- data[i][j] = byte(testutil.Int())
+ data[i][j] = byte(testutil.RandomInt())
}
}
if err := binary.Create(ctx, int32(length), repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
diff --git a/services/internal/binarylib/util_test.go b/services/internal/binarylib/util_test.go
index 2038f46..30b414f 100644
--- a/services/internal/binarylib/util_test.go
+++ b/services/internal/binarylib/util_test.go
@@ -89,7 +89,7 @@
// testData creates up to 4MB of random bytes.
func testData() []byte {
- size := testutil.Intn(1000 * binarylib.BufferLength)
+ size := testutil.RandomIntn(1000 * binarylib.BufferLength)
data := testutil.RandomBytes(size)
return data
}
diff --git a/test/init.go b/test/init.go
index 395cab7..d86b452 100644
--- a/test/init.go
+++ b/test/init.go
@@ -10,11 +10,11 @@
"runtime"
"sync"
+ "v.io/x/lib/vlog"
+
"v.io/v23"
"v.io/v23/context"
- "v.io/x/lib/vlog"
-
"v.io/x/ref/lib/flags"
"v.io/x/ref/test/testutil"
)
@@ -58,7 +58,6 @@
// function of a _test.go file.
flag.Parse()
vlog.ConfigureLibraryLoggerFromFlags()
- testutil.InitRandGenerator()
}
once.Do(init)
}
diff --git a/test/modules/modules_test.go b/test/modules/modules_test.go
index 117b4e4..993e060 100644
--- a/test/modules/modules_test.go
+++ b/test/modules/modules_test.go
@@ -397,7 +397,6 @@
if got, want := stdoutBuf.String(), stdoutOutput+result; got != want {
t.Errorf("got %q want %q", got, want)
}
- stderrBuf.ReadString('\n') // Skip past the random # generator output
if got, want := stderrBuf.String(), stderrOutput; got != want {
t.Errorf("got %q want %q", got, want)
}
diff --git a/test/modules/queue_rw_test.go b/test/modules/queue_rw_test.go
index 66df967..fd55475 100644
--- a/test/modules/queue_rw_test.go
+++ b/test/modules/queue_rw_test.go
@@ -14,12 +14,13 @@
)
func TestQueueRW(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
q := modules.NewRW()
- size := testutil.Intn(1000)
+ size := testutil.RandomIntn(1000)
data := testutil.RandomBytes(size)
begin := 0
for {
- end := begin + testutil.Intn(100) + 1
+ end := begin + testutil.RandomIntn(100) + 1
if end > len(data) {
end = len(data)
}
@@ -37,7 +38,7 @@
}
readData := make([]byte, 0, size)
for {
- buf := make([]byte, testutil.Intn(100)+1)
+ buf := make([]byte, testutil.RandomIntn(100)+1)
n, err := q.Read(buf)
if n > 0 {
readData = append(readData, buf[:n]...)
diff --git a/test/testutil/rand.go b/test/testutil/rand.go
index e6ef82b..ca9f038 100644
--- a/test/testutil/rand.go
+++ b/test/testutil/rand.go
@@ -5,13 +5,12 @@
package testutil
import (
+ "fmt"
"math/rand"
"os"
"strconv"
"sync"
"time"
-
- "v.io/x/lib/vlog"
)
const (
@@ -27,25 +26,26 @@
// Random is a concurrent-access friendly source of randomness.
type Random struct {
mu sync.Mutex
+ seed int64
rand *rand.Rand
}
-// Int returns a non-negative pseudo-random int.
-func (r *Random) Int() int {
+// RandomInt returns a non-negative pseudo-random int.
+func (r *Random) RandomInt() int {
r.mu.Lock()
defer r.mu.Unlock()
return r.rand.Int()
}
-// Intn returns a non-negative pseudo-random int in the range [0, n).
-func (r *Random) Intn(n int) int {
+// RandomIntn returns a non-negative pseudo-random int in the range [0, n).
+func (r *Random) RandomIntn(n int) int {
r.mu.Lock()
defer r.mu.Unlock()
return r.rand.Intn(n)
}
-// Int63 returns a non-negative 63-bit pseudo-random integer as an int64.
-func (r *Random) Int63() int64 {
+// RandomInt63 returns a non-negative 63-bit pseudo-random integer as an int64.
+func (r *Random) RandomInt63() int64 {
r.mu.Lock()
defer r.mu.Unlock()
return r.rand.Int63()
@@ -65,7 +65,7 @@
extra := generateRandomBytes(rand, size-len(random))
random = append(random, extra...)
}
- start := rand.Intn(len(random) - size + 1)
+ start := rand.RandomIntn(len(random) - size + 1)
copy(buffer, random[start:start+size])
return buffer
}
@@ -80,18 +80,25 @@
base, bitSize := 0, 64
seed, err = strconv.ParseInt(seedString, base, bitSize)
if err != nil {
- vlog.Fatalf("ParseInt(%v, %v, %v) failed: %v", seedString, base, bitSize, err)
+ panic(fmt.Sprintf("ParseInt(%v, %v, %v) failed: %v", seedString, base, bitSize, err))
}
}
- vlog.Infof("Seeding pseudo-random number generator with %v", seed)
- return &Random{rand: rand.New(rand.NewSource(seed))}
+ return &Random{seed: seed, rand: rand.New(rand.NewSource(seed))}
}
-// InitRandGenerator creates an instance of Random in the public variable Rand.
-func InitRandGenerator() {
+// InitRandGenerator creates an instance of Random in the public variable Rand
+// and returns a function intended to be defer'ed that prints out the
+// seed use when creating the number number generator using the supplied
+// logging function.
+func InitRandGenerator(loggingFunc func(format string, args ...interface{})) func() {
once.Do(func() {
Rand = NewRandGenerator()
})
+ return func() {
+ if loggingFunc != nil {
+ loggingFunc("Seeded pseudo-random number generator with %v", Rand.seed)
+ }
+ }
}
var (
@@ -103,7 +110,7 @@
buffer := make([]byte, size)
offset := 0
for {
- bits := int64(rand.Int63())
+ bits := int64(rand.RandomInt63())
for i := 0; i < 8; i++ {
buffer[offset] = byte(bits & 0xff)
size--
@@ -116,21 +123,21 @@
}
}
-// Int returns a non-negative pseudo-random int using the public variable Rand.
-func Int() int {
- return Rand.Int()
+// RandomInt returns a non-negative pseudo-random int using the public variable Rand.
+func RandomInt() int {
+ return Rand.RandomInt()
}
-// Intn returns a non-negative pseudo-random int in the range [0, n) using
+// RandomIntn returns a non-negative pseudo-random int in the range [0, n) using
// the public variable Rand.
-func Intn(n int) int {
- return Rand.Intn(n)
+func RandomIntn(n int) int {
+ return Rand.RandomIntn(n)
}
-// Int63 returns a non-negative 63-bit pseudo-random integer as an int64
+// RandomInt63 returns a non-negative 63-bit pseudo-random integer as an int64
// using the public variable Rand.
-func Int63() int64 {
- return Rand.Int63()
+func RandomInt63() int64 {
+ return Rand.RandomInt63()
}
// RandomBytes generates the given number of random bytes using
diff --git a/test/testutil/security_test.go b/test/testutil/security_test.go
index f6d5a35..b13eb6b 100644
--- a/test/testutil/security_test.go
+++ b/test/testutil/security_test.go
@@ -2,16 +2,18 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package testutil
+package testutil_test
import (
"reflect"
"testing"
+
+ "v.io/x/ref/test/testutil"
)
func TestIDProvider(t *testing.T) {
- idp := NewIDProvider("foo")
- p := NewPrincipal()
+ idp := testutil.NewIDProvider("foo")
+ p := testutil.NewPrincipal()
if err := idp.Bless(p, "bar"); err != nil {
t.Fatal(err)
}
diff --git a/test/testutil/testdata/rand_test.go b/test/testutil/testdata/rand_test.go
new file mode 100644
index 0000000..bddb946
--- /dev/null
+++ b/test/testutil/testdata/rand_test.go
@@ -0,0 +1,17 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testutil_test
+
+import (
+ "testing"
+
+ "v.io/x/ref/test/testutil"
+)
+
+func TestRandSeed(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
+ t.Logf("rand: %d", testutil.RandomInt())
+ t.FailNow()
+}
diff --git a/test/testutil/util_test.go b/test/testutil/util_test.go
index 0a44dab..91b9aff 100644
--- a/test/testutil/util_test.go
+++ b/test/testutil/util_test.go
@@ -2,16 +2,45 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package testutil
+package testutil_test
import (
"regexp"
"testing"
+
+ _ "v.io/x/ref/runtime/factories/generic"
+ "v.io/x/ref/test/testutil"
+ "v.io/x/ref/test/v23tests"
)
func TestFormatLogline(t *testing.T) {
- line, want := FormatLogLine(2, "test"), "testing.go:.*"
+ line, want := testutil.FormatLogLine(2, "test"), "testing.go:.*"
if ok, err := regexp.MatchString(want, line); !ok || err != nil {
t.Errorf("got %v, want %v", line, want)
}
}
+
+//go:generate v23 test generate .
+
+func V23TestRandSeed(i *v23tests.T) {
+ v23bin := i.BinaryFromPath("v23")
+ inv := v23bin.Start("go", "test", "./testdata")
+ inv.ExpectRE("FAIL: TestRandSeed.*", 1)
+ parts := inv.ExpectRE(`rand: (\d+)`, -1)
+ if len(parts) != 1 || len(parts[0]) != 2 {
+ i.Fatalf("failed to match regexp")
+ }
+ randInt := parts[0][1]
+ parts = inv.ExpectRE(`Seeded pseudo-random number generator with (\d+)`, -1)
+ if len(parts) != 1 || len(parts[0]) != 2 {
+ i.Fatalf("failed to match regexp")
+ }
+
+ seed := parts[0][1]
+ // Rerun the test, this time with the seed that we want to use.
+ v23bin = v23bin.WithEnv("V23_RNG_SEED=" + seed)
+ inv = v23bin.Start("go", "test", "./testdata")
+ inv.ExpectRE("FAIL: TestRandSeed.*", 1)
+ inv.ExpectRE("rand: "+randInt, 1)
+ inv.ExpectRE("Seeded pseudo-random number generator with "+seed, -1)
+}
diff --git a/test/testutil/v23_test.go b/test/testutil/v23_test.go
new file mode 100644
index 0000000..0463ee0
--- /dev/null
+++ b/test/testutil/v23_test.go
@@ -0,0 +1,30 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+package testutil_test
+
+import (
+ "os"
+ "testing"
+
+ "v.io/x/ref/test"
+ "v.io/x/ref/test/modules"
+ "v.io/x/ref/test/v23tests"
+)
+
+func TestMain(m *testing.M) {
+ test.Init()
+ modules.DispatchAndExitIfChild()
+ cleanup := v23tests.UseSharedBinDir()
+ r := m.Run()
+ cleanup()
+ os.Exit(r)
+}
+
+func TestV23RandSeed(t *testing.T) {
+ v23tests.RunTest(t, V23TestRandSeed)
+}
diff --git a/test/testutil/vtest_test.go b/test/testutil/vtest_test.go
index 0bd33cc..516fe06 100644
--- a/test/testutil/vtest_test.go
+++ b/test/testutil/vtest_test.go
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package testutil
+package testutil_test
import (
"testing"
+
+ "v.io/x/ref/test/testutil"
)
func TestCallAndRecover(t *testing.T) {
@@ -19,7 +21,7 @@
{func() { panic("abc") }, "abc"},
}
for _, test := range tests {
- got := CallAndRecover(test.f)
+ got := testutil.CallAndRecover(test.f)
if got != test.expect {
t.Errorf(`CallAndRecover got "%v", want "%v"`, got, test.expect)
}
diff --git a/test/v23tests/v23tests_test.go b/test/v23tests/v23tests_test.go
index 63efeb9..47c8d4c 100644
--- a/test/v23tests/v23tests_test.go
+++ b/test/v23tests/v23tests_test.go
@@ -143,6 +143,7 @@
}
func TestInputRedirection(t *testing.T) {
+ defer testutil.InitRandGenerator(t.Logf)()
env := v23tests.New(t)
defer env.Cleanup()
@@ -296,7 +297,7 @@
msg := recover().(string)
// this, and the tests below are intended to ensure that line #s
// are captured and reported correctly.
- if got, want := msg, "v23tests_test.go:306"; !strings.Contains(got, want) {
+ if got, want := msg, "v23tests_test.go:307"; !strings.Contains(got, want) {
t.Fatalf("%q does not contain %q", got, want)
}
if got, want := msg, "fork/exec /bin/echox: no such file or directory"; !strings.Contains(got, want) {
@@ -318,7 +319,7 @@
sh.SetDefaultStartOpts(opts)
defer func() {
msg := recover().(string)
- if got, want := msg, "v23tests_test.go:328"; !strings.Contains(got, want) {
+ if got, want := msg, "v23tests_test.go:329"; !strings.Contains(got, want) {
t.Fatalf("%q does not contain %q", got, want)
}
if got, want := msg, "StartWithOpts"; !strings.Contains(got, want) {
@@ -342,7 +343,7 @@
if iterations == 0 {
t.Fatalf("our sleeper didn't get to run")
}
- if got, want := recover().(string), "v23tests_test.go:349: timed out"; !strings.Contains(got, want) {
+ if got, want := recover().(string), "v23tests_test.go:350: timed out"; !strings.Contains(got, want) {
t.Fatalf("%q does not contain %q", got, want)
}
}()
@@ -364,7 +365,7 @@
if iterations != 0 {
t.Fatalf("our sleeper got to run")
}
- if got, want := recover().(string), "v23tests_test.go:371: timed out"; !strings.Contains(got, want) {
+ if got, want := recover().(string), "v23tests_test.go:372: timed out"; !strings.Contains(got, want) {
t.Fatalf("%q does not contain %q", got, want)
}
}()