Commit 1182eb18 authored by Yegor's avatar Yegor Committed by GitHub

add "flaky" and "timeout_in_minutes" devicelab task options (#9168)

parent 93126a85
...@@ -32,6 +32,8 @@ class ManifestTask { ...@@ -32,6 +32,8 @@ class ManifestTask {
@required this.description, @required this.description,
@required this.stage, @required this.stage,
@required this.requiredAgentCapabilities, @required this.requiredAgentCapabilities,
@required this.isFlaky,
@required this.timeoutInMinutes,
}) { }) {
final String taskName = 'task "$name"'; final String taskName = 'task "$name"';
_checkIsNotBlank(name, 'Task name', taskName); _checkIsNotBlank(name, 'Task name', taskName);
...@@ -51,6 +53,14 @@ class ManifestTask { ...@@ -51,6 +53,14 @@ class ManifestTask {
/// Capabilities required of the build agent to be able to perform this task. /// Capabilities required of the build agent to be able to perform this task.
final List<String> requiredAgentCapabilities; final List<String> requiredAgentCapabilities;
/// Whether this test is flaky.
///
/// Flaky tests are not considered when deciding if the build is broken.
final bool isFlaky;
/// An optional custom timeout specified in minutes.
final int timeoutInMinutes;
} }
/// Thrown when the manifest YAML is not valid. /// Thrown when the manifest YAML is not valid.
...@@ -72,7 +82,8 @@ Manifest _validateAndParseManifest(Map<String, dynamic> manifestYaml) { ...@@ -72,7 +82,8 @@ Manifest _validateAndParseManifest(Map<String, dynamic> manifestYaml) {
List<ManifestTask> _validateAndParseTasks(dynamic tasksYaml) { List<ManifestTask> _validateAndParseTasks(dynamic tasksYaml) {
_checkType(tasksYaml is Map, tasksYaml, 'Value of "tasks"', 'dictionary'); _checkType(tasksYaml is Map, tasksYaml, 'Value of "tasks"', 'dictionary');
return tasksYaml.keys.map((dynamic taskName) => _validateAndParseTask(taskName, tasksYaml[taskName])).toList(); final List<String> sortedKeys = tasksYaml.keys.toList()..sort();
return sortedKeys.map((dynamic taskName) => _validateAndParseTask(taskName, tasksYaml[taskName])).toList();
} }
ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) { ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
...@@ -82,14 +93,28 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) { ...@@ -82,14 +93,28 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
'description', 'description',
'stage', 'stage',
'required_agent_capabilities', 'required_agent_capabilities',
'flaky',
'timeout_in_minutes',
]); ]);
final dynamic isFlaky = taskYaml['flaky'];
if (isFlaky != null) {
_checkType(isFlaky is bool, isFlaky, 'flaky', 'boolean');
}
final dynamic timeoutInMinutes = taskYaml['timeout_in_minutes'];
if (timeoutInMinutes != null) {
_checkType(timeoutInMinutes is int, timeoutInMinutes, 'timeout_in_minutes', 'integer');
}
final List<String> capabilities = _validateAndParseCapabilities(taskName, taskYaml['required_agent_capabilities']); final List<String> capabilities = _validateAndParseCapabilities(taskName, taskYaml['required_agent_capabilities']);
return new ManifestTask._( return new ManifestTask._(
name: taskName, name: taskName,
description: taskYaml['description'], description: taskYaml['description'],
stage: taskYaml['stage'], stage: taskYaml['stage'],
requiredAgentCapabilities: capabilities, requiredAgentCapabilities: capabilities,
isFlaky: isFlaky ?? false,
timeoutInMinutes: timeoutInMinutes,
); );
} }
......
...@@ -34,6 +34,22 @@ void main() { ...@@ -34,6 +34,22 @@ void main() {
}); });
} }
test('accepts task with minimum amount of configuration', () {
final Manifest manifest = loadTaskManifest('''
tasks:
minimum_configuration_task:
description: Description is mandatory.
stage: stage_is_mandatory_too
required_agent_capabilities: ["so-is-capability"]
''');
expect(manifest.tasks.single.description, 'Description is mandatory.');
expect(manifest.tasks.single.stage, 'stage_is_mandatory_too');
expect(manifest.tasks.single.requiredAgentCapabilities, <String>['so-is-capability']);
expect(manifest.tasks.single.isFlaky, false);
expect(manifest.tasks.single.timeoutInMinutes, null);
});
testManifestError( testManifestError(
'invalid top-level type', 'invalid top-level type',
'Manifest must be a dictionary but was YamlScalar: null', 'Manifest must be a dictionary but was YamlScalar: null',
...@@ -79,7 +95,7 @@ void main() { ...@@ -79,7 +95,7 @@ void main() {
testManifestError( testManifestError(
'invalid task property', 'invalid task property',
'Unrecognized property "bar" in Value of task "foo". Allowed properties: description, stage, required_agent_capabilities', 'Unrecognized property "bar" in Value of task "foo". Allowed properties: description, stage, required_agent_capabilities, flaky, timeout_in_minutes',
''' '''
tasks: tasks:
foo: foo:
...@@ -129,7 +145,7 @@ void main() { ...@@ -129,7 +145,7 @@ void main() {
); );
testManifestError( testManifestError(
'missing stage', 'missing required_agent_capabilities',
'requiredAgentCapabilities must not be empty in task "foo".', 'requiredAgentCapabilities must not be empty in task "foo".',
''' '''
tasks: tasks:
...@@ -139,5 +155,45 @@ void main() { ...@@ -139,5 +155,45 @@ void main() {
required_agent_capabilities: [] required_agent_capabilities: []
''' '''
); );
testManifestError(
'bad flaky type',
'flaky must be a boolean but was String: not-a-boolean',
'''
tasks:
foo:
description: b
stage: c
required_agent_capabilities: ["a"]
flaky: not-a-boolean
'''
);
test('accepts boolean flaky option', () {
final Manifest manifest = loadTaskManifest('''
tasks:
flaky_task:
description: d
stage: s
required_agent_capabilities: ["c"]
flaky: true
''');
expect(manifest.tasks.single.name, 'flaky_task');
expect(manifest.tasks.single.isFlaky, isTrue);
});
test('accepts custom timeout_in_minutes option', () {
final Manifest manifest = loadTaskManifest('''
tasks:
task_with_custom_timeout:
description: d
stage: s
required_agent_capabilities: ["c"]
timeout_in_minutes: 120
''');
expect(manifest.tasks.single.timeoutInMinutes, 120);
});
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment