blob: 6dc0b56d79f37b1c8b5a9a9ec086e04ef48782f7 [file] [log] [blame]
package testutil
import (
"fmt"
"path/filepath"
"runtime"
"sync"
)
var (
random []byte
randomMutex sync.Mutex
)
func generateRandomBytes(size int) []byte {
buffer := make([]byte, size)
offset := 0
for {
bits := int64(Rand.Int63())
for i := 0; i < 8; i++ {
buffer[offset] = byte(bits & 0xff)
size--
if size == 0 {
return buffer
}
offset++
bits >>= 8
}
}
}
// DepthToExternalCaller determines the number of stack frames to the first
// enclosing caller that is external to the package that this function is
// called from. Drectory name is used as a proxy for package name,
// that is, the directory component of the file return runtime.Caller is
// compared to that of the lowest level caller until a different one is
// encountered as the stack is walked upwards.
func DepthToExternalCaller() int {
_, file, _, _ := runtime.Caller(1)
cwd := filepath.Dir(file)
for d := 2; d < 10; d++ {
_, file, _, _ := runtime.Caller(d)
if cwd != filepath.Dir(file) {
return d
}
}
return 1
}
// FormatLogLine will prepend the file and line number of the caller
// at the specificied depth (as per runtime.Caller) to the supplied
// format and args and return a formatted string. It is useful when
// implementing functions that factor out error handling and reporting
// in tests.
func FormatLogLine(depth int, format string, args ...interface{}) string {
_, file, line, _ := runtime.Caller(depth)
nargs := []interface{}{filepath.Base(file), line}
nargs = append(nargs, args...)
return fmt.Sprintf("%s:%d: "+format, nargs...)
}
// RandomBytes generates the given number of random bytes.
func RandomBytes(size int) []byte {
buffer := make([]byte, size)
randomMutex.Lock()
defer randomMutex.Unlock()
// Generate a 10MB of random bytes since that is a value commonly
// used in the tests.
if len(random) == 0 {
random = generateRandomBytes(10 << 20)
}
if size > len(random) {
extra := generateRandomBytes(size - len(random))
random = append(random, extra...)
}
start := Rand.Intn(len(random) - size + 1)
copy(buffer, random[start:start+size])
return buffer
}