blob: 5e9c28f93e263e248a3926ff383ebfbb708fae80 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001// Package testutil provides initalization and utility routines for unit tests.
2//
3// All tests should import it, even if only for its initialization:
Jiri Simsa519c5072014-09-17 21:37:57 -07004// import _ "veyron.io/veyron/veyron/lib/testutil"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07005//
6package testutil
7
8import (
9 "flag"
Jiri Simsa870ddd62014-06-27 14:56:58 -070010 "math/rand"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070011 "os"
12 "runtime"
Jiri Simsa870ddd62014-06-27 14:56:58 -070013 "strconv"
Asim Shankar20282032014-07-07 22:48:00 -070014 "sync"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070015 // Need to import all of the packages that could possibly
16 // define flags that we care about. In practice, this is the
17 // flags defined by the testing package, the logging library
18 // and any flags defined by the blackbox package below.
19 _ "testing"
Jiri Simsa870ddd62014-06-27 14:56:58 -070020 "time"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070021
22 // Import blackbox to ensure that it gets to define its flags.
Jiri Simsa519c5072014-09-17 21:37:57 -070023 _ "veyron.io/veyron/veyron/lib/testutil/blackbox"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070024
Jiri Simsa519c5072014-09-17 21:37:57 -070025 "veyron.io/veyron/veyron2/vlog"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070026)
27
Jiri Simsa870ddd62014-06-27 14:56:58 -070028const (
29 SeedEnv = "VEYRON_RNG_SEED"
30)
31
Asim Shankar20282032014-07-07 22:48:00 -070032// Random is a concurrent-access friendly source of randomness.
33type Random struct {
34 mu sync.Mutex
35 rand *rand.Rand
36}
37
38// Int returns a non-negative pseudo-random int.
39func (r *Random) Int() int {
40 r.mu.Lock()
41 defer r.mu.Unlock()
42 return r.rand.Int()
43}
44
45// Intn returns a non-negative pseudo-random int in the range [0, n).
46func (r *Random) Intn(n int) int {
47 r.mu.Lock()
48 defer r.mu.Unlock()
49 return r.rand.Intn(n)
50}
51
52// Int63 returns a non-negative 63-bit pseudo-random integer as an int64.
53func (r *Random) Int63() int64 {
54 r.mu.Lock()
55 defer r.mu.Unlock()
56 return r.rand.Int63()
57}
58
Jiri Simsa870ddd62014-06-27 14:56:58 -070059var (
Asim Shankar20282032014-07-07 22:48:00 -070060 Rand *Random
Jiri Simsa870ddd62014-06-27 14:56:58 -070061)
62
Jiri Simsa5293dcb2014-05-10 09:56:38 -070063func init() {
64 if os.Getenv("GOMAXPROCS") == "" {
65 // Set the number of logical processors to the number of CPUs,
66 // if GOMAXPROCS is not set in the environment.
67 runtime.GOMAXPROCS(runtime.NumCPU())
68 }
Jiri Simsa01cf9372014-06-30 09:49:55 -070069 // At this point all of the flags that we're going to use for
70 // tests must be defined.
71 flag.Parse()
72 vlog.ConfigureLibraryLoggerFromFlags()
Jiri Simsa870ddd62014-06-27 14:56:58 -070073 // Initialize pseudo-random number generator.
74 seed := time.Now().UnixNano()
75 seedString := os.Getenv(SeedEnv)
76 if seedString != "" {
77 var err error
78 base, bitSize := 0, 64
Jiri Simsaf6598512014-06-30 10:32:02 -070079 seed, err = strconv.ParseInt(seedString, base, bitSize)
Jiri Simsa870ddd62014-06-27 14:56:58 -070080 if err != nil {
81 vlog.Fatalf("ParseInt(%v, %v, %v) failed: %v", seedString, base, bitSize, err)
82 }
83 }
84 vlog.Infof("Seeding pseudo-random number generator with %v", seed)
Asim Shankar20282032014-07-07 22:48:00 -070085 Rand = &Random{rand: rand.New(rand.NewSource(seed))}
Jiri Simsa5293dcb2014-05-10 09:56:38 -070086}