1999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh#!/usr/bin/python
2999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
3999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh__author__ = """Ashwin Ganti (aganti@google.com)"""
4999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
5999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighimport os, sys, socket, errno, unittest, threading
6999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighfrom time import time, sleep
7999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighimport common
8861b2d54aec24228cdb3895dbc40062cb40cb2adEric Lifrom autotest_lib.client.common_lib import error, barrier, base_barrier
9999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighfrom autotest_lib.client.common_lib.test_utils import mock
10999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
11999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
12999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighclass listen_server_test(unittest.TestCase):
13999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
14999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_init(self):
15999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server = barrier.listen_server()
16999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server.close()
17999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
18999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
19999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_close(self):
20999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server = barrier.listen_server()
21999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # cannot bind on the same port again
22999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertRaises(socket.error, barrier.listen_server)
23999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server.close()
24999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # now we can
25999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server = barrier.listen_server()
26999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server.close()
27999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
28999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
29999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighclass barrier_test(unittest.TestCase):
30999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
31999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def setUp(self):
32999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.god = mock.mock_god()
33999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.god.mock_io()
34999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
35999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
36999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def tearDown(self):
37999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.god.unmock_io()
38999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
39999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
40999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_initialize(self):
41999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        b = barrier.barrier('127.0.0.1#', 'testtag', 100, 11921)
42999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(b._hostid, '127.0.0.1#')
43999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(b._tag, 'testtag')
44999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(b._timeout_secs, 100)
45999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(b._port, 11921)
46999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
47999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
4838c9960162f1eaad0d3b197e2662c815cc286f2eAllen Li    def test__get_host_from_id(self):
4938c9960162f1eaad0d3b197e2662c815cc286f2eAllen Li        hostname = base_barrier._get_host_from_id('my_host')
50999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(hostname, 'my_host')
51999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
5238c9960162f1eaad0d3b197e2662c815cc286f2eAllen Li        hostname = base_barrier._get_host_from_id('my_host#')
53999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(hostname, 'my_host')
54999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
55861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        self.assertRaises(error.BarrierError,
5638c9960162f1eaad0d3b197e2662c815cc286f2eAllen Li                          base_barrier._get_host_from_id, '#my_host')
57999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
58999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
59999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_update_timeout(self):
60999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        b = barrier.barrier('127.0.0.1#', 'update', 100)
61999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        b._update_timeout(120)
62999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(b._timeout_secs, 120)
63999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
64999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
65999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_remaining(self):
66999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        b = barrier.barrier('127.0.0.1#', 'remain', 100)
67999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        remain = b._remaining()
68999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertEqual(remain, 100)
69999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
70999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
71999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_master_welcome_garbage(self):
72999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        b = barrier.barrier('127.0.0.1#', 'garbage', 100)
73999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        waiting_before = dict(b._waiting)
74999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        seen_before = b._seen
75999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
76999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        sender, receiver = socket.socketpair()
77999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        try:
78999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            sender.send('GET /foobar?p=-1 HTTP/1.0\r\n\r\n')
79999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            # This should not raise an exception.
80999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            b._master_welcome((receiver, 'fakeaddr'))
81999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
82999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            self.assertEqual(waiting_before, b._waiting)
83999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            self.assertEqual(seen_before, b._seen)
84999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
85999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            sender, receiver = socket.socketpair()
86999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            sender.send('abcdefg\x00\x01\x02\n'*5)
87999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            # This should not raise an exception.
88999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            b._master_welcome((receiver, 'fakeaddr'))
89999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
90999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            self.assertEqual(waiting_before, b._waiting)
91999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            self.assertEqual(seen_before, b._seen)
92999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        finally:
93999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            sender.close()
94999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            receiver.close()
95999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
96999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
97999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_basic(self):
98999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # Basic rendezvous testing
99999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(60, port=11920)
100999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
101999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
102999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_timeout(self):
103999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # The rendezvous should time out here and throw a
104999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # BarrierError since we are specifying a timeout of 0
105999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertRaises(error.BarrierError,
106999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          self.rendezvous_test, 0, port=11921)
107999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
108999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
109999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_abort_ok(self):
110999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # Test with abort flag set to not abort.
111999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(60, port=11920,
112999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                             test_abort=True, abort=False)
113999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
114999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
115999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_abort(self):
116999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # The rendezvous should abort here and throw a
117999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # BarrierError since we are asking to abort
118999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertRaises(error.BarrierError,
119999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          self.rendezvous_test, 0, port=11921,
120999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          test_abort=True, abort=True)
121999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
122999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
123999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_servers_basic(self):
124999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # The rendezvous should time out here and throw a
125999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # BarrierError since we are specifying a timeout of 0
126999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(60, port=11921,
127999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                             rendezvous_servers=True)
128999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
129999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
130999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_servers_timeout(self):
131999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # The rendezvous should time out here and throw a
132999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # BarrierError since we are specifying a timeout of 0
133999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertRaises(error.BarrierError,
134999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          self.rendezvous_test, 0, port=11922,
135999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          rendezvous_servers=True)
136999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
137999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
138999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_servers_abort_ok(self):
139999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # Test with abort flag set to not abort.
140999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(60, port=11920, rendezvous_servers=True,
141999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                             test_abort=True, abort=False)
142999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
143999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
144999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_rendezvous_servers_abort(self):
145999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # The rendezvous should abort here and throw a
146999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        # BarrierError since we are asking to abort
147999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.assertRaises(error.BarrierError,
148999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          self.rendezvous_test, 0, port=11922,
149999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          rendezvous_servers=True,
150999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                          test_abort=True, abort=True)
151999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
152999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
153999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    # Internal utility function (not a unit test)
154999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def rendezvous_test(self, timeout, port=11922,
155999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                        rendezvous_servers=False, test_abort=False,
156999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                        abort=False, listen_server=None):
157999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        if listen_server:
158999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            port = None
159999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
160999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        def _rdv(addr):
161999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            b1 = barrier.barrier(addr, "test_meeting", timeout, port,
162999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                                 listen_server=listen_server)
163999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            if not rendezvous_servers:
164999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                if test_abort:
165999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                    b1.rendezvous('127.0.0.1#0', '127.0.0.1#1', abort=abort)
166999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                else:
167999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                    b1.rendezvous('127.0.0.1#0', '127.0.0.1#1')
168999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            else:
169999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                if test_abort:
170999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                    b1.rendezvous_servers('127.0.0.1#0', '127.0.0.1#1',
171999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                                          abort=abort)
172999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                else:
173999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                    b1.rendezvous_servers('127.0.0.1#0', '127.0.0.1#1')
174999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
175999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
176999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        def _thread_rdv(addr):
177999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            # We need to ignore the exception on one side.
178999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            try:
179999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                _rdv(addr)
180999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh            except error.BarrierError:
181999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                pass
182999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
183999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        client = threading.Thread(target=_thread_rdv,
184999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh                                  args=('127.0.0.1#0',))
185999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        client.start()
186999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        _rdv('127.0.0.1#1')
187999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        client.join()
188999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
189999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
190999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    def test_reusing_listen_server(self):
191999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        """
192999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        Test that reusing the same listen server object works.
193999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        """
194999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        server = barrier.listen_server()
195999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(10, listen_server=server)
196999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(10, listen_server=server)
197999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh        self.rendezvous_test(10, listen_server=server)
198999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
199999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh
200999fb13dcbf4de5e37ca2b3059ef1061b5faba43mblighif __name__ == "__main__":
201999fb13dcbf4de5e37ca2b3059ef1061b5faba43mbligh    unittest.main()
202