barrier_unittest.py revision 02fc0b9199aa71c7f801aee4fcd4b86513e8facb
1#!/usr/bin/python
2
3__author__ = """Ashwin Ganti (aganti@google.com)"""
4
5import os, sys, socket, errno, unittest, threading
6from time import time, sleep
7import common
8from autotest_lib.client.common_lib import error, barrier
9from autotest_lib.client.common_lib.test_utils import mock
10
11
12class listen_server_test(unittest.TestCase):
13
14    def test_init(self):
15        server = barrier.listen_server()
16        server.close()
17
18
19    def test_close(self):
20        server = barrier.listen_server()
21        # cannot bind on the same port again
22        self.assertRaises(socket.error, barrier.listen_server)
23        server.close()
24        # now we can
25        server = barrier.listen_server()
26        server.close()
27
28
29class barrier_test(unittest.TestCase):
30
31    def setUp(self):
32        self.god = mock.mock_god()
33        self.god.mock_io()
34
35
36    def tearDown(self):
37        self.god.unmock_io()
38
39
40    def test_initialize(self):
41        b = barrier.barrier('127.0.0.1#', 'testtag', 100, 11921)
42        self.assertEqual(b._hostid, '127.0.0.1#')
43        self.assertEqual(b._tag, 'testtag')
44        self.assertEqual(b._timeout_secs, 100)
45        self.assertEqual(b._port, 11921)
46
47
48    def test_get_host_from_id(self):
49        b = barrier.barrier('127.0.0.1#', 'testgethost', 100)
50
51        hostname = b._get_host_from_id('my_host')
52        self.assertEqual(hostname, 'my_host')
53
54        hostname = b._get_host_from_id('my_host#')
55        self.assertEqual(hostname, 'my_host')
56
57        self.assertRaises(error.BarrierError, b._get_host_from_id, '#my_host')
58
59
60    def test_update_timeout(self):
61        b = barrier.barrier('127.0.0.1#', 'update', 100)
62        b._update_timeout(120)
63        self.assertEqual(b._timeout_secs, 120)
64
65
66    def test_remaining(self):
67        b = barrier.barrier('127.0.0.1#', 'remain', 100)
68        remain = b._remaining()
69        self.assertEqual(remain, 100)
70
71
72    def test_master_welcome_garbage(self):
73        b = barrier.barrier('127.0.0.1#', 'garbage', 100)
74        waiting_before = dict(b._waiting)
75        seen_before = b._seen
76
77        sender, receiver = socket.socketpair()
78        try:
79            sender.send('GET /foobar?p=-1 HTTP/1.0\r\n\r\n')
80            # This should not raise an exception.
81            b._master_welcome((receiver, 'fakeaddr'))
82
83            self.assertEqual(waiting_before, b._waiting)
84            self.assertEqual(seen_before, b._seen)
85
86            sender, receiver = socket.socketpair()
87            sender.send('abcdefg\x00\x01\x02\n'*5)
88            # This should not raise an exception.
89            b._master_welcome((receiver, 'fakeaddr'))
90
91            self.assertEqual(waiting_before, b._waiting)
92            self.assertEqual(seen_before, b._seen)
93        finally:
94            sender.close()
95            receiver.close()
96
97
98    def test_rendezvous_basic(self):
99        # Basic rendezvous testing
100        self.rendezvous_test(60, port=11920)
101
102
103    def test_rendezvous_timeout(self):
104        # The rendezvous should time out here and throw a
105        # BarrierError since we are specifying a timeout of 0
106        self.assertRaises(error.BarrierError,
107                          self.rendezvous_test, 0, port=11921)
108
109
110    def test_rendezvous_abort_ok(self):
111        # Test with abort flag set to not abort.
112        self.rendezvous_test(60, port=11920,
113                             test_abort=True, abort=False)
114
115
116    def test_rendezvous_abort(self):
117        # The rendezvous should abort here and throw a
118        # BarrierError since we are asking to abort
119        self.assertRaises(error.BarrierError,
120                          self.rendezvous_test, 0, port=11921,
121                          test_abort=True, abort=True)
122
123
124    def test_rendezvous_servers_basic(self):
125        # The rendezvous should time out here and throw a
126        # BarrierError since we are specifying a timeout of 0
127        self.rendezvous_test(60, port=11921,
128                             rendezvous_servers=True)
129
130
131    def test_rendezvous_servers_timeout(self):
132        # The rendezvous should time out here and throw a
133        # BarrierError since we are specifying a timeout of 0
134        self.assertRaises(error.BarrierError,
135                          self.rendezvous_test, 0, port=11922,
136                          rendezvous_servers=True)
137
138
139    def test_rendezvous_servers_abort_ok(self):
140        # Test with abort flag set to not abort.
141        self.rendezvous_test(60, port=11920, rendezvous_servers=True,
142                             test_abort=True, abort=False)
143
144
145    def test_rendezvous_servers_abort(self):
146        # The rendezvous should abort here and throw a
147        # BarrierError since we are asking to abort
148        self.assertRaises(error.BarrierError,
149                          self.rendezvous_test, 0, port=11922,
150                          rendezvous_servers=True,
151                          test_abort=True, abort=True)
152
153
154    # Internal utility function (not a unit test)
155    def rendezvous_test(self, timeout, port=11922,
156                        rendezvous_servers=False, test_abort=False,
157                        abort=False, listen_server=None):
158        if listen_server:
159            port = None
160
161        def _rdv(addr):
162            b1 = barrier.barrier(addr, "test_meeting", timeout, port,
163                                 listen_server=listen_server)
164            if not rendezvous_servers:
165                if test_abort:
166                    b1.rendezvous('127.0.0.1#0', '127.0.0.1#1', abort=abort)
167                else:
168                    b1.rendezvous('127.0.0.1#0', '127.0.0.1#1')
169            else:
170                if test_abort:
171                    b1.rendezvous_servers('127.0.0.1#0', '127.0.0.1#1',
172                                          abort=abort)
173                else:
174                    b1.rendezvous_servers('127.0.0.1#0', '127.0.0.1#1')
175
176
177        def _thread_rdv(addr):
178            # We need to ignore the exception on one side.
179            try:
180                _rdv(addr)
181            except error.BarrierError:
182                pass
183
184        client = threading.Thread(target=_thread_rdv,
185                                  args=('127.0.0.1#0',))
186        client.start()
187        _rdv('127.0.0.1#1')
188        client.join()
189
190
191    def test_reusing_listen_server(self):
192        """
193        Test that reusing the same listen server object works.
194        """
195        server = barrier.listen_server()
196        self.rendezvous_test(10, listen_server=server)
197        self.rendezvous_test(10, listen_server=server)
198        self.rendezvous_test(10, listen_server=server)
199
200
201if __name__ == "__main__":
202    unittest.main()
203