mirror of
https://github.com/flutter/flutter
synced 2024-10-14 04:02:56 +00:00
9b7b9d795e
Fixes #56194 Remove caching of FlutterView and poll forever if the list of flutter views is empty. Added test for missing release mode logic.
326 lines
9.2 KiB
Dart
326 lines
9.2 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:flutter_tools/src/base/common.dart';
|
|
import 'package:flutter_tools/src/convert.dart';
|
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
|
import 'package:mockito/mockito.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/device.dart';
|
|
import 'package:flutter_tools/src/version.dart';
|
|
import 'package:flutter_tools/src/vmservice.dart';
|
|
|
|
import '../src/common.dart';
|
|
import '../src/context.dart';
|
|
|
|
final Map<String, Object> vm = <String, dynamic>{
|
|
'type': 'VM',
|
|
'name': 'vm',
|
|
'architectureBits': 64,
|
|
'targetCPU': 'x64',
|
|
'hostCPU': ' Intel(R) Xeon(R) CPU E5-1650 v2 @ 3.50GHz',
|
|
'version': '2.1.0-dev.7.1.flutter-45f9462398 (Fri Oct 19 19:27:56 2018 +0000) on "linux_x64"',
|
|
'_profilerMode': 'Dart',
|
|
'_nativeZoneMemoryUsage': 0,
|
|
'pid': 103707,
|
|
'startTime': 1540426121876,
|
|
'_embedder': 'Flutter',
|
|
'_maxRSS': 312614912,
|
|
'_currentRSS': 33091584,
|
|
'isolates': <dynamic>[
|
|
<String, dynamic>{
|
|
'type': '@Isolate',
|
|
'fixedId': true,
|
|
'id': 'isolates/242098474',
|
|
'name': 'main.dart:main()',
|
|
'number': 242098474,
|
|
},
|
|
],
|
|
};
|
|
|
|
final vm_service.Isolate isolate = vm_service.Isolate.parse(
|
|
<String, dynamic>{
|
|
'type': 'Isolate',
|
|
'fixedId': true,
|
|
'id': 'isolates/242098474',
|
|
'name': 'main.dart:main()',
|
|
'number': 242098474,
|
|
'_originNumber': 242098474,
|
|
'startTime': 1540488745340,
|
|
'_heaps': <String, dynamic>{
|
|
'new': <String, dynamic>{
|
|
'used': 0,
|
|
'capacity': 0,
|
|
'external': 0,
|
|
'collections': 0,
|
|
'time': 0.0,
|
|
'avgCollectionPeriodMillis': 0.0,
|
|
},
|
|
'old': <String, dynamic>{
|
|
'used': 0,
|
|
'capacity': 0,
|
|
'external': 0,
|
|
'collections': 0,
|
|
'time': 0.0,
|
|
'avgCollectionPeriodMillis': 0.0,
|
|
},
|
|
},
|
|
}
|
|
);
|
|
|
|
final Map<String, Object> listViews = <String, dynamic>{
|
|
'type': 'FlutterViewList',
|
|
'views': <dynamic>[
|
|
<String, dynamic>{
|
|
'type': 'FlutterView',
|
|
'id': '_flutterView/0x4a4c1f8',
|
|
'isolate': <String, dynamic>{
|
|
'type': '@Isolate',
|
|
'fixedId': true,
|
|
'id': 'isolates/242098474',
|
|
'name': 'main.dart:main()',
|
|
'number': 242098474,
|
|
},
|
|
},
|
|
]
|
|
};
|
|
|
|
typedef ServiceCallback = Future<Map<String, dynamic>> Function(Map<String, Object>);
|
|
|
|
void main() {
|
|
testUsingContext('VmService registers reloadSources', () async {
|
|
Future<void> reloadSources(String isolateId, { bool pause, bool force}) async {}
|
|
|
|
final MockVMService mockVMService = MockVMService();
|
|
setUpVmService(
|
|
reloadSources,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
mockVMService,
|
|
);
|
|
|
|
verify(mockVMService.registerService('reloadSources', 'Flutter Tools')).called(1);
|
|
}, overrides: <Type, Generator>{
|
|
Logger: () => BufferLogger.test()
|
|
});
|
|
|
|
testUsingContext('VmService registers reloadMethod', () async {
|
|
Future<void> reloadMethod({ String classId, String libraryId,}) async {}
|
|
|
|
final MockVMService mockVMService = MockVMService();
|
|
setUpVmService(
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
reloadMethod,
|
|
mockVMService,
|
|
);
|
|
|
|
verify(mockVMService.registerService('reloadMethod', 'Flutter Tools')).called(1);
|
|
}, overrides: <Type, Generator>{
|
|
Logger: () => BufferLogger.test()
|
|
});
|
|
|
|
testUsingContext('VmService registers flutterMemoryInfo service', () async {
|
|
final MockDevice mockDevice = MockDevice();
|
|
|
|
final MockVMService mockVMService = MockVMService();
|
|
setUpVmService(
|
|
null,
|
|
null,
|
|
null,
|
|
mockDevice,
|
|
null,
|
|
mockVMService,
|
|
);
|
|
|
|
verify(mockVMService.registerService('flutterMemoryInfo', 'Flutter Tools')).called(1);
|
|
}, overrides: <Type, Generator>{
|
|
Logger: () => BufferLogger.test()
|
|
});
|
|
|
|
testUsingContext('VMService returns correct FlutterVersion', () async {
|
|
final MockVMService mockVMService = MockVMService();
|
|
setUpVmService(
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
mockVMService,
|
|
);
|
|
|
|
verify(mockVMService.registerService('flutterVersion', 'Flutter Tools')).called(1);
|
|
}, overrides: <Type, Generator>{
|
|
FlutterVersion: () => MockFlutterVersion(),
|
|
});
|
|
|
|
testWithoutContext('setAssetDirectory forwards arguments correctly', () async {
|
|
final Completer<String> completer = Completer<String>();
|
|
final vm_service.VmService vmService = vm_service.VmService(
|
|
const Stream<String>.empty(),
|
|
completer.complete,
|
|
);
|
|
|
|
unawaited(vmService.setAssetDirectory(
|
|
assetsDirectory: Uri(path: 'abc', scheme: 'file'),
|
|
viewId: 'abc',
|
|
uiIsolateId: 'def',
|
|
));
|
|
|
|
final Map<String, Object> rawRequest = json.decode(await completer.future) as Map<String, Object>;
|
|
|
|
expect(rawRequest, allOf(<Matcher>[
|
|
containsPair('method', kSetAssetBundlePathMethod),
|
|
containsPair('params', allOf(<Matcher>[
|
|
containsPair('viewId', 'abc'),
|
|
containsPair('assetDirectory', '/abc'),
|
|
containsPair('isolateId', 'def'),
|
|
]))
|
|
]));
|
|
});
|
|
|
|
testWithoutContext('getSkSLs forwards arguments correctly', () async {
|
|
final Completer<String> completer = Completer<String>();
|
|
final vm_service.VmService vmService = vm_service.VmService(
|
|
const Stream<String>.empty(),
|
|
completer.complete,
|
|
);
|
|
|
|
unawaited(vmService.getSkSLs(
|
|
viewId: 'abc',
|
|
));
|
|
|
|
final Map<String, Object> rawRequest = json.decode(await completer.future) as Map<String, Object>;
|
|
|
|
expect(rawRequest, allOf(<Matcher>[
|
|
containsPair('method', kGetSkSLsMethod),
|
|
containsPair('params', allOf(<Matcher>[
|
|
containsPair('viewId', 'abc'),
|
|
]))
|
|
]));
|
|
});
|
|
|
|
testWithoutContext('flushUIThreadTasks forwards arguments correctly', () async {
|
|
final Completer<String> completer = Completer<String>();
|
|
final vm_service.VmService vmService = vm_service.VmService(
|
|
const Stream<String>.empty(),
|
|
completer.complete,
|
|
);
|
|
|
|
unawaited(vmService.flushUIThreadTasks(
|
|
uiIsolateId: 'def',
|
|
));
|
|
|
|
final Map<String, Object> rawRequest = json.decode(await completer.future) as Map<String, Object>;
|
|
|
|
expect(rawRequest, allOf(<Matcher>[
|
|
containsPair('method', kFlushUIThreadTasksMethod),
|
|
containsPair('params', allOf(<Matcher>[
|
|
containsPair('isolateId', 'def'),
|
|
]))
|
|
]));
|
|
});
|
|
|
|
testWithoutContext('runInView forwards arguments correctly', () async {
|
|
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
|
requests: <VmServiceExpectation>[
|
|
const FakeVmServiceRequest(method: 'streamListen', args: <String, Object>{
|
|
'streamId': 'Isolate'
|
|
}),
|
|
const FakeVmServiceRequest(method: kRunInViewMethod, args: <String, Object>{
|
|
'viewId': '1234',
|
|
'mainScript': 'main.dart',
|
|
'assetDirectory': 'flutter_assets/',
|
|
}),
|
|
FakeVmServiceStreamResponse(
|
|
streamId: 'Isolate',
|
|
event: vm_service.Event(
|
|
kind: vm_service.EventKind.kIsolateRunnable,
|
|
timestamp: 1,
|
|
)
|
|
),
|
|
]
|
|
);
|
|
|
|
await fakeVmServiceHost.vmService.runInView(
|
|
viewId: '1234',
|
|
main: Uri.file('main.dart'),
|
|
assetsDirectory: Uri.file('flutter_assets/'),
|
|
);
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
|
});
|
|
|
|
testWithoutContext('getFlutterViews polls until a view is returned', () async {
|
|
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
|
requests: <VmServiceExpectation>[
|
|
const FakeVmServiceRequest(
|
|
method: kListViewsMethod,
|
|
jsonResponse: <String, Object>{
|
|
'views': <Object>[],
|
|
},
|
|
),
|
|
const FakeVmServiceRequest(
|
|
method: kListViewsMethod,
|
|
jsonResponse: <String, Object>{
|
|
'views': <Object>[],
|
|
},
|
|
),
|
|
const FakeVmServiceRequest(
|
|
method: kListViewsMethod,
|
|
jsonResponse: <String, Object>{
|
|
'views': <Object>[
|
|
<String, Object>{
|
|
'id': 'a',
|
|
'isolate': <String, Object>{},
|
|
},
|
|
],
|
|
},
|
|
),
|
|
]
|
|
);
|
|
|
|
expect(
|
|
await fakeVmServiceHost.vmService.getFlutterViews(
|
|
delay: Duration.zero,
|
|
),
|
|
isNotEmpty,
|
|
);
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
|
});
|
|
|
|
testWithoutContext('getFlutterViews does not poll if returnEarly is true', () async {
|
|
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
|
requests: <VmServiceExpectation>[
|
|
const FakeVmServiceRequest(
|
|
method: kListViewsMethod,
|
|
jsonResponse: <String, Object>{
|
|
'views': <Object>[],
|
|
},
|
|
),
|
|
]
|
|
);
|
|
|
|
expect(
|
|
await fakeVmServiceHost.vmService.getFlutterViews(
|
|
returnEarly: true,
|
|
),
|
|
isEmpty,
|
|
);
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
|
});
|
|
}
|
|
|
|
class MockDevice extends Mock implements Device {}
|
|
class MockVMService extends Mock implements vm_service.VmService {}
|
|
class MockFlutterVersion extends Mock implements FlutterVersion {
|
|
@override
|
|
Map<String, Object> toJson() => const <String, Object>{'Mock': 'Version'};
|
|
}
|