test_stages: use skylab create-suite/wait-task for hwtests
Cherrypicked to address crbug.com/973654
Use `skylab create-suite` and `skylab wait-task` to trigger skylab
hwtests and collect their results.
Do not land this until
https://chromium-review.googlesource.com/c/infra/infra/+/1593690 is
pushed to prod.
BUG=chromium:957805
TEST=tryjob at https://cros-goldeneye.corp.google.com/chromeos/healthmonitoring/buildDetails?buildbucketId=8914633363238609216
shows both passing and failing suites are handled correctly
Change-Id: I1328b09d717af558379483944f9cb2fe9c3522a0
Reviewed-on: https://chromium-review.googlesource.com/1589146
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Aviv Keshet <akeshet@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
(cherry picked from commit ae4c830cc69e9774361a94bb2b72780132f97ee3)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1658751
Reviewed-by: Bernie Thompson <bhthompson@chromium.org>
Commit-Queue: Aviv Keshet <akeshet@chromium.org>
diff --git a/cbuildbot/commands.py b/cbuildbot/commands.py
index f7bf404..aed14f8 100644
--- a/cbuildbot/commands.py
+++ b/cbuildbot/commands.py
@@ -878,6 +878,7 @@
return os.path.basename(target)
+# TODO(akeshet): Deprecate this undocumented type.
HWTestSuiteResult = collections.namedtuple('HWTestSuiteResult',
['to_raise', 'json_dump_result'])
@@ -1066,74 +1067,90 @@
return HWTestSuiteResult(to_raise, json_dump_result)
-# pylint: disable=docstring-missing-args
-def _GetRunSkylabSuiteArgs(
- build, suite, board,
- model=None,
- pool=None,
- priority=None,
- timeout_mins=None,
- retry=None,
- max_retries=None,
- suite_args=None,
- job_keyvals=None,
- quota_account=None):
- """Get a list of args for run_suite.
-
- TODO (xixuan): Add other features as required, e.g.
- subsystems
- test_args
- skip_duts_check
- suite_min_duts
- minimum_duts
+def _GetSkylabWaitTaskArgs(task_id, timeout_mins=None):
+ """Get arguments for the `skylab wait-task` command.
Args:
- See args of |RunHWTestSuite|.
+ timeout_mins: maximum number of minutes to wait for task completion.
+ task_id: id of the task to wait for.
Returns:
- A list of args for SKYLAB_RUN_SUITE_PATH.
+ List of args for `skylab wait-task`, not including the subcommand itself.
"""
- # HACK(pwang): Delete this once better solution is out.
+ args = ['-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT]
+ if timeout_mins is not None:
+ args += ['-timeout-mins', str(timeout_mins)]
+ args += [task_id]
+ return args
+
+
+def _GetSkylabCreateSuiteArgs(
+ build, suite, board, pool,
+ model=None,
+ priority=None,
+ timeout_mins=None,
+ max_retries=None,
+ job_keyvals=None,
+ quota_account=None):
+ """Get arguments for the `skylab create-suite` command.
+
+ Command will run in -json mode.
+
+ Args:
+ build: string image name to use, e.g. elm-paladin/R99-12345
+ suite: suite name to run
+ board: board name to run suite for
+ pool: pool to run the suite in
+ model: (optional) model name to run suite for
+ priority: (optional) integer priority for the suite. Higher number is a
+ lower priority
+ timeout_mins: (optional) suite timeout
+ max_retries: (optional) max retries allowed across all child tasks
+ job_keyvals: (optional) dictionary of {'key': 'value'} keyvals to be
+ injected into all children of suite.
+ quota_account: (optional) quotascheduler account to use for child tasks
+
+ Returns:
+ A list of args for the `skylab create-suite` subcommand (not including)
+ the subcommand itself.
+ """
+ # TODO(crbug.com/958037): Figure out a way to remove this board-replacement
+ # hack.
board = board.replace('-arcnext', '')
board = board.replace('-arcvm', '')
board = board.replace('-kernelnext', '')
- args = ['--build', build, '--board', board]
+
+ args = ['-image', build, '-board', board]
if model:
- args += ['--model', model]
+ args += ['-model', model]
- args += ['--suite_name', suite]
-
- # Add optional arguments to command, if present.
if pool is not None:
- args += ['--pool', pool]
+ args += ['-pool', pool]
if priority is not None:
- args += ['--priority', str(priority)]
+ args += ['-priority', str(priority)]
if timeout_mins is not None:
- args += ['--timeout_mins', str(timeout_mins)]
-
- if retry is not None:
- args += ['--test_retry']
+ args += ['-timeout-mins', str(timeout_mins)]
if max_retries is not None:
- args += ['--max_retries', str(max_retries)]
-
- if suite_args is not None:
- args += ['--suite_args', repr(suite_args)]
+ args += ['-max-retries', str(max_retries)]
if job_keyvals is not None:
- args += ['--job_keyvals', repr(job_keyvals)]
+ for key, value in job_keyvals.items():
+ args += ['-keyval', '%s:%s' % (key, value)]
if quota_account is not None:
- args += ['--quota_account', quota_account]
+ args += ['-qs-account', quota_account]
- # Use fallback request for every skylab suite.
- args += ['--use_fallback']
+ args += ['-json']
+
+ args += ['-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT]
+
+ args += [suite]
return args
-# pylint: enable=docstring-missing-args
def _remove_seeded_steps(output):
@@ -1179,64 +1196,6 @@
return return_output
-def _SkylabHWTestCreate(cmd, **kwargs):
- """Create HWTest with Skylab.
-
- Args:
- cmd: A list of args for proxied run_suite_skylab command.
- kwargs: args to be passed to RunSwarmingCommand.
-
- Returns:
- A string swarming task id, which is regarded as the suite_id.
- """
- create_cmd = cmd + ['--create_and_return']
- logging.info('Suite creation command: \n%s',
- cros_build_lib.CmdToStr(create_cmd))
- result = swarming_lib.RunSwarmingCommandWithRetries(
- max_retry=_MAX_HWTEST_START_CMD_RETRY,
- is_skylab=True,
- error_check=swarming_lib.SwarmingRetriableErrorCheck,
- cmd=create_cmd, capture_output=True,
- combine_stdout_stderr=True, **kwargs)
- # If the command succeeds, result.task_summary_json will have the right
- # content. So result.GetValue is able to return valid values from its
- # json summary.
- for output in result.GetValue('outputs', []):
- sys.stdout.write(_remove_seeded_steps(output))
- sys.stdout.flush()
- return result.GetValue('run_id')
-
-
-def _SkylabHWTestWait(cmd, suite_id, **kwargs):
- """Wait for Skylab HWTest to finish.
-
- Args:
- cmd: Proxied run_suite command.
- suite_id: The string suite_id to wait for.
- kwargs: args to be passed to RunSwarmingCommand.
- """
- wait_cmd = list(cmd) + ['--suite_id', str(suite_id)]
- logging.info('RunSkylabHWTestSuite will wait for suite %s: %s',
- suite_id, cros_build_lib.CmdToStr(wait_cmd))
- try:
- result = swarming_lib.RunSwarmingCommandWithRetries(
- max_retry=_MAX_HWTEST_START_CMD_RETRY,
- is_skylab=True,
- error_check=swarming_lib.SwarmingRetriableErrorCheck,
- cmd=wait_cmd, capture_output=True, combine_stdout_stderr=True,
- **kwargs)
- except cros_build_lib.RunCommandError as e:
- result = e.result
- raise
- finally:
- # This is required to output buildbot annotations, e.g. 'STEP_LINKS'.
- sys.stdout.write('######## Output for buildbot annotations ######## \n')
- for output in result.GetValue('outputs', []):
- sys.stdout.write(_remove_seeded_steps(output))
- sys.stdout.write('######## END Output for buildbot annotations ######## \n')
- sys.stdout.flush()
-
-
def _InstallSkylabTool():
"""Install skylab tool.
@@ -1361,18 +1320,22 @@
sys.stdout.write('######## END Output for buildbot annotations ######## \n')
sys.stdout.flush()
+
# pylint: disable=docstring-missing-args
@failures_lib.SetFailureType(failures_lib.SuiteTimedOut,
timeout_util.TimeoutError)
def RunSkylabHWTestSuite(
build, suite, board,
model=None,
+ # TODO(akeshet): Make this required argument a positional arg.
pool=None,
- wait_for_results=None,
+ wait_for_results=False,
priority=None,
timeout_mins=None,
+ # TODO(akeshet): Delete this ignored argument.
retry=None,
max_retries=None,
+ # TODO(akeshet): Delete this ignored argument.
suite_args=None,
job_keyvals=None,
quota_account=None):
@@ -1384,36 +1347,76 @@
Returns:
See returns of RunHWTestSuite.
"""
- priority_str = priority
+ if suite_args:
+ logging.warning('Skylab suites do not support suite_args, although they '
+ 'were specified: %s', suite_args)
+
+ if retry:
+ logging.warning('Skylab suites do not support retry arg, although it '
+ 'was specified: %s', retry)
+
+ if not pool:
+ raise ValueError('|pool| argument is required in Skylab, but was not '
+ 'supplied.')
+
if priority:
priority = constants.SKYLAB_HWTEST_PRIORITIES_MAP[str(priority)]
- cmd = [SKYLAB_RUN_SUITE_PATH]
- cmd += _GetRunSkylabSuiteArgs(
- build, suite, board,
+ skylab_tool = _InstallSkylabTool()
+
+ cmd = [skylab_tool, 'create-suite']
+
+ cmd += _GetSkylabCreateSuiteArgs(
+ build, suite, board, pool,
model=model,
- pool=pool,
priority=priority,
timeout_mins=timeout_mins,
- retry=retry,
max_retries=max_retries,
- suite_args=suite_args,
job_keyvals=job_keyvals,
quota_account=quota_account)
- swarming_args = _CreateSwarmingArgs(build, suite, board, priority_str,
- timeout_mins, run_skylab=True)
- try:
- suite_id = _SkylabHWTestCreate(cmd, **swarming_args)
- if wait_for_results:
- _SkylabHWTestWait(cmd, suite_id, **swarming_args)
- return HWTestSuiteResult(None, None)
+ try:
+ output = cros_build_lib.RunCommand(cmd, redirect_stdout=True)
+ report = json.loads(output.output)
+ task_id = report['task_id']
+ task_url = report['task_url']
+
+ logging.info('Launched suite task %s', task_url)
+ logging.PrintBuildbotLink('Suite task: %s' % suite, task_url)
+ if not wait_for_results:
+ return HWTestSuiteResult(None, None)
+
+ wait_cmd = [skylab_tool, 'wait-task'] + _GetSkylabWaitTaskArgs(
+ task_id, timeout_mins=timeout_mins)
+ output = cros_build_lib.RunCommand(wait_cmd, redirect_stdout=True)
+ try:
+ report = json.loads(output.output)
+ except:
+ logging.error('Error when json parsing:\n%s', output.output)
+ raise
+
+ # TODO(crbug.com/958142): Once the schema change in this bug is landed,
+ # remove this if block.
+ if task_id in report:
+ report = report[task_id]
+ logging.info(
+ 'Suite ended in state %s (failure=%s) with output:\n%s',
+ report['task-result']['state'],
+ report['task-result']['failure'],
+ report['stdout'],
+ )
+
+ error = None
+ if report['task-result']['failure']:
+ error = failures_lib.TestFailure('Suite failed.')
+
+ return HWTestSuiteResult(error, None)
+
except cros_build_lib.RunCommandError as e:
result = e.result
to_raise = failures_lib.TestFailure(
'** HWTest failed (code %d) **' % result.returncode)
return HWTestSuiteResult(to_raise, None)
-# pylint: enable=docstring-missing-args
# pylint: disable=docstring-missing-args
diff --git a/cbuildbot/commands_unittest.py b/cbuildbot/commands_unittest.py
index 2d117ca..319410e 100644
--- a/cbuildbot/commands_unittest.py
+++ b/cbuildbot/commands_unittest.py
@@ -8,6 +8,7 @@
from __future__ import print_function
import base64
+import collections
import datetime as dt
import json
import hashlib
@@ -175,196 +176,160 @@
'chromiumos_preflight'])
-# pylint: disable=protected-access
-class SkylabHWLabCommandsTest(cros_test_lib.RunCommandTestCase,
- cros_test_lib.OutputTestCase,
- cros_test_lib.MockTempDirTestCase):
- """Test commands related to HWLab tests with Skylab via swarming proxy."""
- SWARMING_TIMEOUT_DEFAULT = str(
- commands._DEFAULT_HWTEST_TIMEOUT_MINS * 60 +
- commands._SWARMING_ADDITIONAL_TIMEOUT)
- SWARMING_EXPIRATION = str(commands._SWARMING_EXPIRATION)
+class SkylabHWLabCommandsTest(cros_test_lib.RunCommandTestCase):
+ """Test commands that launch Skylab suites."""
- WAIT_OUTPUT = '''
-WAIT OUTPUT: Finished.
-'''
-
- CREATE_OUTPUT = '''
-FAKE OUTPUT. Will be filled in later.
-'''
+ _SKYLAB_TOOL = '/opt/skylab'
def setUp(self):
- self._build = 'test-build'
- self._board = 'test-board'
- self._suite = 'test-suite'
- self.temp_json_path = os.path.join(self.tempdir, 'temp_summary.json')
+ self.PatchObject(commands, '_InstallSkylabTool',
+ return_value=self._SKYLAB_TOOL)
- self.create_cmd = None
- self.wait_cmd = None
+ @staticmethod
+ def _fakeWaitJson(state, failure, stdout=''):
+ """Return a fake json serialized suite report, in wait-task format."""
+ report = {
+ 'task-result': {
+ 'state': state,
+ 'failure': failure,
+ },
+ 'stdout': stdout,
+ }
+ return json.dumps(report)
- def SetCmdResults(self, swarming_cli_cmd='run',
- create_return_code=0,
- wait_return_code=0,
- args=(),
- swarming_timeout_secs=SWARMING_TIMEOUT_DEFAULT,
- swarming_io_timeout_secs=SWARMING_TIMEOUT_DEFAULT,
- swarming_hard_timeout_secs=SWARMING_TIMEOUT_DEFAULT,
- swarming_expiration_secs=SWARMING_EXPIRATION):
- """Set the expected results from the specified commands.
+ @staticmethod
+ def _fakeCreateJson(task_id, task_url):
+ """Return a fake json serialized suite report, in create-suite format."""
+ report = {
+ 'task_id': task_id,
+ 'task_url': task_url,
+ }
+ return json.dumps(report)
- Args:
- swarming_cli_cmd: The swarming client command to kick off.
- create_return_code: Return code from create command.
- wait_return_code: Return code from wait command.
- args: Additional args to pass to create and wait commands.
- swarming_timeout_secs: swarming client timeout.
- swarming_io_timeout_secs: swarming client io timeout.
- swarming_hard_timeout_secs: swarming client hard timeout.
- swarming_expiration_secs: swarming task expiration.
- """
- # Pull out the test priority for the swarming tag.
- priority = None
- priority_flag = '--priority'
- if priority_flag in args:
- priority = args[args.index(priority_flag) + 1]
+ def testCreateSuiteNoPoolRaisesError(self):
+ """Attempting to create a suite without specifying a pool should raise."""
+ build = 'foo-bar/R1234'
+ suite = 'foo-suite'
+ board = 'foo-board'
+ with self.assertRaises(ValueError):
+ commands.RunSkylabHWTestSuite(build, suite, board)
- base_cmd = [swarming_lib._SWARMING_PROXY_CLIENT, swarming_cli_cmd,
- '--swarming', topology.topology.get(
- topology.CHROME_SWARMING_PROXY_HOST_KEY)]
- if swarming_cli_cmd == 'run':
- base_cmd += ['--task-summary-json', self.temp_json_path,
- '--print-status-updates',
- '--timeout', swarming_timeout_secs]
- elif swarming_cli_cmd == 'trigger':
- base_cmd += ['--dump-json', self.temp_json_path]
+ def testCreateSuite(self):
+ """Test that function call args are mapped correctly to commandline args."""
+ build = 'foo-bar/R1234'
+ suite = 'foo-suite'
+ board = 'foo-board'
+ pool = 'foo-pool'
+ # An OrderedDict is used to make the keyval order on the command line
+ # deterministic for testing purposes.
+ keyvals = collections.OrderedDict([('k1', 'v1'), ('k2', 'v2')])
+ priority = constants.HWTEST_DEFAULT_PRIORITY
+ quota_account = 'foo-account'
+ max_retries = 10
+ timeout_mins = 10
- base_cmd += ['--raw-cmd',
- '--task-name', 'test-build-test-suite',
- '--dimension', 'os', 'Ubuntu-14.04',
- '--dimension', 'pool', commands.SKYLAB_SUITE_BOT_POOL,
- '--io-timeout', swarming_io_timeout_secs,
- '--hard-timeout', swarming_hard_timeout_secs,
- '--expiration', swarming_expiration_secs,
- '--tags=skylab:run_suite',
- '--tags=priority:%s' % priority,
- '--tags=build:test-build',
- '--tags=task_name:test-build-test-suite',
- '--tags=luci_project:chromeos',
- '--tags=suite:test-suite',
- '--tags=board:test-board',
- '--auth-service-account-json',
- constants.CHROMEOS_SERVICE_ACCOUNT,
- '--', commands.SKYLAB_RUN_SUITE_PATH,
- '--build', self._build, '--board', self._board,
- '--suite_name', self._suite,
- '--use_fallback']
- args = list(args)
- base_cmd = base_cmd + args
+ task_id = 'foo-task_id'
- self.create_cmd = base_cmd + ['--create_and_return',
- '--passed_mins', '0']
- create_results = iter([
- self.rc.CmdResult(returncode=create_return_code,
- output=self.CREATE_OUTPUT,
- error=''),
- ])
+ create_cmd = [
+ self._SKYLAB_TOOL, 'create-suite',
+ '-image', build,
+ '-board', board,
+ '-pool', pool,
+ '-priority', '140',
+ '-timeout-mins', str(timeout_mins),
+ '-max-retries', str(max_retries),
+ '-keyval', 'k1:v1',
+ '-keyval', 'k2:v2',
+ '-qs-account', quota_account,
+ '-json',
+ '-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT,
+ suite
+ ]
+
self.rc.AddCmdResult(
- self.create_cmd,
- side_effect=lambda *args, **kwargs: create_results.next(),
- )
+ create_cmd, output=self._fakeCreateJson(task_id, 'foo://foo'))
- self.wait_cmd = base_cmd + ['--suite_id', 'fake_parent_id',
- '--passed_mins', '0']
- wait_results = iter([
- self.rc.CmdResult(returncode=wait_return_code,
- output=self.WAIT_OUTPUT,
- error=''),
- ])
+ result = commands.RunSkylabHWTestSuite(
+ build, suite, board, pool=pool, job_keyvals=keyvals, priority=priority,
+ quota_account=quota_account, max_retries=max_retries,
+ timeout_mins=timeout_mins)
+
+ self.assertTrue(isinstance(result, commands.HWTestSuiteResult))
+ self.assertEqual(result.to_raise, None)
+ self.assertEqual(result.json_dump_result, None)
+
+ self.rc.assertCommandCalled(create_cmd, redirect_stdout=True)
+ self.assertEqual(self.rc.call_count, 1)
+
+ def testCreateSuiteAndWait(self):
+ """Test that suite can be created and then waited for."""
+ build = 'foo-bar/R1234'
+ suite = 'foo-suite'
+ board = 'foo-board'
+ pool = 'foo-pool'
+
+ task_id = 'foo-task_id'
+
+ create_cmd = [
+ self._SKYLAB_TOOL, 'create-suite',
+ '-image', build,
+ '-board', board,
+ '-pool', pool,
+ '-json',
+ '-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT,
+ suite,
+ ]
+ wait_cmd = [
+ self._SKYLAB_TOOL, 'wait-task',
+ '-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT,
+ task_id
+ ]
self.rc.AddCmdResult(
- self.wait_cmd,
- side_effect=lambda *args, **kwargs: wait_results.next(),
- )
+ create_cmd, output=self._fakeCreateJson(task_id, 'foo://foo'))
+ self.rc.AddCmdResult(
+ wait_cmd, output=self._fakeWaitJson('COMPLETED', False))
- def PatchJson(self, task_outputs):
- """Mock out the code that loads from json.
+ result = commands.RunSkylabHWTestSuite(
+ build, suite, board, pool=pool, wait_for_results=True)
+ self.assertEqual(result.to_raise, None)
+ self.assertEqual(result.json_dump_result, None)
- Args:
- task_outputs: See explaination in PatchJson of HWLabCommandsTest.
- """
- orig_func = commands._CreateSwarmingArgs
+ self.rc.assertCommandCalled(create_cmd, redirect_stdout=True)
+ self.rc.assertCommandCalled(wait_cmd, redirect_stdout=True)
+ self.assertEqual(self.rc.call_count, 2)
- def replacement(*args, **kargs):
- swarming_args = orig_func(*args, **kargs)
- swarming_args['temp_json_path'] = self.temp_json_path
- return swarming_args
+ def testSuiteFailure(self):
+ """Test that nonzero return code is reported as suite failure."""
+ build = 'foo-bar/R1234'
+ suite = 'foo-suite'
+ board = 'foo-board'
+ pool = 'foo-pool'
- self.PatchObject(commands, '_CreateSwarmingArgs', side_effect=replacement)
+ task_id = 'foo-task_id'
- if task_outputs:
- return_values = []
- for s in task_outputs:
- j = {'shards':[{'name': 'fake_name', 'bot_id': 'chromeos-server990',
- 'created_ts': '2015-06-12 12:00:00',
- 'internal_failure': s[1],
- 'state': s[2],
- 'outputs': [s[0]],
- 'run_id': s[3]}]}
- return_values.append(j)
- return_values_iter = iter(return_values)
- self.PatchObject(swarming_lib.SwarmingCommandResult, 'LoadJsonSummary',
- side_effect=lambda json_file: return_values_iter.next())
- else:
- self.PatchObject(swarming_lib.SwarmingCommandResult, 'LoadJsonSummary',
- return_value=None)
+ create_cmd = [
+ self._SKYLAB_TOOL, 'create-suite',
+ '-image', build,
+ '-board', board,
+ '-pool', pool,
+ '-json',
+ '-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT,
+ suite,
+ ]
+ wait_cmd = [
+ self._SKYLAB_TOOL, 'wait-task',
+ '-service-account-json', constants.CHROMEOS_SERVICE_ACCOUNT,
+ task_id,
+ ]
+ self.rc.AddCmdResult(
+ create_cmd, output=self._fakeCreateJson(task_id, 'foo://foo'))
+ self.rc.AddCmdResult(wait_cmd, output=self._fakeWaitJson('COMPLETED', True))
- def RunSkylabHWTestSuite(self, *args, **kwargs):
- """Run the hardware test suite, printing logs to stdout."""
- with cros_test_lib.LoggingCapturer() as logs:
- try:
- cmd_result = commands.RunSkylabHWTestSuite(self._build, self._suite,
- self._board, *args, **kwargs)
- return cmd_result
- finally:
- print(logs.messages)
-
- def testRemoveSeededSteps(self):
- output = ('2018-xx-xx info | kicked off a test\n'
- '@@@SEED_STEP Scheduled Tests@@@\n'
- '@@@STEP_CURSOR Scheduled Tests@@@\n'
- '@@@STEP_STARTED@@@\n'
- '@@@STEP_LINK@[Test-logs]: test 1'
- '@https://chrome-swarming.appspot.com/user/task/123@@@\n'
- '@@@STEP_CLOSED@@@\n'
- '@@@SEED_STEP Scheduled Tests 2@@@\n'
- '@@@STEP_CURSOR Scheduled Tests 2@@@\n'
- '@@@STEP_STARTED@@@\n'
- '@@@STEP_LINK@[Test-logs]: test 2'
- '@https://chrome-swarming.appspot.com/user/task/456@@@\n'
- '@@@STEP_CLOSED@@@\n'
- '@@@STEP_LINK@[Test-logs]: test 3'
- '@https://chrome-swarming.appspot.com/user/task/789@@@\n')
- expected_output = (
- '2018-xx-xx info | kicked off a test\n'
- '@@@STEP_LINK@[Test-logs]: test 3'
- '@https://chrome-swarming.appspot.com/user/task/789@@@\n')
- self.assertEqual(commands._remove_seeded_steps(output), expected_output)
-
- def testRunSkylabHWTestSuiteWithWait(self):
- """Test RunSkylabHWTestSuite with waiting for results."""
- self.SetCmdResults(swarming_cli_cmd='run')
- # When run without optional arguments, wait and dump_json cmd will not run.
- self.PatchJson([(self.CREATE_OUTPUT, False, None, 'fake_parent_id'),
- (self.WAIT_OUTPUT, False, None, 'fake_wait_id')])
-
- with self.OutputCapturer() as output:
- cmd_result = self.RunSkylabHWTestSuite(wait_for_results=True)
- self.assertEqual(cmd_result, (None, None))
- self.assertCommandCalled(self.create_cmd, capture_output=True,
- combine_stdout_stderr=True, env=mock.ANY)
- self.assertCommandCalled(self.wait_cmd, capture_output=True,
- combine_stdout_stderr=True, env=mock.ANY)
- self.assertIn(self.CREATE_OUTPUT, '\n'.join(output.GetStdoutLines()))
- self.assertIn(self.WAIT_OUTPUT, '\n'.join(output.GetStdoutLines()))
+ result = commands.RunSkylabHWTestSuite(
+ build, suite, board, pool=pool, wait_for_results=True)
+ error = result.to_raise
+ self.assertTrue(isinstance(error, failures_lib.TestFailure))
+ self.assertTrue('Suite failed' in error.message)
class HWLabCommandsTest(cros_test_lib.RunCommandTestCase,