Skip to content

Commit 1234c2c

Browse files
authored
Properly record a new task for a new dart_internal build ID. (#4513)
I think this has been a bug for a while, but could have also been caused by the Firestore migration. After this PR, `dart_internal` should show re-runs and previous builds like expected. Closes flutter/flutter#166935. /cc @reidbaker
1 parent e6b3661 commit 1234c2c

File tree

5 files changed

+82
-8
lines changed

5 files changed

+82
-8
lines changed

app_dart/lib/src/model/firestore/task.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,18 @@ final class Task extends AppDocument<Task> {
373373
_setStatusFromLuciStatus(build);
374374
}
375375

376-
void resetAsRetry({int attempt = 1}) {
377-
name =
378-
'$kDatabase/documents/$kTaskCollectionId/${commitSha}_${taskName}_$attempt';
376+
void resetAsRetry({int? attempt}) {
377+
attempt ??= currentAttempt + 1;
378+
name = p.posix.join(
379+
kDatabase,
380+
'documents',
381+
kTaskCollectionId,
382+
Task.documentIdFor(
383+
commitSha: commitSha,
384+
currentAttempt: attempt,
385+
taskName: taskName,
386+
).documentId,
387+
);
379388
fields = <String, Value>{
380389
fieldCreateTimestamp: DateTime.now().millisecondsSinceEpoch.toValue(),
381390
fieldEndTimestamp: 0.toValue(),
@@ -389,6 +398,10 @@ final class Task extends AppDocument<Task> {
389398
};
390399
}
391400

401+
void setBuildNumber(int buildNumber) {
402+
fields[fieldBuildNumber] = buildNumber.toValue();
403+
}
404+
392405
String _setStatusFromLuciStatus(bbv2.Build build) {
393406
// Updates can come out of order. Ensure completed statuses are kept.
394407
if (_isStatusCompleted()) {

app_dart/lib/src/request_handlers/dart_internal_subscription.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ final class DartInternalSubscription extends SubscriptionHandler {
5353
);
5454
if (existing != null) {
5555
fsTask = existing;
56+
if (build.number != fsTask.buildNumber) {
57+
fsTask.resetAsRetry();
58+
fsTask.setBuildNumber(build.number);
59+
}
5660
fsTask.updateFromBuild(build);
5761
} else {
5862
fsTask = fs.Task(

app_dart/lib/src/service/luci_build_service.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,8 +1108,7 @@ class LuciBuildService {
11081108
fs.Task task,
11091109
) async {
11101110
// Update task status in Firestore.
1111-
final newAttempt = task.currentAttempt + 1;
1112-
task.resetAsRetry(attempt: newAttempt);
1111+
task.resetAsRetry();
11131112
task.setStatus(fs.Task.statusInProgress);
11141113

11151114
final firestore = await _config.createFirestoreService();
@@ -1132,11 +1131,11 @@ class LuciBuildService {
11321131
name: task.taskName,
11331132
);
11341133
dsExistingTask
1135-
..attempts = newAttempt
1134+
..attempts = task.currentAttempt
11361135
..status = Task.statusInProgress;
11371136
await datastore.insert([dsExistingTask]);
11381137

1139-
return newAttempt;
1138+
return task.currentAttempt;
11401139
}
11411140

11421141
/// Check if a builder should be rerun.

app_dart/test/model/firestore/task_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void main() {
117117
status: Task.statusFailed,
118118
testFlaky: true,
119119
);
120-
task.resetAsRetry(attempt: 2);
120+
task.resetAsRetry();
121121

122122
expect(int.parse(task.name!.split('_').last), 2);
123123
expect(task.status, Task.statusNew);

app_dart/test/request_handlers/dart_internal_subscription_test.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,62 @@ void main() {
187187
.having((t) => t.status, 'status', 'Succeeded'),
188188
]);
189189
});
190+
191+
test('records a retry of an existing task', () async {
192+
// Insert into Datastore:
193+
await config.db.commit(
194+
inserts: [
195+
generateTask(
196+
1,
197+
attempts: 1,
198+
buildNumber: buildNumber - 1,
199+
builderName: builder,
200+
name: builder,
201+
status: fs.Task.statusFailed,
202+
parent: dsCommit,
203+
),
204+
],
205+
);
206+
207+
// Insert into Firestore:
208+
firestoreService.putDocument(
209+
generateFirestoreTask(
210+
1,
211+
attempts: 1,
212+
buildNumber: buildNumber - 1,
213+
name: builder,
214+
status: fs.Task.statusFailed,
215+
commitSha: dsCommit.sha,
216+
),
217+
);
218+
219+
tester.message = const PushMessage(data: buildMessageJson);
220+
await tester.post(handler);
221+
222+
// Check Firestore:
223+
expect(
224+
firestoreService,
225+
existsInStorage(fs.Task.metadata, [
226+
isTask
227+
.hasTaskName(builder)
228+
.hasCurrentAttempt(1)
229+
.hasBuildNumber(buildNumber - 1)
230+
.hasStatus(fs.Task.statusFailed),
231+
isTask
232+
.hasTaskName(builder)
233+
.hasCurrentAttempt(2)
234+
.hasBuildNumber(buildNumber)
235+
.hasStatus(fs.Task.statusSucceeded),
236+
]),
237+
);
238+
239+
// Check Datastore:
240+
expect(config.db.values.values.whereType<ds.Task>(), [
241+
isA<ds.Task>()
242+
.having((t) => t.builderName, 'builderName', builder)
243+
.having((t) => t.attempts, 'attempts', 2)
244+
.having((t) => t.buildNumber, 'buildNumber', buildNumber)
245+
.having((t) => t.status, 'status', 'Succeeded'),
246+
]);
247+
});
190248
}

0 commit comments

Comments
 (0)