@@ -6,7 +6,9 @@ import 'dart:async';
66import 'dart:convert' ;
77import 'dart:io' ;
88import 'dart:math' as math;
9+ import 'dart:typed_data' ;
910
11+ import 'package:archive/archive.dart' ;
1012import 'package:file/file.dart' as fs;
1113import 'package:file/local.dart' ;
1214import 'package:path/path.dart' as path;
@@ -744,6 +746,89 @@ Future<void> _runFrameworkTests() async {
744746 await _runFlutterTest (path.join (flutterRoot, 'examples' , 'layers' ), options: soundNullSafetyOptions);
745747 }
746748
749+ Future <void > runTracingTests () async {
750+ final String tracingDirectory = path.join (flutterRoot, 'dev' , 'tracing_tests' );
751+
752+ // run the tests for debug mode
753+ await _runFlutterTest (tracingDirectory, options: < String > ['--enable-vmservice' ]);
754+
755+ Future <List <String >> verifyTracingAppBuild ({
756+ required String modeArgument,
757+ required String sourceFile,
758+ required Set <String > allowed,
759+ required Set <String > disallowed,
760+ }) async {
761+ await runCommand (
762+ flutter,
763+ < String > [
764+ 'build' , 'appbundle' , '--$modeArgument ' , path.join ('lib' , sourceFile),
765+ ],
766+ workingDirectory: tracingDirectory,
767+ );
768+ final Archive archive = ZipDecoder ().decodeBytes (File (path.join (tracingDirectory, 'build' , 'app' , 'outputs' , 'bundle' , modeArgument, 'app-$modeArgument .aab' )).readAsBytesSync ());
769+ final ArchiveFile libapp = archive.findFile ('base/lib/arm64-v8a/libapp.so' )! ;
770+ final Uint8List libappBytes = libapp.content as Uint8List ; // bytes decompressed here
771+ final String libappStrings = utf8.decode (libappBytes, allowMalformed: true );
772+ await runCommand (flutter, < String > ['clean' ], workingDirectory: tracingDirectory);
773+ final List <String > results = < String > [];
774+ for (final String pattern in allowed) {
775+ if (! libappStrings.contains (pattern)) {
776+ results.add ('When building with --$modeArgument , expected to find "$pattern " in libapp.so but could not find it.' );
777+ }
778+ }
779+ for (final String pattern in disallowed) {
780+ if (libappStrings.contains (pattern)) {
781+ results.add ('When building with --$modeArgument , expected to not find "$pattern " in libapp.so but did find it.' );
782+ }
783+ }
784+ return results;
785+ }
786+
787+ final List <String > results = < String > [];
788+ results.addAll (await verifyTracingAppBuild (
789+ modeArgument: 'profile' ,
790+ sourceFile: 'control.dart' , // this is the control, the other two below are the actual test
791+ allowed: < String > {
792+ 'TIMELINE ARGUMENTS TEST CONTROL FILE' ,
793+ 'toTimelineArguments used in non-debug build' , // we call toTimelineArguments directly to check the message does exist
794+ },
795+ disallowed: < String > {
796+ 'BUILT IN DEBUG MODE' , 'BUILT IN RELEASE MODE' ,
797+ },
798+ ));
799+ results.addAll (await verifyTracingAppBuild (
800+ modeArgument: 'profile' ,
801+ sourceFile: 'test.dart' ,
802+ allowed: < String > {
803+ 'BUILT IN PROFILE MODE' , 'RenderTest.performResize called' , // controls
804+ 'BUILD' , 'LAYOUT' , 'PAINT' , // we output these to the timeline in profile builds
805+ // (LAYOUT and PAINT also exist because of NEEDS-LAYOUT and NEEDS-PAINT in RenderObject.toStringShort)
806+ },
807+ disallowed: < String > {
808+ 'BUILT IN DEBUG MODE' , 'BUILT IN RELEASE MODE' ,
809+ 'TestWidget.debugFillProperties called' , 'RenderTest.debugFillProperties called' , // debug only
810+ 'toTimelineArguments used in non-debug build' , // entire function should get dropped by tree shaker
811+ },
812+ ));
813+ results.addAll (await verifyTracingAppBuild (
814+ modeArgument: 'release' ,
815+ sourceFile: 'test.dart' ,
816+ allowed: < String > {
817+ 'BUILT IN RELEASE MODE' , 'RenderTest.performResize called' , // controls
818+ },
819+ disallowed: < String > {
820+ 'BUILT IN DEBUG MODE' , 'BUILT IN PROFILE MODE' ,
821+ 'BUILD' , 'LAYOUT' , 'PAINT' , // these are only used in Timeline.startSync calls that should not appear in release builds
822+ 'TestWidget.debugFillProperties called' , 'RenderTest.debugFillProperties called' , // debug only
823+ 'toTimelineArguments used in non-debug build' , // not included in release builds
824+ },
825+ ));
826+ if (results.isNotEmpty) {
827+ print (results.join ('\n ' ));
828+ exit (1 );
829+ }
830+ }
831+
747832 Future <void > runFixTests () async {
748833 final List <String > args = < String > [
749834 'fix' ,
@@ -808,10 +893,7 @@ Future<void> _runFrameworkTests() async {
808893 await _runFlutterTest (path.join (flutterRoot, 'packages' , 'flutter_test' ), options: soundNullSafetyOptions);
809894 await _runFlutterTest (path.join (flutterRoot, 'packages' , 'fuchsia_remote_debug_protocol' ), options: soundNullSafetyOptions);
810895 await _runFlutterTest (path.join (flutterRoot, 'dev' , 'integration_tests' , 'non_nullable' ), options: mixedModeNullSafetyOptions);
811- await _runFlutterTest (
812- path.join (flutterRoot, 'dev' , 'tracing_tests' ),
813- options: < String > ['--enable-vmservice' ],
814- );
896+ await runTracingTests ();
815897 await runFixTests ();
816898 await runPrivateTests ();
817899 const String httpClientWarning =
0 commit comments