def testHandleFail(self): """Tests that _HandleFail copies necessary files for repro. In case of a test failure, _HandleFail should copy necessary files to a debug location, and delete existing GCS/GCE resources. And because of the latter, a final call to Cleanup will not make an additional attempt to delete those resources. """ worker = GCEAUWorker(self.options, self.test_results_root, project=self.PROJECT, zone=self.ZONE, network=self.NETWORK, gcs_bucket=self.BUCKET, json_key_file=self.json_key_file) worker.instances = dict(smoke='fake-instance') worker.image = 'fake-image' worker.tarball_local = self.image_path worker.tarball_remote = 'gs://fake-tarball' worker.tests = [dict(name='smoke', flags=dict())] # Fake general commands. for cmd in ['CopyInto', 'DoCommand']: self.PatchObject(worker.gscontext, cmd, autospec=True) self.PatchObject(cros_build_lib, 'RunCommand', autospec=True) self.PatchObject(path_util, 'ToChrootPath', autospec=True, return_value='x/y/z') # Make _RunTest return 0% of pass rate. self.PatchObject(worker, '_RunTest', autospec=True, return_value=(0, None, None)) # Fake resource existance. remote_instance = 'fake-remote-instance' self.PatchObject( worker.gce_context, 'InstanceExists', autospec=True, side_effect=lambda instance: remote_instance is not None) # Fake resource deletors. self.PatchObject(worker.gce_context, 'DeleteImage', autospec=True) # Make DeleteInstance delete the remote resource. def _OverrideDeleteInstance(_): remote_instance = None self.PatchObject(worker.gce_context, 'DeleteInstance', autospec=True, side_effect=_OverrideDeleteInstance) # VerifyImage should fail and _HandleFail should be called. worker.VerifyImage(None) # Assert that required files are retained at debug location. self.assertExists( os.path.join(self.test_results_failed, self.GCE_TARBALL)) self.assertExists( os.path.join(self.test_results_failed, os.path.basename(self.options.ssh_private_key))) # CleanUp will not attempt to delete resources because they should have been # deleted by _HandleFail. worker.instances = dict(smoke='fake-instance') worker.CleanUp() # Assert that one and only one attempt was made to delete existing # instances. worker.gce_context.DeleteInstance.assert_called_once_with(mock.ANY)
def testVerifyImage(self): """Verifies that VerifyImage runs required tests on correct instances.""" worker = GCEAUWorker(self.options, self.test_results_root, project=self.PROJECT, zone=self.ZONE, network=self.NETWORK, gcs_bucket=self.BUCKET, json_key_file=self.json_key_file) # Fake tests and instances. worker.tests = [ dict(name='suite:suite1', flags=dict(foo='bar')), dict(name='suite:suite2', flags=dict(bar='foo')), dict(name='foo_test', flags=dict()), ] worker.instances = { 'suite:suite1': 'instance_1', 'suite:suite2': 'instance_2', 'foo_test': 'instance_3', } expected_tests_run = [ dict(remote='1.1.1.1', test='suite:suite1'), dict(remote='2.2.2.2', test='suite:suite2'), dict(remote='3.3.3.3', test='foo_test'), ] actual_tests_run = [] def _OverrideGetInstanceIP(instance, *_args, **_kwargs): if instance == 'instance_1': return '1.1.1.1' elif instance == 'instance_2': return '2.2.2.2' else: return '3.3.3.3' def _OverrideRunCommand(cmd, *_args, **_kwargs): """A mock of cros_build_lib.RunCommand that injects arguments.""" # In this test setup, |test| and |remote| should be the third and fourth # last argument respectively. test = cmd[-3] remote = cmd[-4] actual_tests_run.append(dict(remote=remote, test=test)) return cros_build_lib.CommandResult() def _OverrideRunParallelSteps(steps, *_args, **_kwargs): """Run steps sequentially.""" return_values = [] for step in steps: ret = step() return_values.append(ret) return return_values self.PatchObject(worker.gce_context, 'CreateInstance', autospec=True) self.PatchObject(path_util, 'ToChrootPath', autospec=True, return_value='x/y/z') self.PatchObject(worker.gce_context, 'GetInstanceIP', autospec=True, side_effect=_OverrideGetInstanceIP) self.PatchObject(cros_build_lib, 'RunCommand', autospec=True, side_effect=_OverrideRunCommand) self.PatchObject(AUWorker, 'ParseGeneratedTestOutput', autospec=True, return_value=100) self.PatchObject(parallel, 'RunParallelSteps', autospec=True, side_effect=_OverrideRunParallelSteps) # VerifyImage should run all expected tests. worker.VerifyImage(None) # Assert that expected and only expected tests are run. self.assertEqual(len(expected_tests_run), len(actual_tests_run)) for test in expected_tests_run: self.assertIn(test, actual_tests_run)