~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/test/test_randbytes.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2007 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Test cases for L{twisted.python.randbytes}.
 
6
"""
 
7
 
 
8
import os, sys
 
9
 
 
10
from twisted.trial import unittest
 
11
from twisted.python import randbytes
 
12
 
 
13
try:
 
14
    from Crypto.Util import randpool
 
15
except ImportError:
 
16
    randpool = None
 
17
 
 
18
 
 
19
 
 
20
class SecureRandomTestCaseBase(object):
 
21
    """
 
22
    Base class for secureRandom test cases.
 
23
    """
 
24
 
 
25
    def _check(self, source):
 
26
        """
 
27
        The given random bytes source should return the number of bytes
 
28
        requested each time it is called and should probably not return the
 
29
        same bytes on two consecutive calls (although this is a perfectly
 
30
        legitimate occurrence and rejecting it may generate a spurious failure
 
31
        -- maybe we'll get lucky and the heat death with come first).
 
32
        """
 
33
        for nbytes in range(17, 25):
 
34
            s = source(nbytes)
 
35
            self.assertEquals(len(s), nbytes)
 
36
            s2 = source(nbytes)
 
37
            self.assertEquals(len(s2), nbytes)
 
38
            # This is crude but hey
 
39
            self.assertNotEquals(s2, s)
 
40
 
 
41
 
 
42
 
 
43
class SecureRandomTestCase(SecureRandomTestCaseBase, unittest.TestCase):
 
44
    """
 
45
    Test secureRandom under normal conditions.
 
46
    """
 
47
 
 
48
    def test_normal(self):
 
49
        """
 
50
        L{randbytes.secureRandom} should return a string of the requested
 
51
        length and make some effort to make its result otherwise unpredictable.
 
52
        """
 
53
        self._check(randbytes.secureRandom)
 
54
 
 
55
 
 
56
 
 
57
class ConditionalSecureRandomTestCase(SecureRandomTestCaseBase,
 
58
                                      unittest.TestCase):
 
59
    """
 
60
    Test random sources one by one, then remove it to.
 
61
    """
 
62
 
 
63
    def setUp(self):
 
64
        """
 
65
        Create a L{randbytes.RandomFactory} to use in the tests.
 
66
        """
 
67
        self.factory = randbytes.RandomFactory()
 
68
 
 
69
 
 
70
    def errorFactory(self, nbytes):
 
71
        """
 
72
        A factory raising an error when a source is not available.
 
73
        """
 
74
        raise randbytes.SourceNotAvailable()
 
75
 
 
76
 
 
77
    def test_osUrandom(self):
 
78
        """
 
79
        L{RandomFactory._osUrandom} should work as a random source whenever
 
80
        L{os.urandom} is available.
 
81
        """
 
82
        try:
 
83
            self._check(self.factory._osUrandom)
 
84
        except randbytes.SourceNotAvailable:
 
85
            # Not available on Python 2.3
 
86
            self.assertTrue(sys.version_info < (2, 4))
 
87
 
 
88
 
 
89
    def test_fileUrandom(self):
 
90
        """
 
91
        L{RandomFactory._fileUrandom} should work as a random source whenever
 
92
        C{/dev/urandom} is available.
 
93
        """
 
94
        try:
 
95
            self._check(self.factory._fileUrandom)
 
96
        except randbytes.SourceNotAvailable:
 
97
            # The test should only fail in /dev/urandom doesn't exist
 
98
            self.assertFalse(os.path.exists('/dev/urandom'))
 
99
 
 
100
 
 
101
    def test_cryptoRandom(self):
 
102
        """
 
103
        L{RandomFactory._cryptoRandom} should work as a random source whenever
 
104
        L{PyCrypto} is installed.
 
105
        """
 
106
        try:
 
107
            self._check(self.factory._cryptoRandom)
 
108
        except randbytes.SourceNotAvailable:
 
109
            # It fails if PyCrypto is not here
 
110
            self.assertIdentical(randpool, None)
 
111
 
 
112
 
 
113
    def test_withoutOsUrandom(self):
 
114
        """
 
115
        If L{os.urandom} is not available but L{PyCrypto} is,
 
116
        L{RandomFactory.secureRandom} should still work as a random source.
 
117
        """
 
118
        self.factory._osUrandom = self.errorFactory
 
119
        self._check(self.factory.secureRandom)
 
120
 
 
121
    if randpool is None:
 
122
        test_withoutOsUrandom.skip = "PyCrypto not available"
 
123
 
 
124
 
 
125
    def test_withoutOsAndFileUrandom(self):
 
126
        """
 
127
        Remove C{os.urandom} and /dev/urandom read.
 
128
        """
 
129
        self.factory._osUrandom = self.errorFactory
 
130
        self.factory._fileUrandom = self.errorFactory
 
131
        self._check(self.factory.secureRandom)
 
132
 
 
133
    if randpool is None:
 
134
        test_withoutOsAndFileUrandom.skip = "PyCrypto not available"
 
135
 
 
136
 
 
137
    def test_withoutAnything(self):
 
138
        """
 
139
        Remove all secure sources and assert it raises a failure. Then try the
 
140
        fallback parameter.
 
141
        """
 
142
        self.factory._osUrandom = self.errorFactory
 
143
        self.factory._fileUrandom = self.errorFactory
 
144
        self.factory._cryptoRandom = self.errorFactory
 
145
        self.assertRaises(randbytes.SecureRandomNotAvailable,
 
146
                          self.factory.secureRandom, 18)
 
147
        def wrapper():
 
148
            return self.factory.secureRandom(18, fallback=True)
 
149
        s = self.assertWarns(
 
150
            RuntimeWarning,
 
151
            "Neither PyCrypto nor urandom available - "
 
152
            "proceeding with non-cryptographically secure random source",
 
153
            __file__,
 
154
            wrapper)
 
155
        self.assertEquals(len(s), 18)
 
156
 
 
157
 
 
158
 
 
159
class RandomTestCaseBase(SecureRandomTestCaseBase, unittest.TestCase):
 
160
    """
 
161
    'Normal' random test cases.
 
162
    """
 
163
 
 
164
    def test_normal(self):
 
165
        """
 
166
        Test basic case.
 
167
        """
 
168
        self._check(randbytes.insecureRandom)
 
169
 
 
170
 
 
171
    def test_withoutGetrandbits(self):
 
172
        """
 
173
        Test C{insecureRandom} without C{random.getrandbits}.
 
174
        """
 
175
        factory = randbytes.RandomFactory()
 
176
        factory.getrandbits = None
 
177
        self._check(factory.insecureRandom)
 
178