| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:io' show | 5 import 'dart:io' show |
| 6 Directory, | 6 Directory, |
| 7 File, | 7 File, |
| 8 FileSystemException, | 8 FileSystemException, |
| 9 Process, | 9 Process, |
| 10 ProcessSignal, | 10 ProcessSignal, |
| 11 Socket, | 11 Socket, |
| 12 SocketException; | 12 SocketException; |
| 13 | 13 |
| 14 import 'dart:convert' show | 14 import 'dart:convert' show |
| 15 LineSplitter, | 15 LineSplitter, |
| 16 UTF8, | 16 UTF8, |
| 17 Utf8Decoder; | 17 Utf8Decoder; |
| 18 | 18 |
| 19 import 'dart:async' show | 19 import 'dart:async' show |
| 20 Future; | 20 Future; |
| 21 | 21 |
| 22 import 'package:expect/expect.dart' show | 22 import 'package:expect/expect.dart' show |
| 23 Expect; | 23 Expect; |
| 24 | 24 |
| 25 import 'package:fletch_agent/messages.dart' show | 25 import 'package:dartino_agent/messages.dart' show |
| 26 PACKAGE_FILE_NAME; | 26 PACKAGE_FILE_NAME; |
| 27 | 27 |
| 28 import 'package:fletch_agent/agent_connection.dart' show | 28 import 'package:dartino_agent/agent_connection.dart' show |
| 29 AgentConnection, | 29 AgentConnection, |
| 30 AgentException, | 30 AgentException, |
| 31 VmData; | 31 VmData; |
| 32 | 32 |
| 33 import 'package:fletchc/src/guess_configuration.dart' show | 33 import 'package:dartino_compiler/src/guess_configuration.dart' show |
| 34 executable; | 34 executable; |
| 35 | 35 |
| 36 import '../fletchc/run.dart' show | 36 import '../dartino_compiler/run.dart' show |
| 37 export; | 37 export; |
| 38 | 38 |
| 39 typedef Future NoArgFuture(); | 39 typedef Future NoArgFuture(); |
| 40 | 40 |
| 41 List<AgentTest> AGENT_TESTS = <AgentTest>[ | 41 List<AgentTest> AGENT_TESTS = <AgentTest>[ |
| 42 new AgentLifeCycleTest(), | 42 new AgentLifeCycleTest(), |
| 43 new AgentUpgradeProtocolTest(), | 43 new AgentUpgradeProtocolTest(), |
| 44 new AgentUnsupportedCommandsTest(), | 44 new AgentUnsupportedCommandsTest(), |
| 45 ]; | 45 ]; |
| 46 | 46 |
| 47 const String fletchVmExecutable = const String.fromEnvironment('fletch-vm'); | 47 const String dartinoVmExecutable = const String.fromEnvironment('dartino-vm'); |
| 48 const String buildDirectory = | 48 const String buildDirectory = |
| 49 const String.fromEnvironment('test.dart.build-dir'); | 49 const String.fromEnvironment('test.dart.build-dir'); |
| 50 const int SIGINT = 2; | 50 const int SIGINT = 2; |
| 51 | 51 |
| 52 abstract class AgentTest { | 52 abstract class AgentTest { |
| 53 final String name; | 53 final String name; |
| 54 final String outputDirectory; | 54 final String outputDirectory; |
| 55 final String host = '127.0.0.1'; | 55 final String host = '127.0.0.1'; |
| 56 final int port; | 56 final int port; |
| 57 Process process; | 57 Process process; |
| 58 Future stdoutFuture; | 58 Future stdoutFuture; |
| 59 Future stderrFuture; | 59 Future stderrFuture; |
| 60 Map<String, String> environment; | 60 Map<String, String> environment; |
| 61 | 61 |
| 62 /// Each agent test must be assigned a unique port on which the fletch agent | 62 /// Each agent test must be assigned a unique port on which the dartino agent |
| 63 /// for the specific test is listening. The port must be unique since the | 63 /// for the specific test is listening. The port must be unique since the |
| 64 /// tests are run in parallel. | 64 /// tests are run in parallel. |
| 65 AgentTest(String name, int port) | 65 AgentTest(String name, int port) |
| 66 : this.name = name, | 66 : this.name = name, |
| 67 this.port = port, | 67 this.port = port, |
| 68 outputDirectory = '$buildDirectory/tests/$name' { | 68 outputDirectory = '$buildDirectory/tests/$name' { |
| 69 environment = { | 69 environment = { |
| 70 'FLETCH_VM': fletchVmExecutable, | 70 'DARTINO_VM': dartinoVmExecutable, |
| 71 'AGENT_IP': host, | 71 'AGENT_IP': host, |
| 72 'AGENT_PORT': port.toString(), | 72 'AGENT_PORT': port.toString(), |
| 73 'AGENT_PID_FILE': '$outputDirectory/fletch-agent.pid', | 73 'AGENT_PID_FILE': '$outputDirectory/dartino-agent.pid', |
| 74 'AGENT_LOG_FILE': '$outputDirectory/fletch-agent.log', | 74 'AGENT_LOG_FILE': '$outputDirectory/dartino-agent.log', |
| 75 'VM_LOG_DIR': outputDirectory, | 75 'VM_LOG_DIR': outputDirectory, |
| 76 'VM_PID_DIR': outputDirectory, | 76 'VM_PID_DIR': outputDirectory, |
| 77 'AGENT_UPGRADE_DRY_RUN': 'true', | 77 'AGENT_UPGRADE_DRY_RUN': 'true', |
| 78 }; | 78 }; |
| 79 } | 79 } |
| 80 | 80 |
| 81 Future<Null> execute(); | 81 Future<Null> execute(); |
| 82 | 82 |
| 83 void createOutputDirectory() { | 83 void createOutputDirectory() { |
| 84 new Directory(outputDirectory).createSync(recursive: true); | 84 new Directory(outputDirectory).createSync(recursive: true); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void deleteOutputDirectory() { | 87 void deleteOutputDirectory() { |
| 88 new Directory(outputDirectory).deleteSync(recursive: true); | 88 new Directory(outputDirectory).deleteSync(recursive: true); |
| 89 } | 89 } |
| 90 | 90 |
| 91 Future<Null> createSnapshot() async { | 91 Future<Null> createSnapshot() async { |
| 92 // Find the path to the fletch agent script. | 92 // Find the path to the dartino agent script. |
| 93 Uri script = executable.resolve('../../pkg/fletch_agent/bin/agent.dart'); | 93 Uri script = executable.resolve('../../pkg/dartino_agent/bin/agent.dart'); |
| 94 await export(script.toFilePath(), '$outputDirectory/fletch-agent.snapshot'); | 94 await export(script.toFilePath(), '$outputDirectory/dartino-agent.snapshot')
; |
| 95 print('Agent snapshot generated: $outputDirectory/fletch-agent.snapshot'); | 95 print('Agent snapshot generated: $outputDirectory/dartino-agent.snapshot'); |
| 96 } | 96 } |
| 97 | 97 |
| 98 Future<Null> start() async { | 98 Future<Null> start() async { |
| 99 process = await Process.start( | 99 process = await Process.start( |
| 100 fletchVmExecutable, | 100 dartinoVmExecutable, |
| 101 ['$outputDirectory/fletch-agent.snapshot'], | 101 ['$outputDirectory/dartino-agent.snapshot'], |
| 102 environment: environment); | 102 environment: environment); |
| 103 stdoutFuture = process.stdout.transform(UTF8.decoder) | 103 stdoutFuture = process.stdout.transform(UTF8.decoder) |
| 104 .transform(new LineSplitter()) | 104 .transform(new LineSplitter()) |
| 105 .listen(print).asFuture(); | 105 .listen(print).asFuture(); |
| 106 stderrFuture = process.stderr.transform(UTF8.decoder) | 106 stderrFuture = process.stderr.transform(UTF8.decoder) |
| 107 .transform(new LineSplitter()) | 107 .transform(new LineSplitter()) |
| 108 .listen(print).asFuture(); | 108 .listen(print).asFuture(); |
| 109 print('Running agent with pid ${process.pid}'); | 109 print('Running agent with pid ${process.pid}'); |
| 110 } | 110 } |
| 111 | 111 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 164 } |
| 165 return tests; | 165 return tests; |
| 166 } | 166 } |
| 167 | 167 |
| 168 class AgentLifeCycleTest extends AgentTest { | 168 class AgentLifeCycleTest extends AgentTest { |
| 169 AgentLifeCycleTest() : super('testAgentLifeCycle', 20000); | 169 AgentLifeCycleTest() : super('testAgentLifeCycle', 20000); |
| 170 | 170 |
| 171 Future<Null> execute() async { | 171 Future<Null> execute() async { |
| 172 // Check the version. | 172 // Check the version. |
| 173 await withConnection((AgentConnection connection) async { | 173 await withConnection((AgentConnection connection) async { |
| 174 String version = await connection.fletchVersion(); | 174 String version = await connection.dartinoVersion(); |
| 175 Expect.isTrue(version.length > 0, 'No version found.'); | 175 Expect.isTrue(version.length > 0, 'No version found.'); |
| 176 }); | 176 }); |
| 177 | 177 |
| 178 // Start a VM. | 178 // Start a VM. |
| 179 VmData data; | 179 VmData data; |
| 180 await withConnection((AgentConnection connection) async { | 180 await withConnection((AgentConnection connection) async { |
| 181 data = await connection.startVm(); | 181 data = await connection.startVm(); |
| 182 Expect.isNotNull(data, 'Failed to spawn new fletch VM'); | 182 Expect.isNotNull(data, 'Failed to spawn new dartino VM'); |
| 183 Expect.isNotNull(data.id, 'Null is not a valid VM pid'); | 183 Expect.isNotNull(data.id, 'Null is not a valid VM pid'); |
| 184 Expect.notEquals(0, data.id, 'Invalid pid returned for VM'); | 184 Expect.notEquals(0, data.id, 'Invalid pid returned for VM'); |
| 185 Expect.isNotNull(data.port, 'Null is not a valid VM port'); | 185 Expect.isNotNull(data.port, 'Null is not a valid VM port'); |
| 186 Expect.notEquals(0, data.port, 'Invalid port returned for VM'); | 186 Expect.notEquals(0, data.port, 'Invalid port returned for VM'); |
| 187 // This will not work on Windows, since the ProcessSignal argument | 187 // This will not work on Windows, since the ProcessSignal argument |
| 188 // is ignored and the fletch-vm is killed. | 188 // is ignored and the dartino-vm is killed. |
| 189 Expect.isTrue(await checkVmState(data.id, true), 'Fletch vm not running'); | 189 Expect.isTrue(await checkVmState(data.id, true), 'Dartino vm not running')
; |
| 190 print('Started 1. VM with id ${data.id} on port ${data.port}.'); | 190 print('Started 1. VM with id ${data.id} on port ${data.port}.'); |
| 191 }); | 191 }); |
| 192 | 192 |
| 193 // Stop the spawned vm. | 193 // Stop the spawned vm. |
| 194 await withConnection((AgentConnection connection) async { | 194 await withConnection((AgentConnection connection) async { |
| 195 await connection.stopVm(data.id); | 195 await connection.stopVm(data.id); |
| 196 Expect.isFalse(await checkVmState(data.id, false), | 196 Expect.isFalse(await checkVmState(data.id, false), |
| 197 'Fletch vm still running'); | 197 'Dartino vm still running'); |
| 198 print('Stopped VM with id ${data.id} on port ${data.port}.'); | 198 print('Stopped VM with id ${data.id} on port ${data.port}.'); |
| 199 }); | 199 }); |
| 200 | 200 |
| 201 // Start a new vm. | 201 // Start a new vm. |
| 202 await withConnection((AgentConnection connection) async { | 202 await withConnection((AgentConnection connection) async { |
| 203 data = await connection.startVm(); | 203 data = await connection.startVm(); |
| 204 Expect.isNotNull(data, 'Failed to spawn new fletch VM'); | 204 Expect.isNotNull(data, 'Failed to spawn new dartino VM'); |
| 205 Expect.isNotNull(data.id, 'Null is not a valid VM pid'); | 205 Expect.isNotNull(data.id, 'Null is not a valid VM pid'); |
| 206 Expect.notEquals(0, data.id, 'Invalid pid returned for VM'); | 206 Expect.notEquals(0, data.id, 'Invalid pid returned for VM'); |
| 207 Expect.isNotNull(data.port, 'Null is not a valid VM port'); | 207 Expect.isNotNull(data.port, 'Null is not a valid VM port'); |
| 208 Expect.notEquals(0, data.port, 'Invalid port returned for VM'); | 208 Expect.notEquals(0, data.port, 'Invalid port returned for VM'); |
| 209 // This will not work on Windows, since the ProcessSignal argument | 209 // This will not work on Windows, since the ProcessSignal argument |
| 210 // is ignored and the fletch-vm is killed. | 210 // is ignored and the dartino-vm is killed. |
| 211 Expect.isTrue(await checkVmState(data.id, true), 'Fletch vm not running'); | 211 Expect.isTrue(await checkVmState(data.id, true), 'Dartino vm not running')
; |
| 212 print('Started 2. VM with id ${data.id} on port ${data.port}.'); | 212 print('Started 2. VM with id ${data.id} on port ${data.port}.'); |
| 213 }); | 213 }); |
| 214 | 214 |
| 215 // Kill the spawned vm using a signal. | 215 // Kill the spawned vm using a signal. |
| 216 await withConnection((AgentConnection connection) async { | 216 await withConnection((AgentConnection connection) async { |
| 217 await connection.signalVm(data.id, SIGINT); | 217 await connection.signalVm(data.id, SIGINT); |
| 218 Expect.isFalse(await checkVmState(data.id, false), | 218 Expect.isFalse(await checkVmState(data.id, false), |
| 219 'Fletch vm still running'); | 219 'Dartino vm still running'); |
| 220 print('Killed VM with id ${data.id} on port ${data.port}.'); | 220 print('Killed VM with id ${data.id} on port ${data.port}.'); |
| 221 }); | 221 }); |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 /// The AgentUpgrade test sends over mock binary data (as List<int> data), | 225 /// The AgentUpgrade test sends over mock binary data (as List<int> data), |
| 226 /// representing the new agent package that should be used to upgrade the | 226 /// representing the new agent package that should be used to upgrade the |
| 227 /// agent. | 227 /// agent. |
| 228 /// When running the test we start the fletch agent with AGENT_UPGRADE_DRY_RUN | 228 /// When running the test we start the dartino agent with AGENT_UPGRADE_DRY_RUN |
| 229 /// set so it won't actually do the dpkg. This allows us to test that the | 229 /// set so it won't actually do the dpkg. This allows us to test that the |
| 230 /// fletch agent correctly receives the mock data and writes it into the temp | 230 /// dartino agent correctly receives the mock data and writes it into the temp |
| 231 /// package file. | 231 /// package file. |
| 232 class AgentUpgradeProtocolTest extends AgentTest { | 232 class AgentUpgradeProtocolTest extends AgentTest { |
| 233 AgentUpgradeProtocolTest() : super('testAgentUpgrade', 20001); | 233 AgentUpgradeProtocolTest() : super('testAgentUpgrade', 20001); |
| 234 | 234 |
| 235 Future<Null> execute() async { | 235 Future<Null> execute() async { |
| 236 await withConnection((AgentConnection connection) async { | 236 await withConnection((AgentConnection connection) async { |
| 237 List<int> data = [72, 69, 76, 76, 79, 10]; | 237 List<int> data = [72, 69, 76, 76, 79, 10]; |
| 238 await connection.upgradeAgent('1-test', data); | 238 await connection.upgradeAgent('1-test', data); |
| 239 List<int> readData = | 239 List<int> readData = |
| 240 await retry(100, () => new File(PACKAGE_FILE_NAME).readAsBytes()); | 240 await retry(100, () => new File(PACKAGE_FILE_NAME).readAsBytes()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 Future<bool> checkVmState(int vmId, bool expectRunning) { | 286 Future<bool> checkVmState(int vmId, bool expectRunning) { |
| 287 return retry(-1, () { | 287 return retry(-1, () { |
| 288 bool running = Process.killPid(vmId, ProcessSignal.SIGCONT); | 288 bool running = Process.killPid(vmId, ProcessSignal.SIGCONT); |
| 289 if (expectRunning != running) { | 289 if (expectRunning != running) { |
| 290 throw new Exception( | 290 throw new Exception( |
| 291 'Vm with id $vmId not' + (expectRunning ? 'running' : 'stopped')); | 291 'Vm with id $vmId not' + (expectRunning ? 'running' : 'stopped')); |
| 292 } | 292 } |
| 293 return running; | 293 return running; |
| 294 }); | 294 }); |
| 295 } | 295 } |
| OLD | NEW |