[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.
This commit is contained in:
parent
15913e5d73
commit
2a7ee930c3
@ -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(),
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user