blob: 1d8eb00f5669358bb7c5e430b1d21c03db084696 [file] [log] [blame] [edit]
// Copyright 2010 The Go 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 sysrand
import (
"bytes"
"compress/flate"
"internal/testenv"
"os"
"runtime"
"sync"
"testing"
)
func TestRead(t *testing.T) {
// 40MiB, more than the documented maximum of 32Mi-1 on Linux 32-bit.
b := make([]byte, 40<<20)
Read(b)
if testing.Short() {
b = b[len(b)-100_000:]
}
var z bytes.Buffer
f, _ := flate.NewWriter(&z, 5)
f.Write(b)
f.Close()
if z.Len() < len(b)*99/100 {
t.Fatalf("Compressed %d -> %d", len(b), z.Len())
}
}
func TestReadByteValues(t *testing.T) {
b := make([]byte, 1)
v := make(map[byte]bool)
for {
Read(b)
v[b[0]] = true
if len(v) == 256 {
break
}
}
}
func TestReadEmpty(t *testing.T) {
Read(make([]byte, 0))
Read(nil)
}
func TestConcurrentRead(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
const N = 100
const M = 1000
var wg sync.WaitGroup
wg.Add(N)
for i := 0; i < N; i++ {
go func() {
defer wg.Done()
for i := 0; i < M; i++ {
b := make([]byte, 32)
Read(b)
}
}()
}
wg.Wait()
}
// TestNoUrandomFallback ensures the urandom fallback is not reached in
// normal operations.
func TestNoUrandomFallback(t *testing.T) {
expectFallback := false
if runtime.GOOS == "aix" {
// AIX always uses the urandom fallback.
expectFallback = true
}
if os.Getenv("GO_GETRANDOM_DISABLED") == "1" {
// We are testing the urandom fallback intentionally.
expectFallback = true
}
Read(make([]byte, 1))
if urandomFile != nil && !expectFallback {
t.Error("/dev/urandom fallback used unexpectedly")
t.Log("note: if this test fails, it may be because the system does not have getrandom(2)")
}
if urandomFile == nil && expectFallback {
t.Error("/dev/urandom fallback not used as expected")
}
}
func TestReadError(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode")
}
testenv.MustHaveExec(t)
// We run this test in a subprocess because it's expected to crash.
if os.Getenv("GO_TEST_READ_ERROR") == "1" {
testingOnlyFailRead = true
Read(make([]byte, 32))
t.Error("Read did not crash")
return
}
cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestReadError$")
cmd.Env = append(os.Environ(), "GO_TEST_READ_ERROR=1")
out, err := cmd.CombinedOutput()
if err == nil {
t.Error("subprocess succeeded unexpectedly")
}
exp := "fatal error: crypto/rand: failed to read random data"
if !bytes.Contains(out, []byte(exp)) {
t.Errorf("subprocess output does not contain %q: %s", exp, out)
}
}