def setUp(self): super(TestCase, self).setUp() self._tmpdir = tempfile.mkdtemp(prefix='swarming_main') self._zip_file = os.path.join(self._tmpdir, 'swarming_bot.zip') code, _ = fake_swarming.gen_zip(self.url) with open(self._zip_file, 'wb') as f: f.write(code)
def test_signal(self): # Tests when task_runner gets a SIGTERM. os.mkdir(os.path.join(self.root_dir, 'work')) signal_file = os.path.join(self.root_dir, 'work', 'signal') open(signal_file, 'wb').close() manifest = get_manifest( script='import os,time;os.remove(%r);time.sleep(60)' % signal_file, hard_timeout=60., io_timeout=60.) task_in_file = os.path.join(self.root_dir, 'task_runner_in.json') task_result_file = os.path.join(self.root_dir, 'task_runner_out.json') with open(task_in_file, 'wb') as f: json.dump(manifest, f) bot = os.path.join(self.root_dir, 'swarming_bot.1.zip') code, _ = fake_swarming.gen_zip(self._server.url) with open(bot, 'wb') as f: f.write(code) cmd = [ sys.executable, bot, 'task_runner', '--swarming-server', self._server.url, '--in-file', task_in_file, '--out-file', task_result_file, '--cost-usd-hour', '1', # Include the time taken to poll the task in the cost. '--start', str(time.time()), ] logging.info('%s', cmd) proc = subprocess42.Popen(cmd, cwd=self.root_dir, detached=True) # Wait for the child process to be alive. while os.path.isfile(signal_file): time.sleep(0.01) # Send SIGTERM to task_runner itself. Ensure the right thing happen. # Note that on Windows, this is actually sending a SIGBREAK since there's no # such thing as SIGTERM. proc.send_signal(signal.SIGTERM) proc.wait() task_runner_log = os.path.join(self.root_dir, 'logs', 'task_runner.log') with open(task_runner_log, 'rb') as f: logging.info('task_runner.log:\n---\n%s---', f.read()) expected = { u'exit_code': 0, u'hard_timeout': False, u'io_timeout': False, u'must_signal_internal_failure': None, u'version': task_runner.OUT_VERSION, } self.assertEqual([], self._server.get_events()) tasks = self._server.get_tasks() for task in tasks.itervalues(): for event in task: event.pop('cost_usd') event.pop('duration', None) expected = { '23': [ { u'id': u'localhost', u'task_id': 23, }, { u'exit_code': 1 if sys.platform == 'win32' else -signal.SIGTERM, u'hard_timeout': False, u'id': u'localhost', u'io_timeout': False, u'task_id': 23, }, ], } self.assertEqual(expected, tasks) expected = { 'swarming_bot.1.zip', '092b5bd4562f579711823f61e311de37247c853a-cacert.pem', 'work', 'logs', # TODO(maruel): Move inside work. 'task_runner_in.json', 'task_runner_out.json', } self.assertEqual(expected, set(os.listdir(self.root_dir))) expected = { u'exit_code': 1 if sys.platform == 'win32' else -signal.SIGTERM, u'hard_timeout': False, u'io_timeout': False, u'must_signal_internal_failure': u'task_runner received signal %d' % task_runner.SIG_BREAK_OR_TERM, u'version': 3, } with open(task_result_file, 'rb') as f: self.assertEqual(expected, json.load(f)) self.assertEqual(0, proc.returncode)
def test_signal(self): # Tests when task_runner gets a SIGTERM. # https://msdn.microsoft.com/library/cc704588.aspx # STATUS_ENTRYPOINT_NOT_FOUND=0xc0000139. Python sees it as -1073741510. # TODO(sethkoehler): Reenable this line when we correctly pass exit_code # on failure (see TODO in task_runner.py). # exit_code = -1073741510 if sys.platform == 'win32' else -signal.SIGTERM os.mkdir(os.path.join(self.root_dir, 'w')) signal_file = os.path.join(self.root_dir, 'w', 'signal') open(signal_file, 'wb').close() # As done by bot_main.py. manifest = get_manifest( script='import os,time;os.remove(%r);time.sleep(60)' % signal_file, hard_timeout=60., io_timeout=60.) task_in_file = os.path.join(self.root_dir, 'w', 'task_runner_in.json') task_result_file = os.path.join(self.root_dir, 'w', 'task_runner_out.json') with open(task_in_file, 'wb') as f: json.dump(manifest, f) bot = os.path.join(self.root_dir, 'swarming_bot.1.zip') code, _ = fake_swarming.gen_zip(self._server.url) with open(bot, 'wb') as f: f.write(code) cmd = [ sys.executable, bot, 'task_runner', '--swarming-server', self._server.url, '--in-file', task_in_file, '--out-file', task_result_file, '--cost-usd-hour', '1', # Include the time taken to poll the task in the cost. '--start', str(time.time()), '--', '--cache', 'isolated_cache_party', ] logging.info('%s', cmd) proc = subprocess42.Popen(cmd, cwd=self.root_dir, detached=True) # Wait for the child process to be alive. while os.path.isfile(signal_file): time.sleep(0.01) # Send SIGTERM to task_runner itself. Ensure the right thing happen. # Note that on Windows, this is actually sending a SIGBREAK since there's no # such thing as SIGTERM. proc.send_signal(signal.SIGTERM) proc.wait() task_runner_log = os.path.join(self.root_dir, 'logs', 'task_runner.log') with open(task_runner_log, 'rb') as f: logging.info('task_runner.log:\n---\n%s---', f.read()) self.assertEqual([], self._server.get_events()) tasks = self._server.get_tasks() for task in tasks.itervalues(): for event in task: event.pop('cost_usd') event.pop('duration', None) event.pop('bot_overhead', None) # TODO(sethkoehler): Reinsert u'exit_code': exit_code in expected results # when we correctly pass exit_code on failure (see TODO in task_runner.py). expected = { '23': [ { u'id': u'localhost', u'task_id': 23, }, { u'hard_timeout': False, u'id': u'localhost', u'io_timeout': False, u'task_id': 23, }, ], } self.assertEqual(expected, tasks) expected = { 'swarming_bot.1.zip', 'e2bfe61c8f0dc89e72a854f4afb14f4b662ea6301fc5652ebe03f80fa2b06263-cacert.' 'pem', 'w', 'isolated_cache_party', 'logs', 'c', } self.assertEqual(expected, set(os.listdir(self.root_dir))) # TODO(sethkoehler): Set exit_code to 'exit_code' variable rather than None # when we correctly pass exit_code on failure (see TODO in task_runner.py). expected = { u'exit_code': None, u'hard_timeout': False, u'io_timeout': False, u'must_signal_internal_failure': u'', u'version': 3, } with open(task_result_file, 'rb') as f: self.assertEqual(expected, json.load(f)) self.assertEqual(0, proc.returncode) # Also verify the correct error was posted. errors = self._server.get_errors() expected = { '23': [{ u'message': u'task_runner received signal 15', u'id': u'localhost', u'task_id': 23, }], } self.assertEqual(expected, errors)