gopkg.in/goose.v2@v2.0.1/testservices/identityservice/util_test.go (about)

     1  package identityservice
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"fmt"
     7  	"io"
     8  	"testing/iotest"
     9  
    10  	gc "gopkg.in/check.v1"
    11  )
    12  
    13  type UtilSuite struct{}
    14  
    15  var _ = gc.Suite(&UtilSuite{})
    16  
    17  func (s *UtilSuite) TestRandomHexTokenHasLength(c *gc.C) {
    18  	val := randomHexToken()
    19  	c.Assert(val, gc.HasLen, 32)
    20  }
    21  
    22  func (s *UtilSuite) TestRandomHexTokenIsHex(c *gc.C) {
    23  	val := randomHexToken()
    24  	for i, b := range val {
    25  		switch {
    26  		case (b >= 'a' && b <= 'f') || (b >= '0' && b <= '9'):
    27  			continue
    28  		default:
    29  			c.Logf("char %d of %s was not in the right range",
    30  				i, val)
    31  			c.Fail()
    32  		}
    33  	}
    34  }
    35  
    36  func (s *UtilSuite) TestDefaultReader(c *gc.C) {
    37  	raw := make([]byte, 6)
    38  	c.Assert(string(raw), gc.Equals, "\x00\x00\x00\x00\x00\x00")
    39  	n, err := io.ReadFull(randReader, raw)
    40  	c.Assert(err, gc.IsNil)
    41  	c.Assert(n, gc.Equals, 6)
    42  	c.Assert(string(raw), gc.Not(gc.Equals), "\x00\x00\x00\x00\x00\x00")
    43  }
    44  
    45  func (s *UtilSuite) TestSetReader(c *gc.C) {
    46  	orig := randReader
    47  	// This test will be mutating global state (randReader), ensure that we
    48  	// restore it sanely even if tests fail
    49  	defer func() { randReader = orig }()
    50  	// "randomize" everything to the letter 'n'
    51  	nRandom := bytes.NewBufferString("nnnnnnnnnnnnnnnnnnnnnnn")
    52  	c.Assert(randReader, gc.Equals, rand.Reader)
    53  	cleanup := setReader(nRandom)
    54  	c.Assert(randReader, gc.Equals, nRandom)
    55  	raw := make([]byte, 6)
    56  	n, err := io.ReadFull(randReader, raw)
    57  	c.Assert(err, gc.IsNil)
    58  	c.Assert(n, gc.Equals, 6)
    59  	c.Assert(string(raw), gc.Equals, "nnnnnn")
    60  	cleanup()
    61  	c.Assert(randReader, gc.Equals, rand.Reader)
    62  }
    63  
    64  // Change how we get random data, the default is to use crypto/rand
    65  // This mostly exists to be able to test error side effects
    66  // The return value is a function you can call to restore the previous
    67  // randomizer
    68  func setReader(r io.Reader) (restore func()) {
    69  	old := randReader
    70  	randReader = r
    71  	return func() {
    72  		randReader = old
    73  	}
    74  }
    75  
    76  func (s *UtilSuite) TestNotEnoughRandomBytes(c *gc.C) {
    77  	// No error, just not enough bytes
    78  	shortRand := bytes.NewBufferString("xx")
    79  	cleanup := setReader(shortRand)
    80  	defer cleanup()
    81  	c.Assert(randomHexToken, gc.PanicMatches, "failed to read 16 random bytes \\(read 2 bytes\\): unexpected EOF")
    82  }
    83  
    84  type ErrReader struct{}
    85  
    86  func (e ErrReader) Read(b []byte) (n int, err error) {
    87  	b[0] = 'x'
    88  	b[1] = 'x'
    89  	b[2] = 'x'
    90  	return 3, fmt.Errorf("Not enough bytes")
    91  }
    92  
    93  func (s *UtilSuite) TestRandomBytesError(c *gc.C) {
    94  	// No error, just not enough bytes
    95  	cleanup := setReader(ErrReader{})
    96  	defer cleanup()
    97  	c.Assert(randomHexToken, gc.PanicMatches, "failed to read 16 random bytes \\(read 3 bytes\\): Not enough bytes")
    98  }
    99  
   100  func (s *UtilSuite) TestSlowBytes(c *gc.C) {
   101  	// Even when we have to read one byte at a time, we can still get our
   102  	// hex token
   103  	defer setReader(iotest.OneByteReader(rand.Reader))()
   104  	val := randomHexToken()
   105  	c.Assert(val, gc.HasLen, 32)
   106  }