Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions agent/bin/agent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'package:http/http.dart';

import 'package:cocoon_agent/src/agent.dart';
import 'package:cocoon_agent/src/commands/ci.dart';
import 'package:cocoon_agent/src/commands/run.dart';
import 'package:cocoon_agent/src/utils.dart';

Future<Null> main(List<String> rawArgs) async {
Expand All @@ -26,7 +25,6 @@ Future<Null> main(List<String> rawArgs) async {
defaultsTo: '.'
);
argParser.addCommand('ci');
argParser.addCommand('run', RunCommand.argParser);

ArgResults args = argParser.parse(rawArgs);

Expand All @@ -45,7 +43,6 @@ Future<Null> main(List<String> rawArgs) async {
}

registerCommand(new ContinuousIntegrationCommand(agent));
registerCommand(new RunCommand(agent));

if (args.command == null) {
print('No command specified, expected one of: ${allCommands.keys.join(', ')}');
Expand Down
100 changes: 14 additions & 86 deletions agent/lib/src/adb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:math' as math;

import 'package:meta/meta.dart';

Expand All @@ -28,24 +27,8 @@ abstract class DeviceDiscovery {
}
}

/// Selects a device to work with, load-balancing between devices if more than
/// one are available.
///
/// A task performing multiple actions on a device would call this method
/// first then follow up by calling [workingDevice]. Calling [workingDevice]
/// repeatedly must guarantee to return the same device.
Future<Null> chooseWorkingDevice();

/// Returns current working device.
///
/// Must be called _after_ a successful call to [chooseWorkingDevice]. May be
/// called repeatedly to perform multiple operations on one specific device;
/// guarantees to return the same device until the next time
/// [chooseWorkingDevice] is called.
Device get workingDevice;

/// Lists all available devices' IDs.
Future<List<String>> discoverDevices();
Future<List<Device>> discoverDevices();

/// Checks the health of the available devices.
Future<Map<String, HealthCheckResult>> checkDevices();
Expand Down Expand Up @@ -94,37 +77,8 @@ class AndroidDeviceDiscovery implements DeviceDiscovery {

AndroidDeviceDiscovery._();

AndroidDevice _workingDevice;

@override
AndroidDevice get workingDevice {
if (_workingDevice == null) {
throw new StateError(
'No working device chosen. Call `chooseWorkingDevice` prior to calling '
'the `workingDevice` getter.',
);
}

return _workingDevice;
}

/// Picks a random Android device out of connected devices and sets it as
/// [workingDevice].
@override
Future<Null> chooseWorkingDevice() async {
List<Device> allDevices = (await discoverDevices())
.map((String id) => new AndroidDevice(deviceId: id))
.toList();

if (allDevices.isEmpty)
throw 'No Android devices detected';

// TODO(yjbanov): filter out and warn about those with low battery level
_workingDevice = allDevices[new math.Random().nextInt(allDevices.length)];
}

@override
Future<List<String>> discoverDevices() async {
Future<List<Device>> discoverDevices() async {
List<String> output = (await eval(config.adbPath, ['devices', '-l'], canFail: false))
.trim().split('\n');
List<String> results = <String>[];
Expand All @@ -150,21 +104,22 @@ class AndroidDeviceDiscovery implements DeviceDiscovery {
}
}

return results;
return results
.map((String id) => new AndroidDevice(deviceId: id))
.toList();
}

@override
Future<Map<String, HealthCheckResult>> checkDevices() async {
Map<String, HealthCheckResult> results = <String, HealthCheckResult>{};
for (String deviceId in await discoverDevices()) {
for (AndroidDevice device in await discoverDevices()) {
try {
AndroidDevice device = new AndroidDevice(deviceId: deviceId);
// Just a smoke test that we can read wakefulness state
// TODO(yjbanov): check battery level
await device._getWakefulness();
results['android-device-$deviceId'] = new HealthCheckResult.success();
results['android-device-${device.deviceId}'] = new HealthCheckResult.success();
} catch(e, s) {
results['android-device-$deviceId'] = new HealthCheckResult.error(e, s);
results['android-device-${device.deviceId}'] = new HealthCheckResult.error(e, s);
}
}
return results;
Expand Down Expand Up @@ -260,53 +215,26 @@ class IosDeviceDiscovery implements DeviceDiscovery {

IosDeviceDiscovery._();

IosDevice _workingDevice;

@override
IosDevice get workingDevice {
if (_workingDevice == null) {
throw new StateError(
'No working device chosen. Call `chooseWorkingDevice` prior to calling '
'the `workingDevice` getter.',
);
}

return _workingDevice;
}

/// Picks a random iOS device out of connected devices and sets it as
/// [workingDevice].
@override
Future<Null> chooseWorkingDevice() async {
List<IosDevice> allDevices = (await discoverDevices())
.map((String id) => new IosDevice(deviceId: id))
.toList();

if (allDevices.length == 0)
throw 'No iOS devices detected';

// TODO(yjbanov): filter out and warn about those with low battery level
_workingDevice = allDevices[new math.Random().nextInt(allDevices.length)];
}

@override
Future<List<String>> discoverDevices() async {
Future<List<Device>> discoverDevices() async {
// TODO: use the -k UniqueDeviceID option, which requires much less parsing.
List<String> iosDeviceIds = grep('UniqueDeviceID', from: await eval('ideviceinfo', []))
.map((String line) => line.split(' ').last).toList();

if (iosDeviceIds.isEmpty)
throw 'No connected iOS devices found.';

return iosDeviceIds;
return iosDeviceIds
.map((String id) => new IosDevice(deviceId: id))
.toList();
}

@override
Future<Map<String, HealthCheckResult>> checkDevices() async {
Map<String, HealthCheckResult> results = <String, HealthCheckResult>{};
for (String deviceId in await discoverDevices()) {
for (Device device in await discoverDevices()) {
// TODO: do a more meaningful connectivity check than just recording the ID
results['ios-device-$deviceId'] = new HealthCheckResult.success();
results['ios-device-${device.deviceId}'] = new HealthCheckResult.success();
}
return results;
}
Expand Down
58 changes: 0 additions & 58 deletions agent/lib/src/agent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ import 'package:args/args.dart';
import 'package:http/http.dart';
import 'package:meta/meta.dart';

import 'package:cocoon_agent/src/adb.dart';
import 'package:cocoon_agent/src/analysis.dart';
import 'package:cocoon_agent/src/framework.dart';
import 'package:cocoon_agent/src/gallery.dart';
import 'package:cocoon_agent/src/golem.dart';
import 'package:cocoon_agent/src/perf_tests.dart';
import 'package:cocoon_agent/src/refresh.dart';
import 'package:cocoon_agent/src/hot_dev_cycle.dart';
import 'package:cocoon_agent/src/size_tests.dart';
import 'package:cocoon_agent/src/utils.dart';

/// Contains information about a Cocoon task.
Expand Down Expand Up @@ -49,25 +40,6 @@ class Agent {
return JSON.decode(resp.body);
}

Future<BuildResult> performTask(CocoonTask reservation) async {
int golemRevision = await computeGolemRevision();
Task task = await getTask(reservation);
TaskRunner runner = new TaskRunner(reservation.revision, golemRevision, <Task>[task]);
try {
return await runner.run();
} finally {
await _screenOff();
}
}

Future<Null> _screenOff() async {
try {
await devices.workingDevice.sendToSleep();
} catch(error, stackTrace) {
print('Failed to turn off screen: $error\n$stackTrace');
}
}

Future<Null> uploadLogChunk(CocoonTask task, String chunk) async {
String url = '$baseCocoonUrl/api/append-log?ownerKey=${task.key}';
Response resp = await httpClient.post(url, body: chunk);
Expand All @@ -77,36 +49,6 @@ class Agent {
}
}

Future<Task> getTask(CocoonTask task) async {
DateTime revisionTimestamp = await getFlutterRepoCommitTimestamp(task.revision);
String dartSdkVersion = await getDartVersion();

List<Task> allTasks = <Task>[
createComplexLayoutScrollPerfTest(),
createComplexLayoutScrollPerfTest(ios: true),
createFlutterGalleryStartupTest(),
createFlutterGalleryStartupTest(ios: true),
createComplexLayoutStartupTest(),
createComplexLayoutStartupTest(ios: true),
createFlutterGalleryBuildTest(),
createComplexLayoutBuildTest(),
createGalleryTransitionTest(),
createGalleryTransitionTest(ios: true),
createBasicMaterialAppSizeTest(),
createAnalyzerCliTest(sdk: dartSdkVersion, commit: task.revision, timestamp: revisionTimestamp),
createAnalyzerServerTest(sdk: dartSdkVersion, commit: task.revision, timestamp: revisionTimestamp),
createRefreshTest(commit: task.revision, timestamp: revisionTimestamp),
createHotDevCycleTest(commit: task.revision, timestamp: revisionTimestamp),
];

return allTasks.firstWhere(
(Task t) => t.name == task.name,
orElse: () {
throw 'Task $task.name not found';
}
);
}

/// Reserves a task in Cocoon backend to be performed by this agent.
///
/// If not tasks are available returns `null`.
Expand Down
107 changes: 0 additions & 107 deletions agent/lib/src/analysis.dart

This file was deleted.

Loading