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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 library http_server; 5 library http_server;
6 6
7 import 'dart:io'; 7 import 'dart:io';
8 import 'dart:isolate'; 8 import 'dart:isolate';
9 import 'test_suite.dart'; // For TestUtils. 9 import 'test_suite.dart'; // For TestUtils.
10 // TODO(efortuna): Rewrite to not use the args library and simply take an 10 // TODO(efortuna): Rewrite to not use the args library and simply take an
11 // expected number of arguments, so test.dart doesn't rely on the args library? 11 // expected number of arguments, so test.dart doesn't rely on the args library?
12 // See discussion on https://codereview.chromium.org/11931025/. 12 // See discussion on https://codereview.chromium.org/11931025/.
13 import 'vendored_pkg/args/args.dart'; 13 import 'vendored_pkg/args/args.dart';
14 import 'utils.dart';
15
16 const PREFIX_BUILDDIR = 'root_build';
ricow1 2013/02/12 07:14:04 how about putting these in the utils class, we use
Emily Fortuna 2013/02/12 18:04:09 I know you have an explanation for how these are u
kustermann 2013/02/15 08:00:30 I'm not sure what we should do. Here's my reasonin
kustermann 2013/02/15 08:00:30 Good idea. Done.
17 const PREFIX_DARTDIR = 'root_dart';
14 18
15 main() { 19 main() {
16 /** Convenience method for local testing. */ 20 /** Convenience method for local testing. */
17 var parser = new ArgParser(); 21 var parser = new ArgParser();
18 parser.addOption('port', abbr: 'p', 22 parser.addOption('port', abbr: 'p',
19 help: 'The main server port we wish to respond to requests.', 23 help: 'The main server port we wish to respond to requests.',
20 defaultsTo: '0'); 24 defaultsTo: '0');
21 parser.addOption('crossOriginPort', abbr: 'c', 25 parser.addOption('crossOriginPort', abbr: 'c',
22 help: 'A different port that accepts request from the main server port.', 26 help: 'A different port that accepts request from the main server port.',
23 defaultsTo: '0'); 27 defaultsTo: '0');
24 parser.addOption('mode', abbr: 'm', help: 'Testing mode.', 28 parser.addOption('mode', abbr: 'm', help: 'Testing mode.',
25 defaultsTo: 'release'); 29 defaultsTo: 'release');
26 parser.addOption('arch', abbr: 'a', help: 'Testing architecture.', 30 parser.addOption('arch', abbr: 'a', help: 'Testing architecture.',
27 defaultsTo: 'ia32'); 31 defaultsTo: 'ia32');
28 parser.addFlag('help', abbr: 'h', negatable: false, 32 parser.addFlag('help', abbr: 'h', negatable: false,
29 help: 'Print this usage information.'); 33 help: 'Print this usage information.');
30 parser.addOption('package-root', help: 'The package root to use.'); 34 parser.addOption('package-root', help: 'The package root to use.');
31 var args = parser.parse(new Options().arguments); 35 var args = parser.parse(new Options().arguments);
32 if (args['help']) { 36 if (args['help']) {
33 print(parser.getUsage()); 37 print(parser.getUsage());
34 } else { 38 } else {
35 // Pretend we're running test.dart so that TestUtils doesn't get confused 39 // Pretend we're running test.dart so that TestUtils doesn't get confused
36 // about the "current directory." This is only used if we're trying to run 40 // about the "current directory." This is only used if we're trying to run
37 // this file independently for local testing. 41 // this file independently for local testing.
38 TestUtils.testScriptPath = new Path(new Options().script) 42 TestUtils.testScriptPath = new Path(new Options().script)
39 .directoryPath 43 .directoryPath
40 .join(new Path('../../test.dart')) 44 .join(new Path('../../test.dart'))
41 .canonicalize() 45 .canonicalize()
42 .toNativePath(); 46 .toNativePath();
47 // Note: args['package-root'] is always the build directory. We have the
48 // implicit assumption that it contains the 'packages' subdirectory.
49 // TODO: We should probably rename 'package-root' to 'build-directory'.
43 TestingServerRunner._packageRootDir = new Path(args['package-root']); 50 TestingServerRunner._packageRootDir = new Path(args['package-root']);
51 TestingServerRunner._buildDirectory = new Path(args['package-root']);
44 TestingServerRunner.startHttpServer('127.0.0.1', 52 TestingServerRunner.startHttpServer('127.0.0.1',
45 port: int.parse(args['port'])); 53 port: int.parse(args['port']));
46 print('Server listening on port ' 54 print('Server listening on port '
47 '${TestingServerRunner.serverList[0].port}.'); 55 '${TestingServerRunner.serverList[0].port}.');
48 TestingServerRunner.startHttpServer('127.0.0.1', 56 TestingServerRunner.startHttpServer('127.0.0.1',
49 allowedPort: TestingServerRunner.serverList[0].port, port: 57 allowedPort: TestingServerRunner.serverList[0].port, port:
50 int.parse(args['crossOriginPort'])); 58 int.parse(args['crossOriginPort']));
51 print( 59 print(
52 'Server listening on port ${TestingServerRunner.serverList[1].port}.'); 60 'Server listening on port ${TestingServerRunner.serverList[1].port}.');
53 } 61 }
54 } 62 }
55 /** 63 /**
56 * Runs a set of servers that are initialized specifically for the needs of our 64 * Runs a set of servers that are initialized specifically for the needs of our
57 * test framework, such as dealing with package-root. 65 * test framework, such as dealing with package-root.
58 */ 66 */
59 class TestingServerRunner { 67 class TestingServerRunner {
60 static List serverList = []; 68 static List serverList = [];
61 static Path _packageRootDir = null; 69 static Path _packageRootDir = null;
70 static Path _buildDirectory = null;
62 71
63 // Added as a getter so that the function will be called again each time the 72 // Added as a getter so that the function will be called again each time the
64 // default request handler closure is executed. 73 // default request handler closure is executed.
65 static Path get packageRootDir => _packageRootDir; 74 static Path get packageRootDir => _packageRootDir;
75 static Path get buildDirectory => _buildDirectory;
66 76
67 static setPackageRootDir(Map configuration) { 77 static setPackageRootDir(Map configuration) {
68 _packageRootDir = TestUtils.currentWorkingDirectory.join( 78 _packageRootDir = TestUtils.absolutePath(
79 new Path(TestUtils.buildDir(configuration)));
80 }
81
82 static setBuildDir(Map configuration) {
83 _buildDirectory = TestUtils.absolutePath(
69 new Path(TestUtils.buildDir(configuration))); 84 new Path(TestUtils.buildDir(configuration)));
70 } 85 }
71 86
72 static startHttpServer(String host, {int allowedPort:-1, int port: 0}) { 87 static startHttpServer(String host, {int allowedPort:-1, int port: 0}) {
73 var basePath = TestUtils.dartDir();
74 var httpServer = new HttpServer(); 88 var httpServer = new HttpServer();
75 var packagesDirName = 'packages';
76 httpServer.onError = (e) { 89 httpServer.onError = (e) {
77 // TODO(ricow): Once we have a debug log we should write this out there. 90 DebugLogger.error('HttpServer: an error occured: $e');
78 print('Test http server error: $e');
79 }; 91 };
80 httpServer.defaultRequestHandler = (request, resp) { 92 httpServer.defaultRequestHandler = (request, resp) {
81 var requestPath = new Path(request.path.substring(1)).canonicalize(); 93 void respondWithNotFound() {
82 var path = basePath.join(requestPath); 94 // NOTE: Since some tests deliberately try to access non-existent files.
83 var file = new File(path.toNativePath()); 95 // We might want to remove this warning (otherwise it will show
84 96 // up in the debug.log every time).
85 if (requestPath.segments().contains(packagesDirName)) { 97 DebugLogger.warning('HttpServer: could not find file for request path: '
86 // Essentially implement the packages path rewriting, so we don't have 98 '"${request.path}"');
87 // to pass environment variables to the browsers. 99 resp.statusCode = HttpStatus.NOT_FOUND;
88 var requestPathStr = requestPath.toNativePath().substring( 100 try {
89 requestPath.toNativePath().indexOf(packagesDirName)); 101 resp.outputStream.close();
90 path = packageRootDir.append(requestPathStr); 102 } catch (e) {
91 file = new File(path.toNativePath()); 103 if (e is StreamException) {
92 } 104 DebugLogger.warning('HttpServer: error while closing the response '
93 file.exists().then((exists) { 105 'stream: $e');
94 if (exists) {
95 if (allowedPort != -1) {
96 // Allow loading from localhost:$allowedPort in browsers.
97 resp.headers.set("Access-Control-Allow-Origin",
98 "http://127.0.0.1:$allowedPort");
99 resp.headers.set('Access-Control-Allow-Credentials', 'true');
100 } else { 106 } else {
101 // No allowedPort specified. Allow from anywhere (but cross-origin 107 throw e;
102 // requests *with credentials* will fail because you can't use "*").
103 resp.headers.set("Access-Control-Allow-Origin", "*");
104 }
105 if (path.toNativePath().endsWith('.html')) {
106 resp.headers.set('Content-Type', 'text/html');
107 } else if (path.toNativePath().endsWith('.js')) {
108 resp.headers.set('Content-Type', 'application/javascript');
109 } else if (path.toNativePath().endsWith('.dart')) {
110 resp.headers.set('Content-Type', 'application/dart');
111 }
112 file.openInputStream().pipe(resp.outputStream);
113 } else {
114 resp.statusCode = HttpStatus.NOT_FOUND;
115 try {
116 resp.outputStream.close();
117 } catch (e) {
118 if (e is StreamException) {
119 print('Test http_server error closing the response stream: $e');
120 } else {
121 throw e;
122 }
123 } 108 }
124 } 109 }
125 }); 110 }
111
112 void respondWithFileContent(Path path, File file) {
113 if (allowedPort != -1) {
114 // Allow loading from localhost:$allowedPort in browsers.
115 resp.headers.set("Access-Control-Allow-Origin",
116 "http://127.0.0.1:$allowedPort");
117 resp.headers.set('Access-Control-Allow-Credentials', 'true');
118 } else {
119 // No allowedPort specified. Allow from anywhere (but cross-origin
120 // requests *with credentials* will fail because you can't use "*").
121 resp.headers.set("Access-Control-Allow-Origin", "*");
122 }
123 if (path.filename.endsWith('.html')) {
124 resp.headers.set('Content-Type', 'text/html');
125 } else if (path.filename.endsWith('.js')) {
126 resp.headers.set('Content-Type', 'application/javascript');
127 } else if (path.filename.endsWith('.dart')) {
128 resp.headers.set('Content-Type', 'application/dart');
129 }
130 file.openInputStream().pipe(resp.outputStream);
131 }
132
133 Path getFilePathFromRequestPath(String urlRequestPath) {
ricow1 2013/02/12 07:14:04 could we just move this and the other functions ou
kustermann 2013/02/15 08:00:30 Done.
134 // TODO(kustermann,ricow): We could change this to the following scheme:
135 // http://host:port/root_packages/X -> $BuildDir/packages/X
136 // Issue: 8368
137
138 // NOTE: files from the dart and from the build directory are served as
ricow1 2013/02/12 07:14:04 from the dart -> from the dart repository
kustermann 2013/02/15 08:00:30 Done.
139 // follows:
140 // http://host:port/$PREFIX_DARTDIR/X -> $DartDir/X
141 // http://host:port/$PREFIX_BUILDDIR/X -> $BuildDir/X
142
143 var requestPath = new Path(urlRequestPath.substring(1)).canonicalize();
144 var pathSegments = requestPath.segments();
145 if (pathSegments.length > 1) {
ricow1 2013/02/12 07:14:04 using segments here seems like a lot of work, why
Emily Fortuna 2013/02/12 18:04:09 Also, consider using the relativeTo function from
kustermann 2013/02/15 08:00:30 a) segments was used in the old code as well ('req
kustermann 2013/02/15 08:00:30 a) I don't like using vendored_pkg: the less thing
146 var basePath;
147 var relativePath;
148 if (pathSegments[0] == PREFIX_BUILDDIR) {
149 basePath = _buildDirectory;
150 relativePath = new Path(
151 pathSegments.getRange(1, pathSegments.length - 1).join('/'));
152 } else if (pathSegments[0] == PREFIX_DARTDIR) {
153 basePath = TestUtils.dartDir();
154 relativePath = new Path(
155 pathSegments.getRange(1, pathSegments.length - 1).join('/'));
156 }
157 var packagesDirName = 'packages';
158 var packagesIndex = pathSegments.indexOf(packagesDirName);
159 if (packagesIndex != -1 && packagesIndex < pathSegments.length - 1) {
160 var start = packagesIndex + 1;
161 var length = pathSegments.length - start;
162 basePath = _packageRootDir.append(packagesDirName);
163 relativePath = new Path(
164 pathSegments.getRange(start, length).join('/'));
165 }
166 if (basePath != null && relativePath != null) {
167 return basePath.join(relativePath);
168 }
169 }
170 return null;
171 }
172
173 var path = getFilePathFromRequestPath(request.path);
174 if (path != null) {
175 var file = new File.fromPath(path);
176 file.exists().then((exists) {
177 if (exists) {
178 respondWithFileContent(path, file);
179 } else {
180 respondWithNotFound();
181 }
182 });
183 } else {
184 respondWithNotFound();
185 }
126 }; 186 };
127 187
128 // Echos back the contents of the request as the response data. 188 // Echos back the contents of the request as the response data.
129 httpServer.addRequestHandler((req) => req.path == "/echo", (request, resp) { 189 httpServer.addRequestHandler((req) => req.path == "/echo", (request, resp) {
130 resp.headers.set("Access-Control-Allow-Origin", "*"); 190 resp.headers.set("Access-Control-Allow-Origin", "*");
131 191
132 request.inputStream.pipe(resp.outputStream); 192 request.inputStream.pipe(resp.outputStream);
133 }); 193 });
134 194
135 httpServer.listen(host, port); 195 httpServer.listen(host, port);
136 serverList.add(httpServer); 196 serverList.add(httpServer);
137 } 197 }
138 198
139 static terminateHttpServers() { 199 static terminateHttpServers() {
140 for (var server in serverList) server.close(); 200 for (var server in serverList) server.close();
141 } 201 }
142 } 202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698