blob: 87381b8b85667f8fc676094f2f992dcf6886d342 [file] [log] [blame]
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:cocoon_service/src/model/appengine/task.dart';
import 'package:cocoon_service/src/model/luci/push_message.dart';
import 'package:gcloud/db.dart';
import 'package:test/test.dart';
import '../src/utilities/entity_generators.dart';
void main() {
group('Task', () {
test('byAttempts comparator', () {
final List<Task> tasks = <Task>[
generateTask(1, attempts: 5),
generateTask(2, attempts: 9),
generateTask(3, attempts: 3),
];
tasks.sort(Task.byAttempts);
expect(tasks.map<int>((Task task) => task.attempts!), <int>[3, 5, 9]);
});
test('disallows illegal status', () {
expect(() => generateTask(1, status: 'unknown'), throwsArgumentError);
expect(() => generateTask(1)..status = 'unknown', throwsArgumentError);
});
group('updateFromBuild', () {
test('updates if buildNumber is null', () {
final DateTime created = DateTime.utc(2022, 1, 11, 1, 1);
final DateTime started = DateTime.utc(2022, 1, 11, 1, 2);
final DateTime completed = DateTime.utc(2022, 1, 11, 1, 3);
final Build build = generatePushMessageBuild(
1,
createdTimestamp: created,
startedTimestamp: started,
completedTimestamp: completed,
);
final Task task = generateTask(1);
expect(task.status, Task.statusNew);
expect(task.buildNumberList, isNull);
expect(task.buildNumber, isNull);
expect(task.endTimestamp, 0);
expect(task.createTimestamp, 0);
expect(task.startTimestamp, 0);
task.updateFromBuild(build);
expect(task.status, Task.statusSucceeded);
expect(task.buildNumber, 1);
expect(task.buildNumberList, '1');
expect(task.createTimestamp, created.millisecondsSinceEpoch);
expect(task.startTimestamp, started.millisecondsSinceEpoch);
expect(task.endTimestamp, completed.millisecondsSinceEpoch);
});
test('defaults timestamps to 0', () {
final Build build = generatePushMessageBuild(1);
final Task task = generateTask(1);
expect(task.endTimestamp, 0);
expect(task.createTimestamp, 0);
expect(task.startTimestamp, 0);
task.updateFromBuild(build);
expect(task.endTimestamp, 0);
expect(task.createTimestamp, 0);
expect(task.startTimestamp, 0);
});
test('updates if buildNumber is prior to pushMessage', () {
final Build build = generatePushMessageBuild(
1,
buildNumber: 2,
status: Status.started,
);
final Task task = generateTask(
1,
buildNumber: 1,
status: Task.statusSucceeded,
);
expect(task.buildNumberList, '1');
expect(task.status, Task.statusSucceeded);
task.updateFromBuild(build);
expect(task.buildNumber, 2);
expect(task.buildNumberList, '1,2');
expect(task.status, Task.statusInProgress);
});
test('does not duplicate build numbers on multiple messages', () {
final Build build = generatePushMessageBuild(
1,
status: Status.started,
);
final Task task = generateTask(
1,
buildNumber: 1,
status: Task.statusSucceeded,
);
expect(task.buildNumber, 1);
expect(task.buildNumberList, '1');
expect(task.status, Task.statusSucceeded);
task.updateFromBuild(build);
expect(task.buildNumber, 1);
expect(task.buildNumberList, '1');
expect(task.status, Task.statusSucceeded);
});
test('does not update status if older status', () {
final Build build = generatePushMessageBuild(
1,
status: Status.started,
);
final Task task = generateTask(
1,
buildNumber: 1,
status: Task.statusSucceeded,
);
expect(task.buildNumber, 1);
expect(task.status, Task.statusSucceeded);
task.updateFromBuild(build);
expect(task.buildNumber, 1);
expect(task.status, Task.statusSucceeded);
});
test('does not update if build is older than task', () {
final Build build = generatePushMessageBuild(
1,
status: Status.completed,
result: Result.success,
);
final Task task = generateTask(
1,
buildNumber: 2,
status: Task.statusNew,
);
expect(task.buildNumber, 2);
expect(task.status, Task.statusNew);
task.updateFromBuild(build);
expect(task.buildNumber, 2);
expect(task.status, Task.statusNew);
});
test('handles cancelled build', () {
final Build build = generatePushMessageBuild(
1,
status: Status.completed,
result: Result.canceled,
);
final Task task = generateTask(
1,
buildNumber: 1,
status: Task.statusNew,
);
expect(task.status, Task.statusNew);
task.updateFromBuild(build);
expect(task.status, Task.statusCancelled);
});
});
});
}
void validateModel(Task task) {
// Throws an exception when property validation fails.
ModelDBImpl().toDatastoreEntity(task);
}