summaryrefslogtreecommitdiff
path: root/tests/test_timeout.py
blob: 90080fc57e9ca280f298ce18c940e87903cff4cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python

"""Unit tests for M2Crypto.SSL.timeout.
"""

import sys
from M2Crypto.SSL import timeout, struct_to_timeout, struct_size
from tests import unittest

# Max value for sec argument on Windows:
# - needs to fit DWORD (signed 32-bit) when converted to millisec
MAX_SEC_WIN32 = int((2**31 - 1) / 1000)

# Max value for sec argument on other platforms:
# Note: It may actually be 64-bit but we are happy with 32-bit.
# We use the signed maximum, because the packing uses lower case "l".
MAX_SEC_OTHER = 2**31 - 1

# Enable this to test the Windows logic on a non-Windows platform:
# sys.platform = 'win32'


class TimeoutTestCase(unittest.TestCase):

    def timeout_test(self, sec, microsec, exp_sec=None, exp_microsec=None):
        """
        Test that the timeout values (sec, microsec) are the same after
        round tripping through a pack / unpack cycle.
        """
        if exp_sec is None:
            exp_sec = sec
        if exp_microsec is None:
            exp_microsec = microsec

        to = timeout(sec, microsec)

        binstr = to.pack()

        act_to = struct_to_timeout(binstr)

        self.assertEqual(
            (act_to.sec, act_to.microsec), (exp_sec, exp_microsec),
            "Unexpected timeout(sec,microsec) after pack + unpack: "
            "Got (%r,%r), expected (%r,%r), input was (%r,%r)" %
            (act_to.sec, act_to.microsec, exp_sec, exp_microsec,
            sec, microsec))

    def test_timeout_0_0(self):
        self.timeout_test(0, 0)

    def test_timeout_123_0(self):
        self.timeout_test(123, 0)

    def test_timeout_max_0(self):
        if sys.platform == 'win32':
            self.timeout_test(MAX_SEC_WIN32, 0)
        else:
            self.timeout_test(MAX_SEC_OTHER, 0)

    def test_timeout_0_456000(self):
        self.timeout_test(0, 456000)

    def test_timeout_123_456000(self):
        self.timeout_test(123, 456000)

    def test_timeout_2_3000000(self):
        if sys.platform == 'win32':
            self.timeout_test(2, 3000000, 5, 0)
        else:
            self.timeout_test(2, 3000000)

    def test_timeout_2_2499000(self):
        if sys.platform == 'win32':
            self.timeout_test(2, 2499000, 4, 499000)
        else:
            self.timeout_test(2, 2499000)

    def test_timeout_2_2999000(self):
        if sys.platform == 'win32':
            self.timeout_test(2, 2999000, 4, 999000)
        else:
            self.timeout_test(2, 2999000)

    def test_timeout_max_456000(self):
        if sys.platform == 'win32':
            self.timeout_test(MAX_SEC_WIN32, 456000)
        else:
            self.timeout_test(MAX_SEC_OTHER, 456000)

    def test_timeout_0_456(self):
        if sys.platform == 'win32':
            self.timeout_test(0, 456, None, 0)
        else:
            self.timeout_test(0, 456)

    def test_timeout_123_456(self):
        if sys.platform == 'win32':
            self.timeout_test(123, 456, None, 0)
        else:
            self.timeout_test(123, 456)

    def test_timeout_max_456(self):
        if sys.platform == 'win32':
            self.timeout_test(MAX_SEC_WIN32, 456, None, 0)
        else:
            self.timeout_test(MAX_SEC_OTHER, 456)

    def test_timeout_1_499(self):
        if sys.platform == 'win32':
            self.timeout_test(123, 499, None, 0)  # 499 us rounds down to 0
        else:
            self.timeout_test(123, 499)

    def test_timeout_1_501(self):
        # We use 501 for this test and not 500 because 0.5 is not exactly
        # represented in binary floating point numbers, and because 0.5
        # rounds differently between py2 and py3. See Python round() docs.
        if sys.platform == 'win32':
            self.timeout_test(123, 501, None, 1000)  # 501 us rounds up to 1000
        else:
            self.timeout_test(123, 501)

    def test_timeout_size(self):
        exp_size = len(timeout(0, 0).pack())
        self.assertEqual(struct_size(), exp_size)


def suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.TestLoader().loadTestsFromTestCase(TimeoutTestCase))
    return suite


if __name__ == '__main__':
    unittest.TextTestRunner().run(suite())