def test_execute(self): """Test task queue execute.""" drone1 = self.create_remote_drone('fakehostname1') drone2 = self.create_remote_drone('fakehostname2') drone3 = self.create_remote_drone('fakehostname3') # Check task queue exception conditions. task_queue = thread_lib.ThreadedTaskQueue() task_queue.results_queue.put(1) self.assertRaises(drone_task_queue.DroneTaskQueueException, task_queue.execute, []) task_queue.results_queue.get() task_queue.drone_threads[drone1] = None self.assertRaises(drone_task_queue.DroneTaskQueueException, task_queue.execute, []) task_queue.drone_threads = {} # Queue 2 calls against each drone, and confirm that the host's # run method is called 3 times. Then check the threads created, # and finally compare results returned by the task queue against # the mock results. drones = [drone1, drone2, drone3] for drone in drones: drone.queue_call('foo') drone.queue_call('bar') mock_result = utils.CmdResult( stdout=cPickle.dumps(self.mock_return)) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(drone.get_calls()), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) task_queue.execute(drones, wait=False) self.assertTrue(set(task_queue.drone_threads.keys()) == set(drones)) for drone, thread in task_queue.drone_threads.iteritems(): self.assertTrue(drone.hostname in thread.getName()) self.assertTrue(thread.isDaemon()) self.assertRaises(RuntimeError, thread.start) results = task_queue.get_results() for drone, result in results.iteritems(): self.assertTrue(result == self.mock_return['results']) # Test synchronous execute drone1.queue_call('foo') mock_result = utils.CmdResult(stdout=cPickle.dumps(self.mock_return)) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(drone1.get_calls()), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) self.assertTrue( task_queue.execute(drones, wait=True)[drone1] == self.mock_return['results']) self.god.check_playback()
def construct_server_job(self): # XXX(gps): These expect_call's must be kept in perfect sync # call for call with what base_server_job does. This is too # painful to maintain. # setup recording for constructor file_obj = self.god.create_mock_class(file, "file") server_job.open.expect_call(self.control).and_return(file_obj) file_obj.read.expect_call().and_return('') file_obj.close.expect_call() os.path.exists.expect_call( mock.is_string_comparator()).and_return(False) os.mkdir.expect_call(mock.is_string_comparator()) os.path.exists.expect_call( mock.is_string_comparator()).and_return(False) os.mkdir.expect_call(mock.is_string_comparator()) self.god.mock_up(sysinfo, 'sysinfo') sysinfo.sysinfo.expect_call(mock.is_string_comparator()) os.access.expect_call(mock.is_string_comparator(), os.W_OK).and_return(False) os.makedirs.expect_call(mock.is_string_comparator(), 0700) os.access.expect_call(mock.is_string_comparator(), os.W_OK).and_return(True) os.path.isdir.expect_call(mock.is_string_comparator()).and_return(False) self.god.stub_function(tempfile, 'gettempdir') tempfile.gettempdir.expect_call().and_return('/tmp/server_job_unittest') os.makedirs.expect_call(mock.is_string_comparator(), 0700).and_raises(os.error) os.chmod.expect_call(mock.is_string_comparator(), stat.S_IRWXU) cls = server_job.base_server_job compare = mock.is_instance_comparator(cls) os.path.isdir.expect_call('results').and_return(True) os.path.exists.expect_call('results/keyval').and_return(False) server_job.get_site_job_data.expect_call(compare).and_return({}) utils.write_keyval.expect_call(mock.is_string_comparator(), mock.is_instance_comparator(dict)) self.job = server_job.base_server_job(self.control, self.args, self.resultdir, self.label, self.user, self.machines) self.god.check_playback() # use this stub alot self.god.stub_function(self.job, "_execute_code")
def test_fill_server_control_namespace(self): class MockAutotest(object): job = None class MockHosts(object): job = None # Verify that the job attributes are injected in the expected place. self.god.stub_with(autotest, 'Autotest', MockAutotest) self.god.stub_with(hosts, 'Host', MockHosts) self.job._fill_server_control_namespace({}) self.assertEqual(hosts.Host.job, self.job) self.assertEqual(autotest.Autotest.job, self.job) test_ns = {} self.job._fill_server_control_namespace(test_ns) # Verify that a few of the expected module exports were loaded. self.assertEqual(test_ns['sys'], sys) self.assert_('git' in test_ns) self.assert_('parallel_simple' in test_ns) self.assert_('sh_escape' in test_ns) self.assert_('barrier' in test_ns) self.assert_('format_error' in test_ns) self.assert_('AutoservRebootError' in test_ns) # This should not exist, client.common_lib.errors does not export it. self.assert_('format_exception' not in test_ns) # Replacing something that exists with something else is an error. orig_test_ns = {'hosts': 'not the autotest_lib.server.hosts module'} test_ns = orig_test_ns.copy() self.assertRaises(error.AutoservError, self.job._fill_server_control_namespace, test_ns) # Replacing something that exists with something else is an error. test_ns = orig_test_ns.copy() self.assertRaises(error.AutoservError, self.job._fill_server_control_namespace, test_ns) # Replacing something without protection should succeed. test_ns = orig_test_ns.copy() self.job._fill_server_control_namespace(test_ns, protect=False) self.assertEqual(test_ns['hosts'], hosts) # Replacing something with itself should issue a warning. test_ns = {'hosts': hosts} self.god.stub_function(warnings, 'showwarning') warnings.showwarning.expect_call( mock.is_instance_comparator(UserWarning), UserWarning, mock.is_string_comparator(), mock.is_instance_comparator(int)) self.job._fill_server_control_namespace(test_ns) self.god.check_playback() self.assertEqual(test_ns['hosts'], hosts)
def test_execute(self): """Test execute method.""" drone1 = self.create_remote_drone('fakehostname1') drone2 = self.create_remote_drone('fakehostname2') drone3 = self.create_remote_drone('fakehostname3') # Check task queue exception conditions. task_queue = drone_task_queue.DroneTaskQueue() task_queue.results[drone1] = None self.assertRaises(drone_task_queue.DroneTaskQueueException, task_queue.execute, []) task_queue.results.clear() # Queue 2 calls against each drone, and confirm that the host's # run method is called 3 times. Then compare results returned by # the task queue against the mock results. drones = [drone1, drone2, drone3] for drone in drones: drone.queue_call('foo') drone.queue_call('bar') mock_result = utils.CmdResult( stdout=cPickle.dumps(self.mock_return)) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(drone.get_calls()), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) task_queue.execute(drones, wait=False) self.assertTrue(set(task_queue.results.keys()) == set(drones)) results = task_queue.get_results() self.assertTrue(len(task_queue.results) == 0) for drone, result in results.iteritems(): self.assertTrue(result == self.mock_return['results']) # Test execute and get_results drone1.queue_call('foo') mock_result = utils.CmdResult(stdout=cPickle.dumps(self.mock_return)) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(drone1.get_calls()), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) self.assertTrue( task_queue.execute(drones, wait=True)[drone1] == self.mock_return['results']) self.assertTrue(len(task_queue.results) == 0) self.assertTrue(len(task_queue.get_results()) == 0) self.god.check_playback()
def test_trigger_refresh(self): """Test drone manager trigger refresh.""" self.god.stub_with(self._DRONE_CLASS, '_drone_utility_path', self.drone_utility_path) mock_drone = self.create_drone('fakedrone1', 'fakehost1') self.manager._drones[mock_drone.hostname] = mock_drone # Create some fake pidfiles and confirm that a refresh call is # executed on each drone host, with the same pidfile paths. Then # check that each drone gets a key in the returned results dictionary. for i in range(0, 1): pidfile_info = self.create_fake_pidfile_info( 'tag%s' % i, 'name%s' % i) pidfile_paths = [pidfile.path for pidfile in pidfile_info.keys()] refresh_call = drone_utility.call('refresh', pidfile_paths) expected_results = {} mock_result = utils.CmdResult(stdout=cPickle.dumps(self.mock_return)) for drone in self.manager.get_drones(): drone._host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps([refresh_call]), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) expected_results[drone] = self.mock_return['results'] self.manager.trigger_refresh() self.assertTrue( self.manager._refresh_task_queue.get_results() == expected_results) self.god.check_playback()
def test_execute_calls_impl(self): self.god.stub_with(drones._RemoteDrone, "_drone_utility_path", "mock-drone-utility-path") drones.drone_utility.create_host.expect_call("fakehost").and_return(self._mock_host) self._mock_host.is_up.expect_call().and_return(True) mock_calls = ("foo",) mock_result = utils.CmdResult(stdout=cPickle.dumps("mock return")) self._mock_host.run.expect_call( "python mock-drone-utility-path", stdin=cPickle.dumps(mock_calls), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int), ).and_return(mock_result) drone = drones._RemoteDrone("fakehost") self.assertEqual("mock return", drone._execute_calls_impl(mock_calls)) self.god.check_playback()
def test_execute_calls_impl(self): self.god.stub_with(drones._RemoteDrone, '_drone_utility_path', self.drone_utility_path) drones.drone_utility.create_host.expect_call('fakehost').and_return( self._mock_host) self._mock_host.is_up.expect_call().and_return(True) mock_calls = ('foo', ) mock_result = utils.CmdResult(stdout=cPickle.dumps('mock return')) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(mock_calls), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) drone = drones._RemoteDrone('fakehost', timestamp_remote_calls=False) self.assertEqual('mock return', drone._execute_calls_impl(mock_calls)) self.god.check_playback()
def test_execute_queued_calls(self): self.god.stub_with(drones._RemoteDrone, '_drone_utility_path', self.drone_utility_path) drones.drone_utility.create_host.expect_call('fakehost').and_return( self._mock_host) self._mock_host.is_up.expect_call().and_return(True) drone = drones._RemoteDrone('fakehost', timestamp_remote_calls=False) mock_return = {} mock_return['results'] = ['mock return'] mock_return['warnings'] = [] drone.queue_call('foo') mock_result = utils.CmdResult(stdout=cPickle.dumps(mock_return)) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(drone.get_calls()), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) self.assertEqual(mock_return['results'], drone.execute_queued_calls()) self.god.check_playback()
def test_worker(self): """Test the worker method of a ThreadedTaskQueue.""" # Invoke the worker method with a drone that has a queued call and check # that the drones host.run method is invoked for the call, and the # results queue contains the expected results. drone = self.create_remote_drone('fakehostname') task_queue = thread_lib.ThreadedTaskQueue() drone.queue_call('foo') mock_result = utils.CmdResult(stdout=cPickle.dumps(self.mock_return)) self._mock_host.run.expect_call( 'python %s' % self.drone_utility_path, stdin=cPickle.dumps(drone.get_calls()), stdout_tee=None, connect_timeout=mock.is_instance_comparator(int)).and_return( mock_result) task_queue.worker(drone, task_queue.results_queue) result = task_queue.results_queue.get() self.assertTrue(task_queue.results_queue.empty() and result.drone == drone and result.results == self.mock_return['results']) self.god.check_playback()