Source file src/crypto/internal/sysrand/rand_test.go

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sysrand
     6  
     7  import (
     8  	"bytes"
     9  	"compress/flate"
    10  	"internal/testenv"
    11  	"os"
    12  	"runtime"
    13  	"sync"
    14  	"testing"
    15  )
    16  
    17  func TestRead(t *testing.T) {
    18  	// 40MiB, more than the documented maximum of 32Mi-1 on Linux 32-bit.
    19  	b := make([]byte, 40<<20)
    20  	Read(b)
    21  
    22  	if testing.Short() {
    23  		b = b[len(b)-100_000:]
    24  	}
    25  
    26  	var z bytes.Buffer
    27  	f, _ := flate.NewWriter(&z, 5)
    28  	f.Write(b)
    29  	f.Close()
    30  	if z.Len() < len(b)*99/100 {
    31  		t.Fatalf("Compressed %d -> %d", len(b), z.Len())
    32  	}
    33  }
    34  
    35  func TestReadByteValues(t *testing.T) {
    36  	b := make([]byte, 1)
    37  	v := make(map[byte]bool)
    38  	for {
    39  		Read(b)
    40  		v[b[0]] = true
    41  		if len(v) == 256 {
    42  			break
    43  		}
    44  	}
    45  }
    46  
    47  func TestReadEmpty(t *testing.T) {
    48  	Read(make([]byte, 0))
    49  	Read(nil)
    50  }
    51  
    52  func TestConcurrentRead(t *testing.T) {
    53  	if testing.Short() {
    54  		t.Skip("skipping in short mode")
    55  	}
    56  	const N = 100
    57  	const M = 1000
    58  	var wg sync.WaitGroup
    59  	wg.Add(N)
    60  	for i := 0; i < N; i++ {
    61  		go func() {
    62  			defer wg.Done()
    63  			for i := 0; i < M; i++ {
    64  				b := make([]byte, 32)
    65  				Read(b)
    66  			}
    67  		}()
    68  	}
    69  	wg.Wait()
    70  }
    71  
    72  // TestNoUrandomFallback ensures the urandom fallback is not reached in
    73  // normal operations.
    74  func TestNoUrandomFallback(t *testing.T) {
    75  	expectFallback := false
    76  	if runtime.GOOS == "aix" {
    77  		// AIX always uses the urandom fallback.
    78  		expectFallback = true
    79  	}
    80  	if os.Getenv("GO_GETRANDOM_DISABLED") == "1" {
    81  		// We are testing the urandom fallback intentionally.
    82  		expectFallback = true
    83  	}
    84  	Read(make([]byte, 1))
    85  	if urandomFile != nil && !expectFallback {
    86  		t.Error("/dev/urandom fallback used unexpectedly")
    87  		t.Log("note: if this test fails, it may be because the system does not have getrandom(2)")
    88  	}
    89  	if urandomFile == nil && expectFallback {
    90  		t.Error("/dev/urandom fallback not used as expected")
    91  	}
    92  }
    93  
    94  func TestReadError(t *testing.T) {
    95  	if testing.Short() {
    96  		t.Skip("skipping test in short mode")
    97  	}
    98  	testenv.MustHaveExec(t)
    99  
   100  	// We run this test in a subprocess because it's expected to crash.
   101  	if os.Getenv("GO_TEST_READ_ERROR") == "1" {
   102  		testingOnlyFailRead = true
   103  		Read(make([]byte, 32))
   104  		t.Error("Read did not crash")
   105  		return
   106  	}
   107  
   108  	cmd := testenv.Command(t, os.Args[0], "-test.run=TestReadError")
   109  	cmd.Env = append(os.Environ(), "GO_TEST_READ_ERROR=1")
   110  	out, err := cmd.CombinedOutput()
   111  	if err == nil {
   112  		t.Error("subprocess succeeded unexpectedly")
   113  	}
   114  	exp := "fatal error: crypto/rand: failed to read random data"
   115  	if !bytes.Contains(out, []byte(exp)) {
   116  		t.Errorf("subprocess output does not contain %q: %s", exp, out)
   117  	}
   118  }
   119  

View as plain text