blob: 6dc0b56d79f37b1c8b5a9a9ec086e04ef48782f7 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package testutil
2
3import (
4 "fmt"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07005 "path/filepath"
6 "runtime"
Jiri Simsa870ddd62014-06-27 14:56:58 -07007 "sync"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07008)
9
Jiri Simsa870ddd62014-06-27 14:56:58 -070010var (
11 random []byte
12 randomMutex sync.Mutex
13)
14
15func generateRandomBytes(size int) []byte {
16 buffer := make([]byte, size)
17 offset := 0
18 for {
19 bits := int64(Rand.Int63())
20 for i := 0; i < 8; i++ {
21 buffer[offset] = byte(bits & 0xff)
22 size--
23 if size == 0 {
24 return buffer
25 }
26 offset++
27 bits >>= 8
28 }
29 }
Jiri Simsa5293dcb2014-05-10 09:56:38 -070030}
31
32// DepthToExternalCaller determines the number of stack frames to the first
33// enclosing caller that is external to the package that this function is
34// called from. Drectory name is used as a proxy for package name,
35// that is, the directory component of the file return runtime.Caller is
36// compared to that of the lowest level caller until a different one is
37// encountered as the stack is walked upwards.
38func DepthToExternalCaller() int {
39 _, file, _, _ := runtime.Caller(1)
40 cwd := filepath.Dir(file)
41 for d := 2; d < 10; d++ {
42 _, file, _, _ := runtime.Caller(d)
43 if cwd != filepath.Dir(file) {
44 return d
45 }
46 }
47 return 1
48}
49
Jiri Simsa870ddd62014-06-27 14:56:58 -070050// FormatLogLine will prepend the file and line number of the caller
51// at the specificied depth (as per runtime.Caller) to the supplied
52// format and args and return a formatted string. It is useful when
53// implementing functions that factor out error handling and reporting
54// in tests.
55func FormatLogLine(depth int, format string, args ...interface{}) string {
56 _, file, line, _ := runtime.Caller(depth)
57 nargs := []interface{}{filepath.Base(file), line}
58 nargs = append(nargs, args...)
59 return fmt.Sprintf("%s:%d: "+format, nargs...)
Ankur53fdf562014-05-16 10:03:49 -070060}
61
Jiri Simsa870ddd62014-06-27 14:56:58 -070062// RandomBytes generates the given number of random bytes.
63func RandomBytes(size int) []byte {
64 buffer := make([]byte, size)
65 randomMutex.Lock()
66 defer randomMutex.Unlock()
67 // Generate a 10MB of random bytes since that is a value commonly
68 // used in the tests.
69 if len(random) == 0 {
70 random = generateRandomBytes(10 << 20)
71 }
72 if size > len(random) {
73 extra := generateRandomBytes(size - len(random))
74 random = append(random, extra...)
75 }
76 start := Rand.Intn(len(random) - size + 1)
77 copy(buffer, random[start:start+size])
78 return buffer
79}