1# Copyright 2015 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import pprint 7import socket 8import time 9 10from autotest_lib.client.common_lib import error 11from autotest_lib.server.cros import stress 12from autotest_lib.server import autotest 13from autotest_lib.server import test 14 15_CLIENT_COMPLETE_FLAG = '/tmp/network_FirewallHolePunch' 16 17class network_FirewallHolePunchServer(test.test): 18 """Server test half of the FirewallHolePunch test.""" 19 version = 1 20 21 22 def connect_to_dut(self): 23 """Attempts to connect to the DUT 24 25 @returns True if connection was successful; False otherwise. 26 27 """ 28 clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 29 clientsocket.settimeout(5) 30 31 connected = False 32 try: 33 clientsocket.connect((self.hostname, self.port)) 34 connected = True 35 logging.debug('Connected to client') 36 except socket.timeout: 37 logging.debug('Socket connection to DUT failed.') 38 39 return connected 40 41 42 def wait_for_client_test(self): 43 """Waits for the client test to complete it's task. 44 45 @returns True if the client responds to the request; False otherwise. 46 47 """ 48 49 for i in range(30): 50 result = self.client.run('ls %s' % _CLIENT_COMPLETE_FLAG, 51 ignore_status=True) 52 if result.exit_status == 0: 53 return True 54 time.sleep(1) 55 return False 56 57 58 def functional_test(self, test_error, test_fail, connected): 59 """Performs a functional testing of the firewall. 60 61 This performs a single test while coordinating with the client test. 62 63 @param test_error: string of the test error message 64 @param test_fail: string of the test fail message 65 @param connected: boolean test if the connection attempt should have 66 passed or failed. 67 68 @raises: TestError if the client flag was not updated 69 @raises: TestFail if the connection expection is not met 70 71 """ 72 73 self.client.run('rm %s' % _CLIENT_COMPLETE_FLAG, ignore_status=True) 74 if self.wait_for_client_test() is False: 75 raise error.TestError(test_error) 76 if self.connect_to_dut() is connected: 77 raise error.TestFail(test_fail) 78 79 80 def perform_tests(self): 81 """Performs all of the tests in the script.""" 82 83 for test in self.tests: 84 logging.debug('Performing...') 85 logging.debug(pprint.pprint(test)) 86 87 self.functional_test(test['server_error'], 88 test['server_fail'], 89 test['server_connected']) 90 91 92 def run_once(self, host, port=8888): 93 """Run the test. 94 95 @param host: the host object 96 @param port: integer value for the port the client to listen on 97 98 """ 99 100 # Strict ordering matters here. If an invalid order is given 101 # below an exception will be thrown in the client test. 102 self.tests = [# Login, fail to connect 103 {'server_error': 'The client test did not login', 104 'server_fail' : 'Server was able to connect (login).', 105 'server_connected' : True, 106 'client_command' : 'login', 107 'client_error': 'Did not receive command to login (login)' 108 }, 109 # Launch App, fail to connect 110 {'server_error': 'The client test did not launch the app', 111 'server_fail' : 'Server was able to connect (setup).', 112 'server_connected' : True, 113 'client_command' : 'launch app', 114 'client_error': 'Did not receive command to launch app (setup)' 115 }, 116 # Start server, connect 117 {'server_error': 'The client test did not open the port. (1)', 118 'server_fail' : 'Server was unable to connect (1).', 119 'server_connected' : False, 120 'client_command' : 'start server', 121 'client_error': 'Did not receive command to start server (1)' 122 }, 123 # Stop server, fail to connect 124 {'server_error' : 'The client test did not close the port', 125 'server_fail' : str('Server was able to connect to the port. (1) ' 126 '(It should not have been able to do so.)'), 127 'server_connected' : True, 128 'client_command' : 'stop server', 129 'client_error' : 'Did not receive command to stop server' 130 }, 131 # Start server, connect 132 {'server_error' : 'The client test did not open the port. (2)', 133 'server_fail' : 'Server was unable to connect (2).', 134 'server_connected' : False, 135 'client_command' : 'start server', 136 'client_error' : 'Did not receive command to start server (2)' 137 }, 138 # Quit app, fail to connect 139 {'server_error' : 'The client test did not close the app.', 140 'server_fail' : str('Server was able to connect to the port (2). ' 141 '(It should not have been able to do so.)'), 142 'server_connected' : True, 143 'client_command' : 'exit app', 144 'client_error' : 'Did not receive command to close app.' 145 }, 146 # Telemetry cannot relaunch a closed extension; logout and back in. 147 # Logout, fail to connect 148 {'server_error' : 'The client test did not quit', 149 'server_fail' : str('Server was able to connect to the port (3). ' 150 '(It should not have been able to do so.)'), 151 'server_connected' : True, 152 'client_command' : 'logout', 153 'client_error': 'Did not receive command to exit.' 154 }, 155 # Login, fail to connect 156 {'server_error': 'The client test did not login', 157 'server_fail' : 'Server was able to connect (login).', 158 'server_connected' : True, 159 'client_command' : 'login', 160 'client_error': 'Did not receive command to login (login)' 161 }, 162 # Launch app, fail to connect 163 {'server_error': 'The client test did not launch the app', 164 'server_fail' : 'Server was able to connect (setup2).', 165 'server_connected' : True, 166 'client_command' : 'launch app', 167 'client_error': 'Did not receive command to launch app (setup2)' 168 }, 169 # Start server, connect 170 {'server_error': 'The client test did not open the port. (1)', 171 'server_fail' : 'Server was unable to connect (1).', 172 'server_connected' : False, 173 'client_command' : 'start server', 174 'client_error': 'Did not receive command to start server (1)' 175 }, 176 # Logout, fail to connect 177 {'server_error' : 'The client test did not quit', 178 'server_fail' : str('Server was able to connect to the port (3). ' 179 '(It should not have been able to do so.)'), 180 'server_connected' : True, 181 'client_command' : 'logout', 182 'client_error': 'Did not receive command to exit.' 183 } 184 ] 185 186 self.client = host 187 self.hostname = self.client.hostname 188 self.port = port 189 client_at = autotest.Autotest(self.client) 190 191 self.client.run('rm %s' % _CLIENT_COMPLETE_FLAG, ignore_status=True) 192 193 stressor = stress.CountedStressor(self.perform_tests) 194 stressor.start(1) 195 client_at.run_test('network_FirewallHolePunch', 196 test_sequence=self.tests, 197 port=self.port) 198 199