OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// Compares the test log of a build step with previous builds. | 5 /// Compares the test log of a build step with previous builds. |
6 /// | 6 /// |
7 /// Use this to detect flakiness of failures, especially timeouts. | 7 /// Use this to detect flakiness of failures, especially timeouts. |
8 | 8 |
9 import 'dart:async'; | 9 import 'dart:async'; |
10 | 10 |
| 11 import 'package:gardening/src/bot.dart'; |
11 import 'package:gardening/src/buildbot_structures.dart'; | 12 import 'package:gardening/src/buildbot_structures.dart'; |
12 import 'package:gardening/src/buildbot_data.dart'; | 13 import 'package:gardening/src/buildbot_data.dart'; |
13 import 'package:gardening/src/client.dart'; | |
14 import 'package:gardening/src/util.dart'; | 14 import 'package:gardening/src/util.dart'; |
15 | 15 |
16 Future mainInternal(BuildbotClient client, List<String> args, | 16 Future mainInternal(Bot bot, List<String> args, {int runCount: 10}) async { |
17 {int runCount: 10}) async { | |
18 printBuildResultsSummary( | 17 printBuildResultsSummary( |
19 await loadBuildResults(client, args, runCount: runCount), args); | 18 await loadBuildResults(bot, args, runCount: runCount), args); |
20 } | 19 } |
21 | 20 |
22 /// Loads [BuildResult]s for the [runCount] last builds for the build(s) in | 21 /// Loads [BuildResult]s for the [runCount] last builds for the build(s) in |
23 /// [args]. [args] can be a list of [BuildGroup] names or a list of log uris. | 22 /// [args]. [args] can be a list of [BuildGroup] names or a list of log uris. |
24 Future<Map<BuildUri, List<BuildResult>>> loadBuildResults( | 23 Future<Map<BuildUri, List<BuildResult>>> loadBuildResults( |
25 BuildbotClient client, List<String> args, | 24 Bot bot, List<String> args, |
26 {int runCount: 10}) async { | 25 {int runCount: 10}) async { |
27 List<BuildUri> buildUriList = <BuildUri>[]; | 26 List<BuildUri> buildUriList = <BuildUri>[]; |
28 for (BuildGroup buildGroup in buildGroups) { | 27 for (BuildGroup buildGroup in buildGroups) { |
29 if (args.contains(buildGroup.groupName)) { | 28 if (args.contains(buildGroup.groupName)) { |
30 buildUriList.addAll(buildGroup.createUris(client.mostRecentBuildNumber)); | 29 buildUriList.addAll(buildGroup.createUris(bot.mostRecentBuildNumber)); |
31 } | 30 } |
32 } | 31 } |
33 if (buildUriList.isEmpty) { | 32 if (buildUriList.isEmpty) { |
34 for (String url in args) { | 33 for (String url in args) { |
35 buildUriList.add(new BuildUri.fromUrl(url)); | 34 buildUriList.add(new BuildUri.fromUrl(url)); |
36 } | 35 } |
37 } | 36 } |
38 Map<BuildUri, List<BuildResult>> buildResults = | 37 Map<BuildUri, List<BuildResult>> pastResultsMap = |
39 <BuildUri, List<BuildResult>>{}; | 38 <BuildUri, List<BuildResult>>{}; |
40 for (BuildUri buildUri in buildUriList) { | 39 List<BuildResult> buildResults = await bot.readResults(buildUriList); |
| 40 for (int index = 0; index < buildUriList.length; index++) { |
| 41 BuildUri buildUri = buildUriList[index]; |
| 42 BuildResult buildResult = buildResults[index]; |
41 List<BuildResult> results = | 43 List<BuildResult> results = |
42 await readBuildResults(client, buildUri, runCount); | 44 await readPastResults(bot, buildUri, buildResult, runCount); |
43 buildResults[buildUri] = results; | 45 pastResultsMap[buildUri] = results; |
44 } | 46 } |
45 return buildResults; | 47 return pastResultsMap; |
46 } | 48 } |
47 | 49 |
48 /// Prints summaries for the [buildResults]. | 50 /// Prints summaries for the [buildResults]. |
49 void printBuildResultsSummary( | 51 void printBuildResultsSummary( |
50 Map<BuildUri, List<BuildResult>> buildResults, List<String> args) { | 52 Map<BuildUri, List<BuildResult>> buildResults, List<String> args) { |
51 List<Summary> emptySummaries = <Summary>[]; | 53 List<Summary> emptySummaries = <Summary>[]; |
52 List<Summary> nonEmptySummaries = <Summary>[]; | 54 List<Summary> nonEmptySummaries = <Summary>[]; |
53 buildResults.forEach((BuildUri buildUri, List<BuildResult> results) { | 55 buildResults.forEach((BuildUri buildUri, List<BuildResult> results) { |
54 Summary summary = new Summary(buildUri, results); | 56 Summary summary = new Summary(buildUri, results); |
55 if (summary.isEmpty) { | 57 if (summary.isEmpty) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 sb.write( | 94 sb.write( |
93 'No errors found for the ${emptySummaries.length} remaining bots.'); | 95 'No errors found for the ${emptySummaries.length} remaining bots.'); |
94 } | 96 } |
95 } | 97 } |
96 } | 98 } |
97 print(sb); | 99 print(sb); |
98 } | 100 } |
99 | 101 |
100 /// Creates a [BuildResult] for [buildUri] and, if it contains failures, the | 102 /// Creates a [BuildResult] for [buildUri] and, if it contains failures, the |
101 /// [BuildResult]s for the previous [runCount] builds. | 103 /// [BuildResult]s for the previous [runCount] builds. |
102 Future<List<BuildResult>> readBuildResults( | 104 Future<List<BuildResult>> readPastResults( |
103 BuildbotClient client, BuildUri buildUri, int runCount) async { | 105 Bot bot, BuildUri buildUri, BuildResult summary, int runCount) async { |
104 List<BuildResult> summaries = <BuildResult>[]; | 106 List<BuildResult> summaries = <BuildResult>[]; |
105 BuildResult summary = await client.readResult(buildUri); | |
106 if (summary == null) { | 107 if (summary == null) { |
107 print('No result found for $buildUri'); | 108 print('No result found for $buildUri'); |
108 return summaries; | 109 return summaries; |
109 } | 110 } |
110 summaries.add(summary); | 111 summaries.add(summary); |
111 if (summary.hasFailures) { | 112 if (summary.hasFailures) { |
112 for (int i = 0; i < runCount; i++) { | 113 summaries.addAll(await bot.readHistoricResults(summary.buildUri.prev(), |
113 buildUri = summary.buildUri.prev(); | 114 previousCount: runCount - 1)); |
114 summary = await client.readResult(buildUri); | |
115 summaries.add(summary); | |
116 } | |
117 } | 115 } |
118 return summaries; | 116 return summaries; |
119 } | 117 } |
120 | 118 |
121 class Summary { | 119 class Summary { |
122 final BuildUri buildUri; | 120 final BuildUri buildUri; |
123 final List<BuildResult> results; | 121 final List<BuildResult> results; |
124 final Set<TestConfiguration> timeoutIds = new Set<TestConfiguration>(); | 122 final Set<TestConfiguration> timeoutIds = new Set<TestConfiguration>(); |
125 final Set<TestConfiguration> errorIds = new Set<TestConfiguration>(); | 123 final Set<TestConfiguration> errorIds = new Set<TestConfiguration>(); |
126 | 124 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 sb.write('No errors found for ${name}'); | 207 sb.write('No errors found for ${name}'); |
210 } | 208 } |
211 } | 209 } |
212 | 210 |
213 String get name => results.isNotEmpty | 211 String get name => results.isNotEmpty |
214 // Use the first result as name since it most likely has an absolute build | 212 // Use the first result as name since it most likely has an absolute build |
215 // number. | 213 // number. |
216 ? results.first.buildUri.toString() | 214 ? results.first.buildUri.toString() |
217 : buildUri.toString(); | 215 : buildUri.toString(); |
218 } | 216 } |
OLD | NEW |