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

Unified Diff: tools/testing/dart/http_server.dart

Issue 12223074: Create generated tests inside the build directory (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 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 | « tools/testing/dart/browser_test.dart ('k') | tools/testing/dart/test_suite.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/testing/dart/http_server.dart
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 06b87da3960551c77cfe4386dad504c64c41d7e0..6ab495b7af70baa95076b66026ba5a2b75656377 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -4,6 +4,7 @@
library http_server;
+import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:uri';
@@ -12,6 +13,30 @@ import 'test_suite.dart'; // For TestUtils.
// expected number of arguments, so test.dart doesn't rely on the args library?
// See discussion on https://codereview.chromium.org/11931025/.
import 'vendored_pkg/args/args.dart';
+import 'utils.dart';
+
+
+/// Interface of the HTTP server:
+///
+/// /echo: This will stream the data received in the request stream back
+/// to the client.
+/// /root_dart/X: This will serve the corresponding file from the dart
+/// directory (i.e. '$DartDirectory/X').
+/// /root_build/X: This will serve the corresponding file from the build
+/// directory (i.e. '$BuildDirectory/X').
+/// /FOO/packages/BAR: This will serve the corresponding file from the packages
+/// directory (i.e. '$BuildDirectory/packages/BAR')
+///
+/// In case a path does not refer to a file but rather to a directory, a
+/// directory listing will be displayed.
+
+const PREFIX_BUILDDIR = 'root_build';
+const PREFIX_DARTDIR = 'root_dart';
+
+// TODO(kustermann,ricow): We could change this to the following scheme:
+// http://host:port/root_packages/X -> $BuildDir/packages/X
+// Issue: 8368
+
main() {
/** Convenience method for local testing. */
@@ -43,7 +68,11 @@ main() {
.join(new Path('../../test.dart'))
.canonicalize()
.toNativePath();
+ // Note: args['package-root'] is always the build directory. We have the
+ // implicit assumption that it contains the 'packages' subdirectory.
+ // TODO: We should probably rename 'package-root' to 'build-directory'.
TestingServerRunner._packageRootDir = new Path(args['package-root']);
+ TestingServerRunner._buildDirectory = new Path(args['package-root']);
var network = args['network'];
TestingServerRunner.startHttpServer(network,
port: int.parse(args['port']));
@@ -63,96 +92,127 @@ main() {
class TestingServerRunner {
static List serverList = [];
static Path _packageRootDir = null;
+ static Path _buildDirectory = null;
// Added as a getter so that the function will be called again each time the
// default request handler closure is executed.
static Path get packageRootDir => _packageRootDir;
+ static Path get buildDirectory => _buildDirectory;
static setPackageRootDir(Map configuration) {
- _packageRootDir = TestUtils.currentWorkingDirectory.join(
+ _packageRootDir = TestUtils.absolutePath(
+ new Path(TestUtils.buildDir(configuration)));
+ }
+
+ static setBuildDir(Map configuration) {
+ _buildDirectory = TestUtils.absolutePath(
new Path(TestUtils.buildDir(configuration)));
}
static startHttpServer(String host, {int allowedPort:-1, int port: 0}) {
- var basePath = TestUtils.dartDir();
var httpServer = new HttpServer();
- var packagesDirName = 'packages';
httpServer.onError = (e) {
- // TODO(ricow): Once we have a debug log we should write this out there.
- print('Test http server error: $e');
+ DebugLogger.error('HttpServer: an error occured: $e');
};
- httpServer.defaultRequestHandler = (request, resp) {
- var requestPath = new Path(request.path.substring(1)).canonicalize();
- var path = basePath.join(requestPath);
- var file = new File(path.toNativePath());
-
- if (requestPath.segments().contains(packagesDirName)) {
- // Essentially implement the packages path rewriting, so we don't have
- // to pass environment variables to the browsers.
- var requestPathStr = requestPath.toNativePath().substring(
- requestPath.toNativePath().indexOf(packagesDirName));
- path = packageRootDir.append(requestPathStr);
- file = new File(path.toNativePath());
- }
+ httpServer.defaultRequestHandler = (request, response) {
+ handleFileOrDirectoryRequest(request, response, allowedPort);
+ };
+ httpServer.addRequestHandler(
+ (req) => req.path == "/echo", handleEchoRequest);
+
+ httpServer.listen(host, port);
+ serverList.add(httpServer);
+ }
+
+
+ static void handleFileOrDirectoryRequest(HttpRequest request,
+ HttpResponse response,
+ int allowedPort) {
+ var path = getFilePathFromRequestPath(request.path);
+ if (path != null) {
+ var file = new File.fromPath(path);
file.exists().then((exists) {
if (exists) {
- if (allowedPort != -1) {
- if (request.headers.value('Origin') != null) {
- var origin = new Uri(request.headers.value('Origin'));
- // Allow loading from http://*:$allowedPort in browsers.
- var allowedOrigin =
- '${origin.scheme}://${origin.domain}:${allowedPort}';
- resp.headers.set("Access-Control-Allow-Origin", allowedOrigin);
- resp.headers.set('Access-Control-Allow-Credentials', 'true');
- }
- } else {
- // No allowedPort specified. Allow from anywhere (but cross-origin
- // requests *with credentials* will fail because you can't use "*").
- resp.headers.set("Access-Control-Allow-Origin", "*");
- }
- if (path.toNativePath().endsWith('.html')) {
- resp.headers.set('Content-Type', 'text/html');
- } else if (path.toNativePath().endsWith('.js')) {
- resp.headers.set('Content-Type', 'application/javascript');
- } else if (path.toNativePath().endsWith('.dart')) {
- resp.headers.set('Content-Type', 'application/dart');
- }
- file.openInputStream().pipe(resp.outputStream);
+ sendFileContent(request, response, allowedPort, path, file);
} else {
var directory = new Directory.fromPath(path);
directory.exists().then((exists) {
- if (!exists) {
- sendNotFound(resp);
+ if (exists) {
+ listDirectory(directory).then((entries) {
+ sendDirectoryListing(entries, request, response);
+ });
} else {
- sendDirectoryListing(directory, request, resp);
+ sendNotFound(request, response);
}
});
}
});
- };
-
- // Echos back the contents of the request as the response data.
- httpServer.addRequestHandler((req) => req.path == "/echo", (request, resp) {
- resp.headers.set("Access-Control-Allow-Origin", "*");
-
- request.inputStream.pipe(resp.outputStream);
- });
+ } else {
+ if (request.path == '/') {
+ var entries = [new _Entry('root_dart', 'root_dart/'),
+ new _Entry('root_build', 'root_build/'),
+ new _Entry('echo', 'echo')];
+ sendDirectoryListing(entries, request, response);
+ } else {
+ sendNotFound(request, response);
+ }
+ }
+ }
- httpServer.listen(host, port);
- serverList.add(httpServer);
+ static void handleEchoRequest(HttpRequest request, HttpResponse response) {
+ response.headers.set("Access-Control-Allow-Origin", "*");
+ request.inputStream.pipe(response.outputStream);
}
- static void sendNotFound(HttpResponse response) {
- response.statusCode = HttpStatus.NOT_FOUND;
- try {
- response.outputStream.close();
- } catch (e) {
- if (e is StreamException) {
- print('Test http_server error closing the response stream: $e');
- } else {
- throw e;
+ static Path getFilePathFromRequestPath(String urlRequestPath) {
+ // Go to the top of the file to see an explanation of the URL path scheme.
+ var requestPath = new Path(urlRequestPath.substring(1)).canonicalize();
+ var pathSegments = requestPath.segments();
+ if (pathSegments.length > 0) {
+ var basePath;
+ var relativePath;
+ if (pathSegments[0] == PREFIX_BUILDDIR) {
+ basePath = _buildDirectory;
+ relativePath = new Path(
+ pathSegments.getRange(1, pathSegments.length - 1).join('/'));
+ } else if (pathSegments[0] == PREFIX_DARTDIR) {
+ basePath = TestUtils.dartDir();
+ relativePath = new Path(
+ pathSegments.getRange(1, pathSegments.length - 1).join('/'));
+ }
+ var packagesDirName = 'packages';
+ var packagesIndex = pathSegments.indexOf(packagesDirName);
+ if (packagesIndex != -1) {
+ var start = packagesIndex + 1;
+ var length = pathSegments.length - start;
+ basePath = _packageRootDir.append(packagesDirName);
+ relativePath = new Path(
+ pathSegments.getRange(start, length).join('/'));
+ }
+ if (basePath != null && relativePath != null) {
+ return basePath.join(relativePath);
}
}
+ return null;
+ }
+
+ static Future<List<_Entry>> listDirectory(Directory directory) {
+ var completer = new Completer();
+ var entries = [];
+
+ directory.list()
+ ..onFile = (filepath) {
+ var filename = new Path(filepath).filename;
+ entries.add(new _Entry(filename, filename));
+ }
+ ..onDir = (dirpath) {
+ var filename = new Path(dirpath).filename;
+ entries.add(new _Entry(filename, '$filename/'));
+ }
+ ..onDone = (_) {
+ completer.complete(entries);
+ };
+ return completer.future;
}
/**
@@ -162,8 +222,9 @@ class TestingServerRunner {
* This is intended to make it easier to browse tests when manually running
* tests against this test server.
*/
- static void sendDirectoryListing(Directory directory, HttpRequest request,
- HttpResponse response) {
+ static void sendDirectoryListing(entries,
+ HttpRequest request,
+ HttpResponse response) {
response.headers.set('Content-Type', 'text/html');
var header = '''<!DOCTYPE html>
<html>
@@ -181,30 +242,62 @@ class TestingServerRunner {
</body>
</html>''';
- var entries = [];
- directory.list()
- ..onFile = (filepath) {
- var filename = new Path(filepath).filename;
- entries.add(new _Entry(filename, filename));
- }
- ..onDir = (dirpath) {
- var filename = new Path(dirpath).filename;
- entries.add(new _Entry(filename, '$filename/'));
+ entries.sort();
+ response.outputStream.writeString(header);
+ for (var entry in entries) {
+ response.outputStream.writeString(
+ '<li><a href="${new Path(request.path).append(entry.name)}">'
+ '${entry.displayName}</a></li>');
+ }
+ response.outputStream.writeString(footer);
+ response.outputStream.close();
+ }
+
+ static void sendFileContent(HttpRequest request,
+ HttpResponse response,
+ int allowedPort,
+ Path path,
+ File file) {
+ if (allowedPort != -1) {
+ var origin = new Uri(request.headers.value('Origin'));
+ // Allow loading from http://*:$allowedPort in browsers.
+ var allowedOrigin =
+ '${origin.scheme}://${origin.domain}:${allowedPort}';
+ response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
+ response.headers.set('Access-Control-Allow-Credentials', 'true');
+ } else {
+ // No allowedPort specified. Allow from anywhere (but cross-origin
+ // requests *with credentials* will fail because you can't use "*").
+ response.headers.set("Access-Control-Allow-Origin", "*");
+ }
+ if (path.filename.endsWith('.html')) {
+ response.headers.set('Content-Type', 'text/html');
+ } else if (path.filename.endsWith('.js')) {
+ response.headers.set('Content-Type', 'application/javascript');
+ } else if (path.filename.endsWith('.dart')) {
+ response.headers.set('Content-Type', 'application/dart');
+ }
+ file.openInputStream().pipe(response.outputStream);
+ }
+
+ static void sendNotFound(HttpRequest request, HttpResponse response) {
+ // NOTE: Since some tests deliberately try to access non-existent files.
+ // We might want to remove this warning (otherwise it will show
+ // up in the debug.log every time).
+ DebugLogger.warning('HttpServer: could not find file for request path: '
+ '"${request.path}"');
+ response.statusCode = HttpStatus.NOT_FOUND;
+ try {
+ response.outputStream.close();
+ } catch (e) {
+ if (e is StreamException) {
+ DebugLogger.warning('HttpServer: error while closing the response '
+ 'stream: $e');
+ } else {
+ throw e;
}
- ..onDone = (_) {
- var requestPath = new Path.raw(request.path);
- entries.sort();
-
- response.outputStream.writeString(header);
- for (var entry in entries) {
- response.outputStream.writeString(
- '<li><a href="${requestPath.append(entry.name)}">'
- '${entry.displayName}</a></li>');
- }
- response.outputStream.writeString(footer);
- response.outputStream.close();
- };
+ }
}
static terminateHttpServers() {
« no previous file with comments | « tools/testing/dart/browser_test.dart ('k') | tools/testing/dart/test_suite.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698