Skip to content

Commit c542804

Browse files
committed
Experimental backfill for ios-experimental branch.
1 parent 352affa commit c542804

File tree

4 files changed

+133
-16
lines changed

4 files changed

+133
-16
lines changed

app_dart/lib/src/request_handlers/scheduler/backfill_grid.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,17 @@ final class BackfillTask {
200200
/// The LUCI scheduling priority of backfilling this task.
201201
final int priority;
202202

203+
/// Creates a copy of `this` with the provided properties replaced.
204+
@useResult
205+
BackfillTask copyWith({int? priority}) {
206+
return BackfillTask._from(
207+
task,
208+
target: target,
209+
commit: commit,
210+
priority: priority ?? this.priority,
211+
);
212+
}
213+
203214
@override
204215
String toString() {
205216
return 'BackfillTask ${const JsonEncoder.withIndent(' ').convert({

app_dart/lib/src/request_handlers/scheduler/batch_backfiller.dart

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,26 @@ final class BatchBackfiller extends RequestHandler {
5151
Future<Response> get(Request request) async {
5252
await _backfillReleaseBranch(Config.flutterSlug);
5353
await Future.forEach(config.supportedRepos, _backfillDefaultBranch);
54+
await _backfillExperimentalBranch(Config.flutterSlug);
5455
return Response.emptyOk;
5556
}
5657

58+
// TODO(matanlurey): Remove or make a formal supported feature.
59+
//
60+
// Hardcodes running a branch named `ios-experimental`, which is being tried
61+
// by the iOS team to do MacOS 15.5 validation. It will appear similar to
62+
// any other branch, but use lower-priority scheduling.
63+
//
64+
// See https://github.com/flutter/flutter/issues/168738.
65+
Future<void> _backfillExperimentalBranch(RepositorySlug slug) async {
66+
final fsGrid = await _firestore.queryRecentCommitsAndTasks(
67+
slug,
68+
commitLimit: config.backfillerCommitLimit,
69+
branch: 'ios-experimental',
70+
);
71+
await _doBackfillFrom(slug, fsGrid, forceLowPriority: true);
72+
}
73+
5774
Future<void> _backfillReleaseBranch(RepositorySlug slug) async {
5875
log.debug('Running release branch backfiller for "$slug"');
5976
final branches = await _branchService.getReleaseBranches(slug: slug);
@@ -82,8 +99,9 @@ final class BatchBackfiller extends RequestHandler {
8299

83100
Future<void> _doBackfillFrom(
84101
RepositorySlug slug,
85-
List<CommitAndTasks> fsGrid,
86-
) async {
102+
List<CommitAndTasks> fsGrid, {
103+
bool forceLowPriority = false,
104+
}) async {
87105
if (fsGrid.isEmpty) {
88106
log.warn('No commits to backfill');
89107
return;
@@ -141,6 +159,15 @@ final class BatchBackfiller extends RequestHandler {
141159
'Backfilling ${toBackfillTasks.length} tasks (pruned from $beforePruning)',
142160
);
143161

162+
if (forceLowPriority) {
163+
log.debug('Overriding ${toBackfillTasks.length} tasks to low priority');
164+
for (var i = 0; i < toBackfillTasks.length; i++) {
165+
toBackfillTasks[i] = toBackfillTasks[i].copyWith(
166+
priority: LuciBuildService.kBackfillPriority,
167+
);
168+
}
169+
}
170+
144171
// Update the database first before we schedule builds.
145172
await _updateFirestore(toBackfillTasks, grid.skippableTasks);
146173
log.info('Wrote updates to ${toBackfillTasks.length} tasks for backfill');

app_dart/test/request_handlers/scheduler/backfill_grid_test.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,26 @@ void main() {
162162
]),
163163
);
164164
});
165+
166+
test('can override BackfillTask priority after creation', () {
167+
final commit = generateFirestoreCommit(1).toRef();
168+
final task = generateFirestoreTask(2, commitSha: commit.sha).toRef();
169+
final target = generateTarget(1, name: task.name);
170+
171+
final grid = BackfillGrid.from(
172+
[
173+
(commit, [task]),
174+
],
175+
tipOfTreeTargets: [target],
176+
);
177+
178+
expect(
179+
grid.createBackfillTask(task, priority: 1001).copyWith(priority: 1002),
180+
isBackfillTask
181+
.hasTask(task)
182+
.hasTarget(target)
183+
.hasCommit(commit)
184+
.hasPriority(1002),
185+
);
186+
});
165187
}

app_dart/test/request_handlers/scheduler/batch_backfiller_test.dart

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@
55
import 'package:cocoon_common/rpc_model.dart' as rpc;
66
import 'package:cocoon_common/task_status.dart';
77
import 'package:cocoon_server_test/test_logging.dart';
8+
import 'package:cocoon_service/src/model/commit_ref.dart';
89
import 'package:cocoon_service/src/request_handlers/scheduler/backfill_grid.dart';
910
import 'package:cocoon_service/src/request_handlers/scheduler/backfill_strategy.dart';
1011
import 'package:cocoon_service/src/request_handlers/scheduler/batch_backfiller.dart';
1112
import 'package:cocoon_service/src/service/config.dart';
1213
import 'package:cocoon_service/src/service/luci_build_service.dart';
14+
import 'package:cocoon_service/src/service/luci_build_service/pending_task.dart';
1315
import 'package:collection/collection.dart';
1416
import 'package:github/github.dart';
1517
import 'package:mockito/mockito.dart';
1618
import 'package:test/test.dart';
1719

1820
import '../../src/fake_config.dart';
19-
import '../../src/request_handling/fake_pubsub.dart';
2021
import '../../src/request_handling/request_handler_tester.dart';
2122
import '../../src/service/fake_ci_yaml_fetcher.dart';
2223
import '../../src/service/fake_firestore_service.dart';
23-
import '../../src/service/fake_luci_build_service.dart';
2424
import '../../src/utilities/entity_generators.dart';
2525
import '../../src/utilities/mocks.mocks.dart';
2626

@@ -31,11 +31,10 @@ void main() {
3131
late BatchBackfiller handler;
3232

3333
// Dependencies.
34-
late FakePubSub pubSub;
35-
late MockGithubChecksUtil mockGithubChecksUtil;
3634
late FakeConfig config;
3735
late FakeFirestoreService firestore;
3836
late FakeCiYamlFetcher ciYamlFetcher;
37+
late _FakeLuciBuildService fakeLuciBuildService;
3938

4039
// Used to implement BranchService.getBranches.
4140
late List<rpc.Branch>? branchesForRepository;
@@ -44,22 +43,14 @@ void main() {
4443
late RequestHandlerTester tester;
4544

4645
setUp(() {
47-
pubSub = FakePubSub();
48-
mockGithubChecksUtil = MockGithubChecksUtil();
4946
firestore = FakeFirestoreService();
5047
config = FakeConfig(
5148
backfillerCommitLimitValue: 10,
5249
backfillerTargetLimitValue: 100,
5350
supportedReposValue: {Config.flutterSlug},
5451
);
5552
ciYamlFetcher = FakeCiYamlFetcher();
56-
57-
final luciBuildService = FakeLuciBuildService(
58-
config: config,
59-
pubsub: pubSub,
60-
githubChecksUtil: mockGithubChecksUtil,
61-
firestore: firestore,
62-
);
53+
fakeLuciBuildService = _FakeLuciBuildService();
6354

6455
final branchService = MockBranchService();
6556
branchesForRepository = [];
@@ -79,7 +70,7 @@ void main() {
7970
handler = BatchBackfiller(
8071
config: config,
8172
ciYamlFetcher: ciYamlFetcher,
82-
luciBuildService: luciBuildService,
73+
luciBuildService: fakeLuciBuildService,
8374
backfillerStrategy: const _NaiveBackfillStrategy(),
8475
firestore: firestore,
8576
branchService: branchService,
@@ -362,6 +353,59 @@ void main() {
362353
]);
363354
// dart format on
364355
});
356+
357+
// https://github.com/flutter/flutter/issues/168738
358+
test('schedules low-priority targets for "ios-experimental"', () async {
359+
branchesForRepository = [
360+
// Intentionally left blank.
361+
];
362+
363+
// dart format off
364+
await fillStorageAndSetCiYaml([
365+
[$N, $I, $F, $S],
366+
[$N, $N, $N, $N],
367+
], branch: 'ios-experimental');
368+
// dart format on
369+
370+
// BEFORE:
371+
expect(
372+
await visualizeFirestoreGrid(commits: 2, branch: 'ios-experimental'),
373+
// dart format off
374+
[
375+
'🧑‍💼 ⬜ 🟨 🟥 🟩',
376+
'🧑‍💼 ⬜ ⬜ ⬜ ⬜',
377+
],
378+
// dart format on
379+
);
380+
381+
await tester.get(handler);
382+
383+
// AFTER:
384+
expect(
385+
await visualizeFirestoreGrid(commits: 2, branch: 'ios-experimental'),
386+
// dart format off
387+
[
388+
'🧑‍💼 🟨 🟨 🟥 🟩',
389+
'🧑‍💼 ⬜ 🟨 🟨 🟨',
390+
],
391+
// dart format on
392+
);
393+
394+
expect(
395+
fakeLuciBuildService.scheduledPostsubmitBuilds,
396+
allOf(
397+
hasLength(4),
398+
everyElement(
399+
isA<PendingTask>().having(
400+
(t) => t.priority,
401+
'priority',
402+
LuciBuildService.kBackfillPriority,
403+
),
404+
),
405+
),
406+
reason: 'Should use a low priority for all executions',
407+
);
408+
});
365409
}
366410

367411
/// A very hermetic but dumb backfilling algorithm.
@@ -385,3 +429,16 @@ final class _NaiveBackfillStrategy extends BackfillStrategy {
385429
];
386430
}
387431
}
432+
433+
final class _FakeLuciBuildService extends Fake implements LuciBuildService {
434+
final scheduledPostsubmitBuilds = <PendingTask>[];
435+
436+
@override
437+
Future<List<PendingTask>> schedulePostsubmitBuilds({
438+
required CommitRef commit,
439+
required List<PendingTask> toBeScheduled,
440+
}) async {
441+
scheduledPostsubmitBuilds.addAll(toBeScheduled);
442+
return [];
443+
}
444+
}

0 commit comments

Comments
 (0)