Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4199)

Unified Diff: mojo/dart/observatory_tester/tester.dart

Issue 1191253005: Add Observatory mojo_shell hearbeat test (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/dart/observatory_tester/runner.py ('k') | mojo/tools/get_test_list.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/dart/observatory_tester/tester.dart
diff --git a/mojo/dart/observatory_tester/tester.dart b/mojo/dart/observatory_tester/tester.dart
new file mode 100644
index 0000000000000000000000000000000000000000..28a3ddd57b8fd2cb9578eb9b0fded400bbfd3ade
--- /dev/null
+++ b/mojo/dart/observatory_tester/tester.dart
@@ -0,0 +1,187 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library observatory_tester;
+
+// Minimal dependency Observatory heartbeat test.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+class Expect {
+ static equals(a, b) {
+ if (a != b) {
+ throw 'Expected $a == $b';
+ }
+ }
+
+ static isMap(a) {
+ if (a is! Map) {
+ throw 'Expected $a to be a Map';
+ }
+ }
+
+ static notExecuted() {
+ throw 'Should not have hit';
+ }
+
+ static isNotNull(a) {
+ if (a == null) {
+ throw 'Expected $a to not be null.';
+ }
+ }
+}
+
+class Launch {
+ Launch(this.executable, this.arguments, this.process, this.port) {
+ _killRequested = false;
+ this.process.exitCode.then(_checkKill);
+ }
+
+ void kill() {
+ _killRequested = true;
+ process.kill();
+ }
+
+ void _checkKill(int exitCode) {
+ if (!_killRequested) {
+ throw 'Unexpected exit of testee. (exitCode = $exitCode)';
+ }
+ }
+
+ final String executable;
+ final String arguments;
+ final Process process;
+ final int port;
+ bool _killRequested;
+}
+
+class Launcher {
+ /// Launch [executable] with [arguments]. Returns a future to a [Launch]
+ /// which includes the process and port where Observatory is running.
+ static Future<Launch> launch(String executable,
+ List<String> arguments) async {
+ var process = await Process.start(executable, arguments);
+
+ // Completer completes once 'Observatory listening on' message has been
+ // scraped and we know the port number.
+ var completer = new Completer();
+
+ process.stdout.transform(UTF8.decoder)
+ .transform(new LineSplitter()).listen((line) {
+ if (line.startsWith('Observatory listening on http://')) {
+ RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)");
+ var port = portExp.firstMatch(line).group(1);
+ var portNumber = int.parse(port);
+ completer.complete(portNumber);
+ } else {
+ print(line);
+ }
+ });
+
+ process.stderr.transform(UTF8.decoder)
+ .transform(new LineSplitter()).listen((line) {
+ print(line);
+ });
+
+ var port = await completer.future;
+ return new Launch(executable, arguments, process, port);
+ }
+}
+
+class ServiceHelper {
+ ServiceHelper(this.client) {
+ client.listen(_onData,
+ onError: _onError,
+ cancelOnError: true);
+ }
+
+ Future<Map> invokeRPC(String method, [Map params]) async {
+ var key = _createKey();
+ var request = JSON.encode({
+ 'jsonrpc': '2.0',
+ 'method': method,
+ 'params': params == null ? {} : params,
+ 'id': key,
+ });
+ client.add(request);
+ var completer = new Completer();
+ _outstanding_requests[key] = completer;
+ print('-> $key ($method)');
+ return completer.future;
+ }
+
+ String _createKey() {
+ var key = '$_id';
+ _id++;
+ return key;
+ }
+
+ void _onData(String message) {
+ var response = JSON.decode(message);
+ var key = response['id'];
+ print('<- $key');
+ var completer = _outstanding_requests.remove(key);
+ assert(completer != null);
+ var result = response['result'];
+ var error = response['error'];
+ if (error != null) {
+ assert(result == null);
+ completer.completeError(error);
+ } else {
+ assert(result != null);
+ completer.complete(result);
+ }
+ }
+
+ void _onError(error) {
+ print('WebSocket error: $error');
+ }
+
+ final WebSocket client;
+ final Map<String, Completer> _outstanding_requests = <String, Completer>{};
+ var _id = 1;
+}
+
+main(List<String> args) async {
+ var executable = args[0];
+ var arguments = args.sublist(1);
+
+ print('Launching $executable with $arguments');
+
+ var launch = await Launcher.launch(executable, arguments);
+
+ print('Observatory is on port ${launch.port}');
+ var serviceUrl = 'ws://127.0.0.1:${launch.port}/ws';
+
+ var client = await WebSocket.connect(serviceUrl);
+ print('Connected to $serviceUrl');
+
+ var helper = new ServiceHelper(client);
+
+ // Invoke getVM RPC. Verify a valid repsonse.
+ var vm = await helper.invokeRPC('getVM');
+ Expect.equals(vm['type'], 'VM');
+
+ // Invoke a bogus RPC. Expect an error.
+ bool errorCaught = false;
+ try {
+ var bad = await helper.invokeRPC('BARTSIMPSON');
+ Expect.notExecuted();
+ } catch (e) {
+ errorCaught = true;
+ // Map.
+ Expect.isMap(e);
+ // Has an error code.
+ Expect.isNotNull(e['code']);
+ }
+ Expect.equals(errorCaught, true);
+
+ await client.close();
+ print('Closed connection');
+
+ print('Finished.');
+ launch.kill();
+}
« no previous file with comments | « mojo/dart/observatory_tester/runner.py ('k') | mojo/tools/get_test_list.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698