blob: 52d1983c44174b40adfd661e06568baae640d296 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library vmservice_test_helper;
import 'dart:async';
import 'dart:io';
import 'dart:json' as JSON;
import 'dart:utf' as UTF;
import 'package:expect/expect.dart';
abstract class VmServiceRequestHelper {
final Uri uri;
final HttpClient client;
VmServiceRequestHelper(String url) :
uri = Uri.parse(url),
client = new HttpClient();
Future makeRequest() {
return client.getUrl(uri)
.then((HttpClientRequest request) => request.close())
.then((HttpClientResponse response) {
return response
.fold(new BytesBuilder(), (b, d) => b..add(d))
.then((builder) {
_requestCompleted(builder.takeBytes(), response);
});
}).catchError((error) {
onRequestFailed(error);
});
}
void _requestCompleted(List<int> data, HttpClientResponse response) {
Expect.equals(200, response.statusCode, 'Invalid HTTP Status Code');
var replyAsString;
try {
replyAsString = UTF.decodeUtf8(data, 0, null, null);
} catch (e) {
onRequestFailed(e);
return;
}
var reply;
try {
reply = JSON.parse(replyAsString);
} catch (e) {
onRequestFailed(e);
return;
}
if (reply is! Map) {
onRequestFailed('Reply was not a map: $reply');
return;
}
if (reply['type'] == null) {
onRequestFailed('Reply does not contain a type key: $reply');
return;
}
try {
onRequestCompleted(reply);
} catch (e) {
onRequestFailed('Test callback failed: $e');
}
}
void onRequestFailed(dynamic error) {
Expect.fail('Failed to make request: $error');
}
void onRequestCompleted(Map response);
}
class TestLauncher {
final String script;
Process process;
TestLauncher(this.script);
String get scriptPath {
var dartScript = Platform.script;
var splitPoint = dartScript.lastIndexOf(Platform.pathSeparator);
var scriptDirectory = dartScript.substring(0, splitPoint);
return scriptDirectory + Platform.pathSeparator + script;
}
Future<int> launch() {
String dartExecutable = Platform.executable;
return Process.start(dartExecutable,
['--enable-vm-service:0', scriptPath]).then((p) {
Completer completer = new Completer();
process = p;
var portNumber;
var blank;
var first = true;
process.stdout.transform(new StringDecoder())
.transform(new LineTransformer()).listen((line) {
if (line.startsWith('VmService listening on port ')) {
RegExp portExp = new RegExp(r"\d+");
var port = portExp.stringMatch(line);
portNumber = int.parse(port);
}
if (line == '') {
// Received blank line.
blank = true;
}
if (portNumber != null && blank == true && first == true) {
completer.complete(portNumber);
// Stop repeat completions.
first = false;
}
});
process.stderr.transform(new StringDecoder())
.transform(new LineTransformer()).listen((line) {
});
process.exitCode.then((_) { });
return completer.future;
});
}
void requestExit() {
process.stdin.add([32]);
}
}
class IsolateListTester {
final Map isolateList;
IsolateListTester(this.isolateList) {
// The reply is an IsolateList.
Expect.equals('IsolateList', isolateList['type'], 'Not an IsolateList.');
}
void checkIsolateCount(int n) {
Expect.equals(n, isolateList['members'].length, 'Isolate count not $n');
}
void checkIsolateIdExists(int id) {
var exists = false;
isolateList['members'].forEach((isolate) {
if (isolate['id'] == id) {
exists = true;
}
});
Expect.isTrue(exists, 'No isolate with id: $id');
}
void checkIsolateNameContains(String name) {
var exists = false;
isolateList['members'].forEach((isolate) {
if (isolate['name'].contains(name)) {
exists = true;
}
});
Expect.isTrue(exists, 'No isolate with name: $name');
}
void checkIsolateNamePrefix(int id, String name) {
var exists = false;
isolateList['members'].forEach((isolate) {
if (isolate['id'] == id) {
exists = true;
Expect.isTrue(isolate['name'].startsWith(name),
'Isolate $id does not have name prefix: $name'
' (was ${isolate['name']})');
}
});
Expect.isTrue(exists, 'No isolate with id: $id');
}
}