1e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa#!/usr/bin/python 2e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa# Copyright 2017 The Chromium OS Authors. All rights reserved. 3e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa# Use of this source code is governed by a BSD-style license that can be 4e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa# found in the LICENSE file. 5e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 6e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaimport os 7e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaimport shutil 8e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaimport socket 9e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaimport tempfile 10e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaimport unittest 11e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwafrom multiprocessing import connection 12e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 13e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaimport common 14e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwafrom autotest_lib.client.common_lib import error 15e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwafrom autotest_lib.site_utils.lxc import unittest_setup 16e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwafrom autotest_lib.site_utils.lxc.container_pool import async_listener 17764c6d7451342e00768b9724badcc9514d31f626Ben Kwafrom autotest_lib.site_utils.lxc.container_pool import unittest_client 18e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 19e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 20e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa# Namespace object for parsing cmd line options. 21e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaoptions = None 22e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 23e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 24e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaclass AsyncListenerTests(unittest.TestCase): 25e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Unit tests for the AsyncListener class.""" 26e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 27e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def setUp(self): 28e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.tmpdir = tempfile.mkdtemp() 29e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.address = os.path.join(self.tmpdir, 'socket') 30e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.authkey = 'foo' 31764c6d7451342e00768b9724badcc9514d31f626Ben Kwa self.listener = async_listener.AsyncListener(self.address) 32e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 33e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 34e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def tearDown(self): 35e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.listener.close() 36e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa shutil.rmtree(self.tmpdir) 37e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 38e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 39e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testInvalidAddresses(self): 40e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Verifies that invalid socket paths raise errors.""" 41e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa with self.assertRaises(socket.error): 42e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa invalid_address = os.path.join(self.tmpdir, 'foo', 'socket') 43764c6d7451342e00768b9724badcc9514d31f626Ben Kwa async_listener.AsyncListener(invalid_address) 44e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 45e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 46e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testAddressConflict(self): 47e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Verifies that address conflicts raise errors.""" 48e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa with self.assertRaises(socket.error): 49764c6d7451342e00768b9724badcc9514d31f626Ben Kwa async_listener.AsyncListener(self.address) 50e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 51e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 52e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testInetAddresses(self): 53e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Verifies that inet addresses raise errors.""" 54e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa with self.assertRaises(TypeError): 55764c6d7451342e00768b9724badcc9514d31f626Ben Kwa async_listener.AsyncListener(('127.0.0.1', 0)) 56e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 57e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 58e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testStartStop(self): 59e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Tests starting and stopping the async listener.""" 60e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa try: 61e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertFalse(self.listener.is_running()) 62e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 63e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.listener.start() 64e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertTrue(self.listener.is_running()) 65e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 66e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # Establish a connection to verify that the listener is actually 67e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # alive. 68e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host, client = self._make_connection() 69e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa client.close() 70e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host.close() 71e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 72e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertTrue(self.listener.stop()) 73e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertFalse(self.listener.is_running()) 74e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa except: 75e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.fail(error.format_error()) 76e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 77e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 78e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testStop_notRunning(self): 79e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Tests stopping the async listener when it's not running.""" 80e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa try: 81e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertFalse(self.listener.is_running()) 82e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # Verify that calling stop just returns False when the listener 83e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # isn't running. 84e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertFalse(self.listener.stop()) 85e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa except: 86e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.fail(error.format_error()) 87e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 88e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 89e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testConnection(self): 90e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Tests starting a connection.""" 91e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.listener.start() 92e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 93e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # Verify no pending connections. 94e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertIsNone(self.listener.get_connection(timeout=1)) 95e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 96e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # Start a client connection, verify that the listener now returns a 97e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # pending connection. Keep a reference to the client, so it doesn't get 98e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # GC'd while the test is in progress. 99764c6d7451342e00768b9724badcc9514d31f626Ben Kwa _unused = connection.Client(self.address) 100e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertIsNotNone(self.listener.get_connection(timeout=1)) 101e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 102e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 103e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testHostToClientComms(self): 104e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Tests that client/host connections can exchange data.""" 105e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.listener.start() 106e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host, client = self._make_connection() 107e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 108e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # Send a message on the host side socket, check that the client receives 109e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # it. 110e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa msg = 'quickly moving jedi zap a brown sith fox' 111e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host.send(msg) 112e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa received_msg = client.recv() 113e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertEqual(msg, received_msg) 114e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 115e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 116e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def testMultipleConnections(self): 117e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Tests for correct pairing of multiple host/client connections.""" 118e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.listener.start() 119e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 120e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # Create two sets of host/client connections. Verify that messages sent 121e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa # on each client are received by the correct respective host. 122e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host0, client0 = self._make_connection() 123e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host1, client1 = self._make_connection() 124e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 125e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa msg0 = 'a large fawn jumped quickly over white zinc boxes' 126e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa msg1 = 'six big devils from japan quickly forgot how to waltz' 127e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 128e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa client0.send(msg0) 129e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa client1.send(msg1) 130e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 131e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa received_msg0 = host0.recv() 132e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa received_msg1 = host1.recv() 133e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 134e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertEquals(msg0, received_msg0) 135e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa self.assertEquals(msg1, received_msg1) 136e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 137e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 138e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa def _make_connection(self): 139e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """Creates pairs of host/client connections. 140e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 141e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa @return: A host, client connection pair. 142e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa """ 143764c6d7451342e00768b9724badcc9514d31f626Ben Kwa client = unittest_client.connect(self.address) 144e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa host = self.listener.get_connection(timeout=1) 145e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa return host, client 146e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 147e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 148e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa 149e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwaif __name__ == '__main__': 150e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa unittest_setup.setup() 151e05b6e5b047d81087aa5ac9462f217de312ad0f3Ben Kwa unittest.main() 152