appsok/test/adb_service_test.dart
toki 9d91b947c6 feat: usb install feature implementation
- Add adb_service.dart with usb install capabilities
- Add adb_service_test.dart for testing
- Update project rules and phase documentation
- Update milestone documents for jenkins-credential and usb-install
- Add agent-task/m-usb-install/ directory with planning documents
2026-06-12 22:05:42 +09:00

134 lines
4.3 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:appsok/src/services/adb_service.dart';
void main() {
group('AdbRuntimeConfig', () {
test('prefers bundled adb when it exists', () {
final tempDir = Directory.systemTemp.createTempSync(
'appsok-adb-runtime-',
);
addTearDown(() => tempDir.deleteSync(recursive: true));
final bundledAdb = File('${tempDir.path}/adb')..writeAsStringSync('');
final runtime = AdbRuntimeConfig(
bundledAdbPath: bundledAdb.path,
).resolve();
expect(runtime.executablePath, bundledAdb.path);
expect(runtime.source, AdbExecutableSource.bundled);
expect(runtime.bundledExists, isTrue);
expect(runtime.fallbackUsed, isFalse);
expect(runtime.serverPort, AdbRuntimeConfig.defaultAppSokServerPort);
});
test('falls back to system adb when bundled adb is missing', () {
final runtime = const AdbRuntimeConfig(
bundledAdbPath: '/tmp/appsok-missing-adb',
).resolve();
expect(runtime.executablePath, AdbRuntimeConfig.systemAdbPath);
expect(runtime.source, AdbExecutableSource.system);
expect(runtime.bundledExists, isFalse);
expect(runtime.fallbackUsed, isTrue);
});
test('uses custom adb as an explicit override', () {
final tempDir = Directory.systemTemp.createTempSync(
'appsok-adb-runtime-',
);
addTearDown(() => tempDir.deleteSync(recursive: true));
final bundledAdb = File('${tempDir.path}/adb')..writeAsStringSync('');
final runtime = AdbRuntimeConfig(
bundledAdbPath: bundledAdb.path,
customAdbPath: '/custom/platform-tools/adb',
).resolve();
expect(runtime.executablePath, '/custom/platform-tools/adb');
expect(runtime.source, AdbExecutableSource.custom);
expect(runtime.fallbackUsed, isFalse);
});
test('uses shared ADB server port when requested', () {
final runtime = const AdbRuntimeConfig(
serverMode: AdbServerMode.shared,
).resolve();
expect(runtime.serverPort, AdbRuntimeConfig.sharedServerPort);
expect(runtime.environment, {'ADB_SERVER_PORT': '5037'});
});
});
group('AdbService', () {
test(
'runs adb devices with the resolved executable and server port',
() async {
final calls =
<({String executable, List<String> args, String? port})>[];
final service = AdbService(
runtimeConfig: const AdbRuntimeConfig(
customAdbPath: '/opt/appsok/adb',
serverPort: 15037,
),
processRunner: (executable, args, {environment}) async {
calls.add((
executable: executable,
args: args,
port: environment?['ADB_SERVER_PORT'],
));
return ProcessResult(
42,
0,
'List of devices attached\n'
'emulator-5554 device product:emu64a '
'model:sdk_gphone64_arm64 device:emu64a\n',
'',
);
},
);
final devices = await service.listDevices();
expect(calls, hasLength(1));
expect(calls.single.executable, '/opt/appsok/adb');
expect(calls.single.args, ['devices', '-l']);
expect(calls.single.port, '15037');
expect(devices.single.serial, 'emulator-5554');
expect(devices.single.state, 'device');
expect(devices.single.model, 'sdk_gphone64_arm64');
},
);
test('runs adb install with the shared server port', () async {
final calls = <({List<String> args, String? port})>[];
final service = AdbService(
runtimeConfig: const AdbRuntimeConfig(
customAdbPath: '/opt/appsok/adb',
serverMode: AdbServerMode.shared,
),
processRunner: (_, args, {environment}) async {
calls.add((args: args, port: environment?['ADB_SERVER_PORT']));
return ProcessResult(42, 0, 'Success', '');
},
);
final result = await service.installApk(
serial: 'R5CT90A1B2C',
apkPath: '/tmp/app.apk',
);
expect(result.succeeded, isTrue);
expect(calls.single.args, [
'-s',
'R5CT90A1B2C',
'install',
'-r',
'/tmp/app.apk',
]);
expect(calls.single.port, '5037');
});
});
}