Add per_test_timeout_secs spec field, respect it for QEMU
The -i flag was added to runtests in change
Ic30b40881fc9561764f38cd574072df09a686f5f.
Testrunner doesn't yet have an equivalent flag, so for now we only
apply this flag to QEMU.
Bug: 39351
Change-Id: Ie138267827ae76b2b891379e0cf91f86279235a4
diff --git a/recipe_modules/testing/api.py b/recipe_modules/testing/api.py
index 732cb9b..763cca6 100644
--- a/recipe_modules/testing/api.py
+++ b/recipe_modules/testing/api.py
@@ -544,7 +544,7 @@
def __init__(self, api, shards, build_artifacts, debug_symbol_gcs_bucket,
pool, swarming_output_dir, timeout_secs,
swarming_expiration_timeout_secs, swarming_io_timeout_secs,
- max_attempts, collect_timeout):
+ max_attempts, collect_timeout, per_test_timeout_secs):
self._api = api
self._pool = pool
self._original_build_artifacts = build_artifacts
@@ -556,6 +556,7 @@
self._swarming_io_timeout_secs = swarming_io_timeout_secs
self._max_attempts = max_attempts
self._collect_timeout = collect_timeout
+ self._per_test_timeout_secs = per_test_timeout_secs
self._uses_legacy_qemu = {
shard.name: (not self._api.experimental.ssh_into_qemu
and self._api.emu.is_emulator_type(shard.device_type))
@@ -618,14 +619,15 @@
test_list_path = self._create_test_list(shard)
runtests_file_bootfs_path = 'infra/shard.run'
runcmds_path = self._api.path['cleanup'].join('runcmds-%s' % shard.name)
+ runtests_cmd_parts = [
+ 'runtests', '-o', self._api.testing.results_dir_on_target, '-f',
+ '/boot/%s' % runtests_file_bootfs_path
+ ]
+ if self._per_test_timeout_secs:
+ runtests_cmd_parts.extend(['-i', '%d' % self._per_test_timeout_secs])
self._api.testing._create_runcmds_script(
device_type=shard.device_type,
- test_cmds=[
- 'runtests -o %s -f /boot/%s' % (
- self._api.testing.results_dir_on_target,
- runtests_file_bootfs_path,
- )
- ],
+ test_cmds=[' '.join(runtests_cmd_parts)],
output_path=runcmds_path,
)
@@ -732,6 +734,7 @@
else:
dimensions.update(shard.dimensions)
+ # TODO(fxb/39351): Respect per_test_timeout_secs
if shard.targets_fuchsia:
botanist_cmd = [
'./botanist',
@@ -885,8 +888,15 @@
spec.test.swarming_expiration_timeout_secs),
max_attempts=spec.test.max_attempts,
collect_timeout_secs=spec.test.collect_timeout_secs,
+ per_test_timeout_secs=spec.test.per_test_timeout_secs,
)
else:
+ runtests_cmd_parts = [
+ 'runtests', '-o', self.results_dir_on_target, spec.test.runtests_args
+ ]
+ if spec.test.per_test_timeout_secs:
+ runtests_cmd_parts.extend(
+ ['-i', '%d' % spec.test.per_test_timeout_secs])
all_results = [
self.deprecated_test(
build_artifacts=build_artifacts,
@@ -898,12 +908,7 @@
swarming_expiration_timeout_secs=(
spec.test.swarming_expiration_timeout_secs),
pave=spec.test.pave,
- test_cmds=[
- 'runtests -o %s %s' % (
- self.results_dir_on_target,
- spec.test.runtests_args,
- ),
- ],
+ test_cmds=[' '.join(runtests_cmd_parts)],
device_type=spec.test.device_type,
requires_secrets=spec.test.requires_secrets,
)
@@ -1623,6 +1628,7 @@
swarming_io_timeout_secs,
max_attempts,
collect_timeout_secs,
+ per_test_timeout_secs,
timeout_secs=40 * 60,
):
"""Tests a Fuchsia build by sharding.
@@ -1638,6 +1644,8 @@
max_attempts (int): Maximum number of attempts before marking a shard
as failed.
collect_timeout_secs (int): Amount of time to wait for tasks to complete.
+ per_test_timeout_secs (int): Any test that executes for longer than this
+ will be considered failed.
timeout_secs (int): The amount of seconds to wait for the tests to execute
before giving up.
@@ -1668,6 +1676,7 @@
swarming_io_timeout_secs=swarming_io_timeout_secs,
max_attempts=max_attempts,
collect_timeout=collect_timeout,
+ per_test_timeout_secs=per_test_timeout_secs,
)
return self._test_runner.run_tests()
diff --git a/recipe_modules/testing/examples/full.expected/isolated_tests_x64_with_secrets.json b/recipe_modules/testing/examples/full.expected/isolated_tests_x64_with_secrets.json
index e8accd8..5e68baa 100644
--- a/recipe_modules/testing/examples/full.expected/isolated_tests_x64_with_secrets.json
+++ b/recipe_modules/testing/examples/full.expected/isolated_tests_x64_with_secrets.json
@@ -254,7 +254,7 @@
"--json-output",
"/path/to/tmp/json",
"copy",
- "mkdir /tmp/infra-test-output\nwaitfor class=block topo=/dev/sys/pci/00:06.0/virtio-block/block timeout=60000\nmount /dev/sys/pci/00:06.0/virtio-block/block /tmp/infra-test-output\nruntests -o /tmp/infra-test-output \numount /tmp/infra-test-output\ndm poweroff",
+ "mkdir /tmp/infra-test-output\nwaitfor class=block topo=/dev/sys/pci/00:06.0/virtio-block/block timeout=60000\nmount /dev/sys/pci/00:06.0/virtio-block/block /tmp/infra-test-output\nruntests -o /tmp/infra-test-output -i 1\numount /tmp/infra-test-output\ndm poweroff",
"[CLEANUP]/runcmds"
],
"infra_step": true,
@@ -263,7 +263,7 @@
"@@@STEP_LOG_LINE@runcmds@mkdir /tmp/infra-test-output@@@",
"@@@STEP_LOG_LINE@runcmds@waitfor class=block topo=/dev/sys/pci/00:06.0/virtio-block/block timeout=60000@@@",
"@@@STEP_LOG_LINE@runcmds@mount /dev/sys/pci/00:06.0/virtio-block/block /tmp/infra-test-output@@@",
- "@@@STEP_LOG_LINE@runcmds@runtests -o /tmp/infra-test-output @@@",
+ "@@@STEP_LOG_LINE@runcmds@runtests -o /tmp/infra-test-output -i 1@@@",
"@@@STEP_LOG_LINE@runcmds@umount /tmp/infra-test-output@@@",
"@@@STEP_LOG_LINE@runcmds@dm poweroff@@@",
"@@@STEP_LOG_END@runcmds@@@"
diff --git a/recipe_modules/testing/examples/full.expected/test_in_shards_single_attempt.json b/recipe_modules/testing/examples/full.expected/test_in_shards_single_attempt.json
index 755c962..cfb8d4d 100644
--- a/recipe_modules/testing/examples/full.expected/test_in_shards_single_attempt.json
+++ b/recipe_modules/testing/examples/full.expected/test_in_shards_single_attempt.json
@@ -312,7 +312,7 @@
"--json-output",
"/path/to/tmp/json",
"copy",
- "mkdir /tmp/infra-test-output\nwaitfor class=block topo=/dev/sys/pci/00:06.0/virtio-block/block timeout=60000\nmount /dev/sys/pci/00:06.0/virtio-block/block /tmp/infra-test-output\nruntests -o /tmp/infra-test-output -f /boot/infra/shard.run\numount /tmp/infra-test-output\ndm poweroff",
+ "mkdir /tmp/infra-test-output\nwaitfor class=block topo=/dev/sys/pci/00:06.0/virtio-block/block timeout=60000\nmount /dev/sys/pci/00:06.0/virtio-block/block /tmp/infra-test-output\nruntests -o /tmp/infra-test-output -f /boot/infra/shard.run -i 1\numount /tmp/infra-test-output\ndm poweroff",
"[CLEANUP]/runcmds-multiplied:fuchsia-0000"
],
"infra_step": true,
@@ -322,7 +322,7 @@
"@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@mkdir /tmp/infra-test-output@@@",
"@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@waitfor class=block topo=/dev/sys/pci/00:06.0/virtio-block/block timeout=60000@@@",
"@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@mount /dev/sys/pci/00:06.0/virtio-block/block /tmp/infra-test-output@@@",
- "@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@runtests -o /tmp/infra-test-output -f /boot/infra/shard.run@@@",
+ "@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@runtests -o /tmp/infra-test-output -f /boot/infra/shard.run -i 1@@@",
"@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@umount /tmp/infra-test-output@@@",
"@@@STEP_LOG_LINE@runcmds-multiplied:fuchsia-0000@dm poweroff@@@",
"@@@STEP_LOG_END@runcmds-multiplied:fuchsia-0000@@@"
diff --git a/recipe_modules/testing/examples/full.py b/recipe_modules/testing/examples/full.py
index 263ec0c..3f5b339 100644
--- a/recipe_modules/testing/examples/full.py
+++ b/recipe_modules/testing/examples/full.py
@@ -74,12 +74,18 @@
kind=bool,
help='Whether to call the deprecated_test_async method',
default=False),
+ 'per_test_timeout_secs':
+ Property(
+ kind=int,
+ help='Passed through to spec field Fuchsia.Test.per_test_timeout_secs',
+ default=0),
}
def RunSteps(api, gcs_bucket, build_artifact_hash, device_type, pave,
requires_secrets, test_in_shards, upload_to_catapult,
- collect_timeout_secs, debug_symbol_gcs_bucket, test_async):
+ collect_timeout_secs, debug_symbol_gcs_bucket, test_async,
+ per_test_timeout_secs):
upload_results = bool(gcs_bucket)
build_artifacts = api.build.BuildArtifacts.download(api, build_artifact_hash)
build_artifacts.isolate(api)
@@ -91,7 +97,8 @@
requires_secrets=requires_secrets,
test_in_shards=test_in_shards,
upload_to_catapult=upload_to_catapult,
- collect_timeout_secs=collect_timeout_secs)
+ collect_timeout_secs=collect_timeout_secs,
+ per_test_timeout_secs=per_test_timeout_secs)
spec = Fuchsia(
test=test_spec,
debug_symbol_gcs_bucket=debug_symbol_gcs_bucket,
@@ -147,6 +154,7 @@
'isolated_tests_x64_with_secrets',
properties={
'requires_secrets': True,
+ 'per_test_timeout_secs': 1,
},
)
yield api.testing.test(
@@ -638,6 +646,7 @@
clear_default_steps=True,
properties={
'test_in_shards': True,
+ 'per_test_timeout_secs': 1,
},
steps=[
api.testing.shards_step_data(shards=[
diff --git a/recipe_proto/infra/fuchsia.proto b/recipe_proto/infra/fuchsia.proto
index 1bd562c..49b9e6b 100644
--- a/recipe_proto/infra/fuchsia.proto
+++ b/recipe_proto/infra/fuchsia.proto
@@ -192,5 +192,9 @@
// A default service account to attach to test tasks; used for shards that do
// not specify one themselves.
string default_service_account = 15;
+
+ // Any test that executes for longer than this will be considered failed.
+ // 0 means no timeout.
+ uint32 per_test_timeout_secs = 16;
}
}