Skip to content

Commit 77d21b8

Browse files
jensjohaCommit Queue
authored and
Commit Queue
committed
[frontend-server] flutter frontend try bot don't save to actual file
The test compiles a file, serializes it to disk, loads it from disk and verifies it. There's more than 1500 compiles and they (at least some) are up to something like 40 MB each meaning why might write something like 60 GB (!) running this test. As the data is only used in-process we can use `IOOverrides` to bybass it actually saving to a file. Change-Id: I4130d02c227ba6769d63482a499846a485aa5a3a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322702 Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 7f82667 commit 77d21b8

File tree

1 file changed

+85
-6
lines changed

1 file changed

+85
-6
lines changed

pkg/frontend_server/test/frontend_server_flutter.dart

+85-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE.md file.
44

5-
import 'dart:async' show StreamController;
6-
import 'dart:convert' show utf8, LineSplitter;
7-
import 'dart:io' show Directory, File, FileSystemEntity, IOSink, exitCode;
5+
import 'dart:async' show StreamController, Zone;
6+
import 'dart:convert' show Encoding, LineSplitter, utf8;
7+
import 'dart:io'
8+
show
9+
Directory,
10+
File,
11+
FileMode,
12+
FileSystemEntity,
13+
IOOverrides,
14+
IOSink,
15+
exitCode;
16+
import 'dart:typed_data' show BytesBuilder, Uint8List;
817

918
import 'package:front_end/src/api_prototype/language_version.dart'
1019
show uriUsesLegacyLanguageVersion;
@@ -277,8 +286,27 @@ Future<List<String>> attemptStuff(
277286
Iterator<File> testFileIterator = testFiles.iterator;
278287
testFileIterator.moveNext();
279288

280-
final Future<int> result =
281-
starter(args, input: inputStreamController.stream, output: ioSink);
289+
Zone parentZone = Zone.current;
290+
Map<String, _MockFile> files = {};
291+
292+
/// Each test writes a complete (modulo platform) dill, often taking around
293+
/// 40 MB. With 1,500+ tests thats easily 50+ GB data to write. We don't
294+
/// really need it as an actual file though, we just need to get a hold on it
295+
/// below so we can run verification on it. We thus use [IOOverrides] to
296+
/// "catch" dill files (`new File("whatnot.dill")`) so we can write those to
297+
/// memory instead of to actual files.
298+
/// This is specialized for how it's actually written in the production code
299+
/// (via `openWrite`) and will fail if that changes (at which point it will
300+
/// have to be updated).
301+
final Future<int> result = IOOverrides.runZoned(() {
302+
return starter(args, input: inputStreamController.stream, output: ioSink);
303+
}, createFile: (String path) {
304+
if (files[path] != null) return files[path]!;
305+
File f = parentZone.run(() => File(path));
306+
if (path.endsWith(".dill")) return files[path] = _MockFile(f);
307+
return f;
308+
});
309+
282310
String testName =
283311
testFileIterator.current.path.substring(flutterDirectory.path.length);
284312

@@ -304,7 +332,7 @@ Future<List<String>> attemptStuff(
304332
logger.logUnexpectedResult(testName);
305333
}
306334
if (!error) {
307-
List<int> resultBytes = dillFile.readAsBytesSync();
335+
Uint8List resultBytes = files[dillFile.path]!.writeSink!.bb.takeBytes();
308336
Component component = loadComponentFromBytes(platformData);
309337
component = loadComponentFromBytes(resultBytes, component);
310338
verifyComponent(
@@ -318,6 +346,8 @@ Future<List<String>> attemptStuff(
318346
logger
319347
.log(" => verified in ${stopwatch2.elapsedMilliseconds} ms.");
320348
}
349+
350+
files.clear();
321351
stopwatch2.reset();
322352

323353
inputStreamController.add('accept\n'.codeUnits);
@@ -483,3 +513,52 @@ class StdoutLogger extends Logger {
483513
print(s);
484514
}
485515
}
516+
517+
class _MockFile implements File {
518+
final File _f;
519+
_MockIOSink? writeSink;
520+
521+
_MockFile(this._f);
522+
523+
@override
524+
bool existsSync() {
525+
return _f.existsSync();
526+
}
527+
528+
@override
529+
Uint8List readAsBytesSync() {
530+
return _f.readAsBytesSync();
531+
}
532+
533+
@override
534+
IOSink openWrite({FileMode mode = FileMode.write, Encoding encoding = utf8}) {
535+
return writeSink = _MockIOSink();
536+
}
537+
538+
@override
539+
dynamic noSuchMethod(Invocation invocation) {
540+
return super.noSuchMethod(invocation);
541+
}
542+
}
543+
544+
class _MockIOSink implements IOSink {
545+
BytesBuilder bb = BytesBuilder();
546+
bool _closed = false;
547+
548+
@override
549+
void add(List<int> data) {
550+
if (_closed) throw "Adding to closed";
551+
bb.add(data);
552+
}
553+
554+
@override
555+
Future close() {
556+
_closed = true;
557+
return Future.value();
558+
}
559+
560+
@override
561+
dynamic noSuchMethod(Invocation invocation) {
562+
return super.noSuchMethod(invocation);
563+
}
564+
}

0 commit comments

Comments
 (0)