mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:31:50 +00:00
[vm] Report a coverage tick for the function as a whole.
This ensures leaf functions have some coverage data. Bug: https://github.com/dart-lang/sdk/issues/31215 Change-Id: I6efc2e1c002e26cd0483dce5a8a1c2b6d8958d13 Reviewed-on: https://dart-review.googlesource.com/16684 Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
parent
d21a98a104
commit
3d409223a3
|
@ -0,0 +1,115 @@
|
|||
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
// VMOptions=--error_on_bad_type --error_on_bad_override
|
||||
|
||||
import 'package:observatory/service_io.dart';
|
||||
import 'package:unittest/unittest.dart';
|
||||
import 'test_helper.dart';
|
||||
import 'service_test_common.dart';
|
||||
import 'dart:developer';
|
||||
|
||||
String leafFunction() {
|
||||
return "some constant";
|
||||
}
|
||||
|
||||
void testFunction() {
|
||||
debugger();
|
||||
leafFunction();
|
||||
debugger();
|
||||
}
|
||||
|
||||
bool allRangesCompiled(coverage) {
|
||||
for (int i = 0; i < coverage['ranges'].length; i++) {
|
||||
if (!coverage['ranges'][i]['compiled']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var tests = [
|
||||
hasStoppedAtBreakpoint,
|
||||
(Isolate isolate) async {
|
||||
var stack = await isolate.getStack();
|
||||
|
||||
// Make sure we are in the right place.
|
||||
expect(stack.type, equals('Stack'));
|
||||
expect(stack['frames'].length, greaterThanOrEqualTo(1));
|
||||
expect(stack['frames'][0].function.name, equals('testFunction'));
|
||||
|
||||
var root = isolate.rootLibrary;
|
||||
await root.load();
|
||||
var func = root.functions.singleWhere((f) => f.name == 'leafFunction');
|
||||
await func.load();
|
||||
|
||||
var expectedRange = {
|
||||
'scriptIndex': 0,
|
||||
'startPos': ifKernel(456, 26),
|
||||
'endPos': ifKernel(499, 37),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([], []),
|
||||
'misses': ifKernel([456], [26])
|
||||
}
|
||||
};
|
||||
|
||||
var params = {
|
||||
'reports': ['Coverage'],
|
||||
'scriptId': func.location.script.id,
|
||||
'tokenPos': func.location.tokenPos,
|
||||
'endTokenPos': func.location.endTokenPos,
|
||||
'forceCompile': true
|
||||
};
|
||||
var report = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
|
||||
expect(report['type'], equals('SourceReport'));
|
||||
expect(report['ranges'].length, 1);
|
||||
expect(report['ranges'][0], equals(expectedRange));
|
||||
expect(report['scripts'].length, 1);
|
||||
expect(report['scripts'][0]['uri'],
|
||||
endsWith('coverage_leaf_function_test.dart'));
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
(Isolate isolate) async {
|
||||
var stack = await isolate.getStack();
|
||||
|
||||
// Make sure we are in the right place.
|
||||
expect(stack.type, equals('Stack'));
|
||||
expect(stack['frames'].length, greaterThanOrEqualTo(1));
|
||||
expect(stack['frames'][0].function.name, equals('testFunction'));
|
||||
|
||||
var root = isolate.rootLibrary;
|
||||
await root.load();
|
||||
var func = root.functions.singleWhere((f) => f.name == 'leafFunction');
|
||||
await func.load();
|
||||
|
||||
var expectedRange = {
|
||||
'scriptIndex': 0,
|
||||
'startPos': ifKernel(456, 26),
|
||||
'endPos': ifKernel(499, 37),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([456], [26]),
|
||||
'misses': ifKernel([], [])
|
||||
}
|
||||
};
|
||||
|
||||
var params = {
|
||||
'reports': ['Coverage'],
|
||||
'scriptId': func.location.script.id,
|
||||
'tokenPos': func.location.tokenPos,
|
||||
'endTokenPos': func.location.endTokenPos,
|
||||
'forceCompile': true
|
||||
};
|
||||
var report = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
|
||||
expect(report['type'], equals('SourceReport'));
|
||||
expect(report['ranges'].length, 1);
|
||||
expect(report['ranges'][0], equals(expectedRange));
|
||||
expect(report['scripts'].length, 1);
|
||||
expect(report['scripts'][0]['uri'],
|
||||
endsWith('coverage_leaf_function_test.dart'));
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
|
|
@ -65,7 +65,7 @@ var tests = [
|
|||
'endPos': ifKernel(633, 88),
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': ifKernel([539, 590, 619], [54, 72, 82]),
|
||||
'hits': ifKernel([501, 539, 590, 619], [39, 54, 72, 82]),
|
||||
'misses': ifKernel([552], [60])
|
||||
}
|
||||
};
|
||||
|
|
|
@ -211,6 +211,12 @@ void SourceReport::PrintCoverageData(JSONObject* jsobj,
|
|||
coverage[i] = kCoverageNone;
|
||||
}
|
||||
|
||||
if (function.usage_counter() > 0) {
|
||||
coverage[0] = kCoverageHit;
|
||||
} else {
|
||||
coverage[0] = kCoverageMiss;
|
||||
}
|
||||
|
||||
PcDescriptors::Iterator iter(
|
||||
descriptors,
|
||||
RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
|
||||
|
|
|
@ -40,9 +40,9 @@ TEST_CASE(SourceReport_Coverage_NoCalls) {
|
|||
EXPECT_STREQ(
|
||||
"{\"type\":\"SourceReport\",\"ranges\":"
|
||||
|
||||
// One compiled range, no hits or misses.
|
||||
// One compiled range, one hit at function declaration.
|
||||
"[{\"scriptIndex\":0,\"startPos\":0,\"endPos\":5,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}}],"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}}],"
|
||||
|
||||
// One script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
@ -77,16 +77,16 @@ TEST_CASE(SourceReport_Coverage_SimpleCall) {
|
|||
EXPECT_STREQ(
|
||||
"{\"type\":\"SourceReport\",\"ranges\":["
|
||||
|
||||
// One range compiled with no hits or misses (helper0).
|
||||
// One range compiled with one hit at function declaration (helper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}},"
|
||||
|
||||
// One range not compiled (helper1).
|
||||
"{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
|
||||
|
||||
// One range with a hit and a miss (main).
|
||||
// One range with two hits and a miss (main).
|
||||
"{\"scriptIndex\":0,\"startPos\":12,\"endPos\":39,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[23],\"misses\":[32]}}],"
|
||||
"\"coverage\":{\"hits\":[12,23],\"misses\":[32]}}],"
|
||||
|
||||
// Only one script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
@ -121,17 +121,17 @@ TEST_CASE(SourceReport_Coverage_ForceCompile) {
|
|||
EXPECT_STREQ(
|
||||
"{\"type\":\"SourceReport\",\"ranges\":["
|
||||
|
||||
// One range compiled with no hits or misses (helper0).
|
||||
// One range compiled with one hit at function declaration (helper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}},"
|
||||
|
||||
// This range is compiled even though it wasn't called (helper1).
|
||||
"{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[6]}},"
|
||||
|
||||
// One range with a hit and a miss (main).
|
||||
// One range with two hits and a miss (main).
|
||||
"{\"scriptIndex\":0,\"startPos\":12,\"endPos\":39,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[23],\"misses\":[32]}}],"
|
||||
"\"coverage\":{\"hits\":[12,23],\"misses\":[32]}}],"
|
||||
|
||||
// Only one script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
@ -169,11 +169,11 @@ TEST_CASE(SourceReport_Coverage_UnusedClass_NoForceCompile) {
|
|||
|
||||
// helper0 is compiled.
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}},"
|
||||
|
||||
// One range with a hit (main).
|
||||
// One range with two hits (main).
|
||||
"{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
|
||||
"\"coverage\":{\"hits\":[22,27],\"misses\":[]}}],"
|
||||
|
||||
// Only one script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
@ -208,15 +208,15 @@ TEST_CASE(SourceReport_Coverage_UnusedClass_ForceCompile) {
|
|||
|
||||
// UnusedClass.helper1 is compiled.
|
||||
"{\"scriptIndex\":0,\"startPos\":10,\"endPos\":18,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[14]}},"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[10,14]}},"
|
||||
|
||||
// helper0 is compiled.
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}},"
|
||||
|
||||
// One range with a hit (main).
|
||||
// One range with two hits (main).
|
||||
"{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
|
||||
"\"coverage\":{\"hits\":[22,27],\"misses\":[]}}],"
|
||||
|
||||
// Only one script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
@ -258,11 +258,11 @@ TEST_CASE(SourceReport_Coverage_UnusedClass_ForceCompileError) {
|
|||
|
||||
// helper0 is compiled.
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}},"
|
||||
|
||||
// One range with a hit (main).
|
||||
// One range with two hits (main).
|
||||
"{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
|
||||
"\"coverage\":{\"hits\":[22,27],\"misses\":[]}}],"
|
||||
|
||||
// Only one script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
@ -303,18 +303,18 @@ TEST_CASE(SourceReport_Coverage_NestedFunctions) {
|
|||
|
||||
// One range compiled with one hit (helper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":22,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[18],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0,18],\"misses\":[]}},"
|
||||
|
||||
// One range not compiled (helper1).
|
||||
"{\"scriptIndex\":0,\"startPos\":24,\"endPos\":28,\"compiled\":false},"
|
||||
|
||||
// One range with a hit and a miss (main).
|
||||
// One range with two hits and a miss (main).
|
||||
"{\"scriptIndex\":0,\"startPos\":30,\"endPos\":57,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[41],\"misses\":[50]}},"
|
||||
"\"coverage\":{\"hits\":[30,41],\"misses\":[50]}},"
|
||||
|
||||
// Nested range compiled (nestedHelper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":5,\"endPos\":9,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[5],\"misses\":[]}},"
|
||||
|
||||
// Nested range not compiled (nestedHelper1).
|
||||
"{\"scriptIndex\":0,\"startPos\":11,\"endPos\":15,\"compiled\":false}],"
|
||||
|
@ -361,11 +361,11 @@ TEST_CASE(SourceReport_Coverage_RestrictedRange) {
|
|||
|
||||
// One range compiled with one hit (helper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":22,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[18],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0,18],\"misses\":[]}},"
|
||||
|
||||
// Nested range compiled (nestedHelper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":5,\"endPos\":9,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[5],\"misses\":[]}},"
|
||||
|
||||
// Nested range not compiled (nestedHelper1).
|
||||
"{\"scriptIndex\":0,\"startPos\":11,\"endPos\":15,\"compiled\":false}],"
|
||||
|
@ -406,7 +406,7 @@ TEST_CASE(SourceReport_Coverage_AllFunctions) {
|
|||
// Make sure that the main function was found.
|
||||
EXPECT_SUBSTRING(
|
||||
"\"startPos\":12,\"endPos\":39,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[23],\"misses\":[32]}",
|
||||
"\"coverage\":{\"hits\":[12,23],\"misses\":[32]}",
|
||||
result);
|
||||
|
||||
// More than one script is referenced in the report.
|
||||
|
@ -448,7 +448,7 @@ TEST_CASE(SourceReport_Coverage_AllFunctions_ForceCompile) {
|
|||
// Make sure that the main function was found.
|
||||
EXPECT_SUBSTRING(
|
||||
"\"startPos\":12,\"endPos\":39,\"compiled\":true,"
|
||||
"\"coverage\":{\"hits\":[23],\"misses\":[32]}",
|
||||
"\"coverage\":{\"hits\":[12,23],\"misses\":[32]}",
|
||||
result);
|
||||
|
||||
// More than one script is referenced in the report.
|
||||
|
@ -603,7 +603,7 @@ TEST_CASE(SourceReport_MultipleReports) {
|
|||
// One range compiled with no callsites (helper0).
|
||||
"{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
|
||||
"\"callSites\":[],"
|
||||
"\"coverage\":{\"hits\":[],\"misses\":[]}},"
|
||||
"\"coverage\":{\"hits\":[0],\"misses\":[]}},"
|
||||
|
||||
// One range not compiled (helper1).
|
||||
"{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
|
||||
|
@ -617,7 +617,7 @@ TEST_CASE(SourceReport_MultipleReports) {
|
|||
"\"id\":\"\",\"name\":\"\",\"uri\":\"test-lib\"},"
|
||||
"\"_kind\":\"RegularFunction\",\"static\":true,\"const\":false,"
|
||||
"\"_intrinsic\":false,\"_native\":false},\"count\":1}]}],"
|
||||
"\"coverage\":{\"hits\":[17],\"misses\":[]}}],"
|
||||
"\"coverage\":{\"hits\":[12,17],\"misses\":[]}}],"
|
||||
|
||||
// One script in the script table.
|
||||
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
|
||||
|
|
Loading…
Reference in a new issue