OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 // VMOptions=--error_on_bad_type --error_on_bad_override | 4 // VMOptions=--error_on_bad_type --error_on_bad_override |
5 | 5 |
6 import 'package:observatory/service_io.dart'; | 6 import 'package:observatory/service_io.dart'; |
7 import 'package:unittest/unittest.dart'; | 7 import 'package:unittest/unittest.dart'; |
8 import 'test_helper.dart'; | 8 import 'test_helper.dart'; |
9 import 'dart:async'; | 9 import 'dart:developer'; |
10 | 10 |
11 int globalVar = 100; | 11 int globalVar = 100; |
12 | 12 |
13 class MyClass { | 13 class MyClass { |
14 static void myFunction(int value) { | 14 static void myFunction(int value) { |
15 print(value); // line 14 | |
16 if (value < 0) { | 15 if (value < 0) { |
17 print("negative"); | 16 print("negative"); |
18 } else { | 17 } else { |
19 print("positive"); | 18 print("positive"); |
20 } | 19 } |
| 20 debugger(); |
21 } | 21 } |
22 | 22 |
23 static void otherFunction(int value) { | 23 static void otherFunction(int value) { |
24 if (value < 0) { | 24 if (value < 0) { |
25 print("otherFunction <"); | 25 print("otherFunction <"); |
26 } else { | 26 } else { |
27 print("otherFunction >="); | 27 print("otherFunction >="); |
28 } | 28 } |
29 } | 29 } |
30 } | 30 } |
31 | 31 |
32 void testFunction() { | 32 void testFunction() { |
33 MyClass.otherFunction(-100); | 33 MyClass.otherFunction(-100); |
34 int i = 0; | 34 MyClass.myFunction(10000); |
35 while (true) { | |
36 if (++i % 100000000 == 0) { | |
37 MyClass.myFunction(10000); | |
38 } | |
39 } | |
40 } | |
41 | |
42 List normalize(List coverage) { | |
43 // The exact coverage numbers may vary based on how many times | |
44 // things run. Normalize the data to 0 or 1. | |
45 List normalized = []; | |
46 for (int i = 0; i < coverage.length; i += 2) { | |
47 normalized.add(coverage[i]); | |
48 normalized.add(coverage[i+1] == 0 ? 0 : 1); | |
49 } | |
50 return normalized; | |
51 } | 35 } |
52 | 36 |
53 var tests = [ | 37 var tests = [ |
54 | 38 |
55 // Go to breakpoint at line 14. | 39 hasStoppedAtBreakpoint, |
56 (Isolate isolate) { | |
57 return isolate.rootLibrary.load().then((_) { | |
58 // Set up a listener to wait for breakpoint events. | |
59 Completer completer = new Completer(); | |
60 isolate.vm.getEventStream(VM.kDebugStream).then((stream) { | |
61 var subscription; | |
62 subscription = stream.listen((ServiceEvent event) { | |
63 if (event.kind == ServiceEvent.kPauseBreakpoint) { | |
64 print('Breakpoint reached'); | |
65 completer.complete(); | |
66 subscription.cancel(); | |
67 } | |
68 }); | |
69 }); | |
70 | |
71 // Create a timer to set a breakpoint with a short delay. | |
72 new Timer(new Duration(milliseconds: 2000), () { | |
73 // Add the breakpoint. | |
74 print('Setting breakpoint.'); | |
75 var script = isolate.rootLibrary.scripts[0]; | |
76 var line = 14; | |
77 isolate.addBreakpoint(script, line); | |
78 }); | |
79 | |
80 return completer.future; | |
81 }); | |
82 }, | |
83 | 40 |
84 // Get coverage for function, class, library, script, and isolate. | 41 // Get coverage for function, class, library, script, and isolate. |
85 (Isolate isolate) { | 42 (Isolate isolate) async { |
86 return isolate.getStack().then((ServiceMap stack) { | 43 var stack = await isolate.getStack(); |
87 // Make sure we are in the right place. | |
88 expect(stack.type, equals('Stack')); | |
89 expect(stack['frames'].length, greaterThanOrEqualTo(2)); | |
90 expect(stack['frames'][0].function.name, equals('myFunction')); | |
91 expect(stack['frames'][0].function.dartOwner.name, equals('MyClass')); | |
92 | 44 |
93 var lib = isolate.rootLibrary; | 45 // Make sure we are in the right place. |
94 var func = stack['frames'][0].function; | 46 expect(stack.type, equals('Stack')); |
95 expect(func.name, equals('myFunction')); | 47 expect(stack['frames'].length, greaterThanOrEqualTo(2)); |
96 var cls = func.dartOwner; | 48 expect(stack['frames'][0].function.name, equals('myFunction')); |
97 expect(cls.name, equals('MyClass')); | 49 expect(stack['frames'][0].function.dartOwner.name, equals('MyClass')); |
98 | 50 |
99 List tests = []; | 51 var lib = isolate.rootLibrary; |
100 // Function | 52 var func = stack['frames'][0].function; |
101 tests.add(isolate.invokeRpcNoUpgrade('_getCoverage', | 53 expect(func.name, equals('myFunction')); |
102 { 'targetId': func.id }) | 54 var cls = func.dartOwner; |
103 .then((Map coverage) { | 55 expect(cls.name, equals('MyClass')); |
104 expect(coverage['type'], equals('CodeCoverage')); | 56 |
105 expect(coverage['coverage'].length, equals(1)); | 57 // Function |
106 expect(normalize(coverage['coverage'][0]['hits']), | 58 var coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', |
107 equals([15, 1, 16, 1, 17, 0, 19, 1])); | 59 { 'targetId': func.id }); |
108 })); | 60 expect(coverage['type'], equals('CodeCoverage')); |
109 // Class | 61 expect(coverage['coverage'].length, equals(1)); |
110 tests.add(isolate.invokeRpcNoUpgrade('_getCoverage', | 62 expect(coverage['coverage'][0]['hits'], |
111 { 'targetId': cls.id }) | 63 equals([15, 1, 16, 0, 18, 1, 20, 1])); |
112 .then((Map coverage) { | 64 |
113 expect(coverage['type'], equals('CodeCoverage')); | 65 // Class |
114 expect(coverage['coverage'].length, equals(1)); | 66 coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', |
115 expect(normalize(coverage['coverage'][0]['hits']), | 67 { 'targetId': cls.id }); |
116 equals([15, 1, 16, 1, 17, 0, 19, 1, | 68 expect(coverage['type'], equals('CodeCoverage')); |
117 24, 1, 25, 1, 27, 0])); | 69 expect(coverage['coverage'].length, equals(1)); |
118 })); | 70 expect(coverage['coverage'][0]['hits'], |
119 // Library | 71 equals([15, 1, 16, 0, 18, 1, 20, 1, |
120 tests.add(isolate.invokeRpcNoUpgrade('_getCoverage', | 72 24, 1, 25, 1, 27, 0])); |
121 { 'targetId': lib.id }) | 73 |
122 .then((Map coverage) { | 74 // Library |
123 expect(coverage['type'], equals('CodeCoverage')); | 75 coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', |
124 expect(coverage['coverage'].length, equals(3)); | 76 { 'targetId': lib.id }); |
125 expect(normalize(coverage['coverage'][0]['hits']), | 77 expect(coverage['type'], equals('CodeCoverage')); |
126 equals([15, 1, 16, 1, 17, 0, 19, 1, | 78 expect(coverage['coverage'].length, equals(3)); |
127 24, 1, 25, 1, 27, 0])); | 79 expect(coverage['coverage'][0]['hits'], |
128 expect(normalize(coverage['coverage'][1]['hits']).take(12), | 80 equals([15, 1, 16, 0, 18, 1, 20, 1, |
129 equals([33, 1, 36, 1, 37, 0, 32, 1, 45, 0, 46, 0])); | 81 24, 1, 25, 1, 27, 0])); |
130 })); | 82 expect(coverage['coverage'][1]['hits'].take(12), |
131 // Script | 83 equals([33, 1, 34, 1, 32, 1, 105, 2, 105, 1])); |
132 tests.add(cls.load().then((_) { | 84 |
133 return isolate.invokeRpcNoUpgrade( | 85 // Script |
134 '_getCoverage', | 86 await cls.load(); |
135 { 'targetId': cls.location.script.id }) | 87 coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', |
136 .then((Map coverage) { | 88 { 'targetId': cls.location.script.id }); |
137 expect(coverage['type'], equals('CodeCoverage')); | 89 expect(coverage['type'], equals('CodeCoverage')); |
138 expect(coverage['coverage'].length, equals(3)); | 90 expect(coverage['coverage'].length, equals(3)); |
139 expect(normalize(coverage['coverage'][0]['hits']), | 91 expect(coverage['coverage'][0]['hits'], |
140 equals([15, 1, 16, 1, 17, 0, 19, 1, | 92 equals([15, 1, 16, 0, 18, 1, 20, 1, |
141 24, 1, 25, 1, 27, 0])); | 93 24, 1, 25, 1, 27, 0])); |
142 expect(normalize(coverage['coverage'][1]['hits']).take(12), | 94 expect(coverage['coverage'][1]['hits'].take(12), |
143 equals([33, 1, 36, 1, 37, 0, 32, 1, 45, 0, 46, 0])); | 95 equals([33, 1, 34, 1, 32, 1, 105, 2, 105, 1])); |
144 }); | 96 |
145 })); | 97 // Isolate |
146 // Isolate | 98 coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', {}); |
147 tests.add(cls.load().then((_) { | 99 expect(coverage['type'], equals('CodeCoverage')); |
148 return isolate.invokeRpcNoUpgrade('_getCoverage', {}) | 100 expect(coverage['coverage'].length, greaterThan(100)); |
149 .then((Map coverage) { | |
150 expect(coverage['type'], equals('CodeCoverage')); | |
151 expect(coverage['coverage'].length, greaterThan(100)); | |
152 }); | |
153 })); | |
154 return Future.wait(tests); | |
155 }); | |
156 }, | 101 }, |
157 | 102 |
158 ]; | 103 ]; |
159 | 104 |
160 main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction); | 105 main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction); |
OLD | NEW |