Unverified Commit 2a7ee930 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] Update WebAssetServer to avoid context, fix tests (#60224)

WebAssetServer could fail if some of the global statics it depended on were initialized in a different order. Fix this by removing globals.

Delete dwds startup test that needs to spawn a real server.
parent 15913e5d
......@@ -20,6 +20,7 @@ import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/net.dart';
import '../base/platform.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../bundle.dart';
......@@ -173,7 +174,13 @@ class WebAssetServer implements AssetReader {
// In release builds deploy a simpler proxy server.
if (buildMode != BuildMode.debug) {
final ReleaseAssetServer releaseAssetServer = ReleaseAssetServer(entrypoint);
final ReleaseAssetServer releaseAssetServer = ReleaseAssetServer(
entrypoint,
fileSystem: globals.fs,
platform: globals.platform,
flutterRoot: Cache.flutterRoot,
webBuildDirectory: getWebBuildDirectory(),
);
shelf.serveRequests(httpServer, releaseAssetServer.handle);
return server;
}
......@@ -817,17 +824,31 @@ class WebDevFS implements DevFS {
}
class ReleaseAssetServer {
ReleaseAssetServer(this.entrypoint);
ReleaseAssetServer(this.entrypoint, {
@required FileSystem fileSystem,
@required String webBuildDirectory,
@required String flutterRoot,
@required Platform platform,
}) : _fileSystem = fileSystem,
_platform = platform,
_flutterRoot = flutterRoot,
_webBuildDirectory = webBuildDirectory,
_fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform);
final Uri entrypoint;
final String _flutterRoot;
final String _webBuildDirectory;
final FileSystem _fileSystem;
final FileSystemUtils _fileSystemUtils;
final Platform _platform;
// Locations where source files, assets, or source maps may be located.
final List<Uri> _searchPaths = <Uri>[
globals.fs.directory(getWebBuildDirectory()).uri,
globals.fs.directory(Cache.flutterRoot).uri,
globals.fs.directory(Cache.flutterRoot).parent.uri,
globals.fs.currentDirectory.uri,
globals.fs.directory(globals.fsUtils.homeDirPath).uri,
List<Uri> _searchPaths() => <Uri>[
_fileSystem.directory(_webBuildDirectory).uri,
_fileSystem.directory(_flutterRoot).uri,
_fileSystem.directory(_flutterRoot).parent.uri,
_fileSystem.currentDirectory.uri,
_fileSystem.directory(_fileSystemUtils.homeDirPath).uri,
];
Future<shelf.Response> handle(shelf.Request request) async {
......@@ -835,10 +856,10 @@ class ReleaseAssetServer {
if (request.url.toString() == 'main.dart') {
fileUri = entrypoint;
} else {
for (final Uri uri in _searchPaths) {
for (final Uri uri in _searchPaths()) {
final Uri potential = uri.resolve(request.url.path);
if (potential == null || !globals.fs.isFileSync(
potential.toFilePath(windows: globals.platform.isWindows))) {
if (potential == null || !_fileSystem.isFileSync(
potential.toFilePath(windows: _platform.isWindows))) {
continue;
}
fileUri = potential;
......@@ -846,7 +867,7 @@ class ReleaseAssetServer {
}
}
if (fileUri != null) {
final File file = globals.fs.file(fileUri);
final File file = _fileSystem.file(fileUri);
final Uint8List bytes = file.readAsBytesSync();
// Fallback to "application/octet-stream" on null which
// makes no claims as to the structure of the data.
......@@ -857,7 +878,7 @@ class ReleaseAssetServer {
});
}
if (request.url.path == '') {
final File file = globals.fs.file(globals.fs.path.join(getWebBuildDirectory(), 'index.html'));
final File file = _fileSystem.file(_fileSystem.path.join(_webBuildDirectory, 'index.html'));
return shelf.Response.ok(file.readAsBytesSync(), headers: <String, String>{
'Content-Type': 'text/html',
});
......
......@@ -93,7 +93,9 @@ void main() {
setUp(() {
testbed = Testbed(setup: () {
globals.fs.file(globalPackagesPath).writeAsStringSync('\n');
globals.fs.file(globalPackagesPath)
..createSync(recursive: true)
..writeAsStringSync('\n');
globals.fs.file(globals.fs.path.join('build', 'app.dill'))
..createSync(recursive: true)
..writeAsStringSync('ABC');
......
......@@ -2,14 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:dwds/data/build_result.dart';
import 'package:dwds/dwds.dart';
import 'package:dwds/src/loaders/strategy.dart';
import 'package:dwds/src/readers/asset_reader.dart';
import 'package:dwds/src/services/expression_compiler.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
......@@ -18,7 +13,6 @@ import 'package:flutter_tools/src/build_runner/devfs_web.dart';
import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:logging/logging.dart';
import 'package:mockito/mockito.dart';
import 'package:package_config/package_config.dart';
import 'package:shelf/shelf.dart';
......@@ -531,46 +525,6 @@ void main() {
expect(uri, Uri.http('localhost:0', ''));
await webDevFS.destroy();
}));
test('Launches DWDS with the correct arguments', () => testbed.run(() async {
globals.fs.file('.packages').writeAsStringSync('\n');
final WebAssetServer server = await WebAssetServer.start(
null,
'any',
8123,
(String url) => null,
true,
BuildMode.debug,
true,
Uri.file('test.dart'),
null,
dwdsLauncher: ({
AssetReader assetReader,
Stream<BuildResult> buildResults,
ConnectionProvider chromeConnection,
bool enableDebugExtension,
bool enableDebugging,
ExpressionCompiler expressionCompiler,
String hostname,
LoadStrategy loadStrategy,
void Function(Level, String) logWriter,
bool serveDevTools,
UrlEncoder urlEncoder,
bool useSseForDebugProxy,
bool verbose,
}) async {
expect(serveDevTools, false);
expect(verbose, null);
expect(enableDebugging, true);
expect(enableDebugExtension, true);
expect(useSseForDebugProxy, true);
expect(hostname, 'any');
return MockDwds();
});
await server.dispose();
}));
}
class MockHttpServer extends Mock implements HttpServer {}
......
......@@ -10,7 +10,6 @@ import 'package:flutter_tools/src/build_runner/devfs_web.dart';
import 'package:shelf/shelf.dart';
import '../../src/common.dart';
import '../../src/context.dart';
const List<int> kTransparentImage = <int>[
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
......@@ -45,8 +44,13 @@ void main() {
..writeAsBytesSync(<int>[1, 2, 3]);
});
testUsingContext('release asset server serves correct mime type and content length for png', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
testWithoutContext('release asset server serves correct mime type and content length for png', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
fileSystem: fileSystem,
platform: platform,
flutterRoot: '/flutter',
webBuildDirectory: 'build/web',
);
fileSystem.file('build/web/assets/foo.png')
..createSync(recursive: true)
..writeAsBytesSync(kTransparentImage);
......@@ -57,14 +61,15 @@ void main() {
'Content-Type': 'image/png',
'content-length': '64',
});
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('release asset server serves correct mime type and content length for JavaScript', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
testWithoutContext('release asset server serves correct mime type and content length for JavaScript', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
fileSystem: fileSystem,
platform: platform,
flutterRoot: '/flutter',
webBuildDirectory: 'build/web',
);
fileSystem.file('build/web/assets/foo.js')
..createSync(recursive: true)
..writeAsStringSync('function main() {}');
......@@ -75,14 +80,15 @@ void main() {
'Content-Type': 'application/javascript',
'content-length': '18',
});
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('release asset server serves correct mime type and content length for html', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
testWithoutContext('release asset server serves correct mime type and content length for html', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
fileSystem: fileSystem,
platform: platform,
flutterRoot: '/flutter',
webBuildDirectory: 'build/web',
);
fileSystem.file('build/web/assets/foo.html')
..createSync(recursive: true)
..writeAsStringSync('<!doctype html><html></html>');
......@@ -93,14 +99,15 @@ void main() {
'Content-Type': 'text/html',
'content-length': '28',
});
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('release asset server serves content from flutter root', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
testWithoutContext('release asset server serves content from flutter root', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
fileSystem: fileSystem,
platform: platform,
flutterRoot: '/flutter',
webBuildDirectory: 'build/web',
);
fileSystem.file('flutter/bar.dart')
..createSync(recursive: true)
..writeAsStringSync('void main() { }');
......@@ -108,14 +115,15 @@ void main() {
.handle(Request('GET', Uri.parse('http://localhost:8080/flutter/bar.dart')));
expect(response.statusCode, HttpStatus.ok);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('release asset server serves content from project directory', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
testWithoutContext('release asset server serves content from project directory', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base,
fileSystem: fileSystem,
platform: platform,
flutterRoot: '/flutter',
webBuildDirectory: 'build/web',
);
fileSystem.file('bar.dart')
..createSync(recursive: true)
..writeAsStringSync('void main() { }');
......@@ -123,9 +131,5 @@ void main() {
.handle(Request('GET', Uri.parse('http://localhost:8080/bar.dart')));
expect(response.statusCode, HttpStatus.ok);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment