Unverified Commit acd68cf4 authored by Lau Ching Jun's avatar Lau Ching Jun Committed by GitHub

Fix compile expression in tests when precompiled dill files are used. (#84470)

parent 7773d0b0
......@@ -451,6 +451,15 @@ class FlutterPlatform extends PlatformPlugin {
String mainDart;
if (precompiledDillPath != null) {
mainDart = precompiledDillPath;
// When start paused is specified, it means that the user is likely
// running this with a debugger attached. Initialize the resident
// compiler in this case.
if (debuggingOptions.startPaused) {
compiler ??= TestCompiler(debuggingOptions.buildInfo, flutterProject, precompiledDillPath: precompiledDillPath);
final Uri testUri = globals.fs.file(testPath).uri;
// Trigger a compilation to initialize the resident compiler.
unawaited(compiler.compile(testUri));
}
} else if (precompiledDillFiles != null) {
mainDart = precompiledDillFiles[testPath];
} else {
......
......@@ -36,10 +36,14 @@ class TestCompiler {
/// extension.
///
/// [flutterProject] is the project for which we are running tests.
///
/// If [precompiledDillPath] is passed, it will be used to initialize the
/// compiler.
TestCompiler(
this.buildInfo,
this.flutterProject,
) : testFilePath = globals.fs.path.join(
{ String precompiledDillPath }
) : testFilePath = precompiledDillPath ?? globals.fs.path.join(
flutterProject.directory.path,
getBuildDirectory(),
'test_cache',
......@@ -47,7 +51,8 @@ class TestCompiler {
trackWidgetCreation: buildInfo.trackWidgetCreation,
dartDefines: buildInfo.dartDefines,
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
)) {
)),
shouldCopyDillFile = precompiledDillPath == null {
// Compiler maintains and updates single incremental dill file.
// Incremental compilation requests done for each test copy that file away
// for independent execution.
......@@ -66,6 +71,7 @@ class TestCompiler {
final FlutterProject flutterProject;
final BuildInfo buildInfo;
final String testFilePath;
final bool shouldCopyDillFile;
ResidentCompiler compiler;
......@@ -112,6 +118,8 @@ class TestCompiler {
platform: globals.platform,
testCompilation: true,
fileSystem: globals.fs,
fileSystemRoots: buildInfo.fileSystemRoots,
fileSystemScheme: buildInfo.fileSystemScheme,
);
return residentCompiler;
}
......@@ -140,7 +148,7 @@ class TestCompiler {
<Uri>[request.mainUri],
outputPath: outputDill.path,
packageConfig: buildInfo.packageConfig,
projectRootPath: flutterProject.directory.absolute.path,
projectRootPath: flutterProject?.directory?.absolute?.path,
fs: globals.fs,
);
final String outputPath = compilerOutput?.outputFilename;
......@@ -149,28 +157,32 @@ class TestCompiler {
// errors, pass [null] upwards to the consumer and shutdown the
// compiler to avoid reusing compiler that might have gotten into
// a weird state.
final String path = request.mainUri.toFilePath(windows: globals.platform.isWindows);
if (outputPath == null || compilerOutput.errorCount > 0) {
request.result.complete(null);
await _shutdown();
} else {
final File outputFile = globals.fs.file(outputPath);
final File kernelReadyToRun = await outputFile.copy('$path.dill');
final File testCache = globals.fs.file(testFilePath);
if (firstCompile || !testCache.existsSync() || (testCache.lengthSync() < outputFile.lengthSync())) {
// The idea is to keep the cache file up-to-date and include as
// much as possible in an effort to re-use as many packages as
// possible.
if (!testCache.parent.existsSync()) {
testCache.parent.createSync(recursive: true);
if (shouldCopyDillFile) {
final String path = request.mainUri.toFilePath(windows: globals.platform.isWindows);
final File outputFile = globals.fs.file(outputPath);
final File kernelReadyToRun = await outputFile.copy('$path.dill');
final File testCache = globals.fs.file(testFilePath);
if (firstCompile || !testCache.existsSync() || (testCache.lengthSync() < outputFile.lengthSync())) {
// The idea is to keep the cache file up-to-date and include as
// much as possible in an effort to re-use as many packages as
// possible.
if (!testCache.parent.existsSync()) {
testCache.parent.createSync(recursive: true);
}
await outputFile.copy(testFilePath);
}
await outputFile.copy(testFilePath);
request.result.complete(kernelReadyToRun.path);
} else {
request.result.complete(outputPath);
}
request.result.complete(kernelReadyToRun.path);
compiler.accept();
compiler.reset();
}
globals.printTrace('Compiling $path took ${compilerTime.elapsedMilliseconds}ms');
globals.printTrace('Compiling ${request.mainUri} took ${compilerTime.elapsedMilliseconds}ms');
// Only remove now when we finished processing the element
compilationQueue.removeAt(0);
}
......
......@@ -59,6 +59,23 @@ void main() {
Logger: () => BufferLogger.test(),
});
testUsingContext('TestCompiler does not try to cache the dill file when precompiled dill is passed', () async {
residentCompiler.compilerOutput = const CompilerOutput('abc.dill', 0, <Uri>[]);
final FakeTestCompiler testCompiler = FakeTestCompiler(
debugBuild,
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
residentCompiler,
precompiledDillPath: 'precompiled.dill',
);
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), 'abc.dill');
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => linuxPlatform,
ProcessManager: () => FakeProcessManager.any(),
Logger: () => BufferLogger.test(),
});
testUsingContext('TestCompiler reports null when a compile fails', () async {
residentCompiler.compilerOutput = const CompilerOutput('abc.dill', 1, <Uri>[]);
final FakeTestCompiler testCompiler = FakeTestCompiler(
......@@ -103,8 +120,10 @@ class FakeTestCompiler extends TestCompiler {
FakeTestCompiler(
BuildInfo buildInfo,
FlutterProject flutterProject,
this.residentCompiler,
) : super(buildInfo, flutterProject);
this.residentCompiler, {
String precompiledDillPath,
}
) : super(buildInfo, flutterProject, precompiledDillPath: precompiledDillPath);
final FakeResidentCompiler residentCompiler;
......
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