| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // Add fields with data about the test run and the commit tested, and |
| // with the result on the last build tested, to the test results file. |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:test_runner/bot_results.dart'; |
| |
| const skipped = 'skipped'; |
| |
| void main(List<String> args) async { |
| final resultsPath = args[0]; |
| final priorResultsPath = args[1]; |
| final flakyPath = args[2]; |
| final priorFlakyPath = args[3]; |
| final builderName = args[4]; |
| final buildNumber = args[5]; |
| final commitTime = int.parse(args[6]); |
| final commitHash = args[7]; |
| final newResultsPath = args[8]; |
| // Load the input and the flakiness data if specified. |
| final results = await loadResultsMap(resultsPath); |
| final priorResults = await loadResultsMap(priorResultsPath); |
| final flakes = await loadResultsMap(flakyPath); |
| final priorFlakes = await loadResultsMap(priorFlakyPath); |
| final firstPriorResult = |
| priorResults.isEmpty ? null : priorResults.values.first; |
| |
| priorResults.forEach((key, priorResult) { |
| if (priorResult['result'] != skipped) { |
| results.putIfAbsent(key, () => constructNotRunResult(priorResult)); |
| } |
| }); |
| for (final String key in results.keys) { |
| final Map<String, dynamic> result = results[key]!; |
| final Map<String, dynamic>? priorResult = priorResults[key]; |
| final Map<String, dynamic>? flaky = flakes[key]; |
| final Map<String, dynamic>? priorFlaky = priorFlakes[key]; |
| result['commit_hash'] = commitHash; |
| result['commit_time'] = commitTime; |
| result['build_number'] = buildNumber; |
| result['builder_name'] = builderName; |
| result['flaky'] = flaky != null && (flaky['active'] ?? true) == true; |
| result['previous_flaky'] = |
| priorFlaky != null && (priorFlaky['active'] ?? true) == true; |
| if (firstPriorResult != null) { |
| result['previous_commit_hash'] = firstPriorResult['commit_hash']; |
| result['previous_commit_time'] = firstPriorResult['commit_time']; |
| result['previous_build_number'] = firstPriorResult['build_number']; |
| } |
| if (priorResult != null) { |
| result['previous_result'] = priorResult['result']; |
| result['changed'] = !(result['result'] == result['previous_result'] && |
| result['flaky'] == result['previous_flaky'] && |
| result['expected'] == priorResult['expected']); |
| } else { |
| result['changed'] = true; |
| } |
| } |
| final sink = File(newResultsPath).openWrite(); |
| final sorted = results.keys.toList()..sort(); |
| for (final key in sorted) { |
| sink.writeln(jsonEncode(results[key])); |
| } |
| sink.close(); |
| } |
| |
| Map<String, dynamic> constructNotRunResult(Map<String, dynamic> previous) => { |
| for (final key in [ |
| 'name', |
| 'configuration', |
| 'suite', |
| 'test_name', |
| 'expected' |
| ]) |
| key: previous[key], |
| 'time_ms': 0, |
| 'result': skipped, |
| 'matches': true, |
| 'bot_name': '', |
| }; |