OLD | NEW |
---|---|
1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import copy | 5 import copy |
6 import json | 6 import json |
7 import os | 7 import os |
8 import shutil | 8 import shutil |
9 import subprocess | 9 import subprocess |
10 import tempfile | 10 import tempfile |
11 import unittest | 11 import unittest |
12 | 12 |
13 import loading_trace | |
14 import page_track | |
13 import pull_sandwich_metrics as puller | 15 import pull_sandwich_metrics as puller |
16 import request_track | |
17 import tracing | |
18 | |
14 | 19 |
15 _BLINK_CAT = 'blink.user_timing' | 20 _BLINK_CAT = 'blink.user_timing' |
16 _MEM_CAT = 'disabled-by-default-memory-infra' | 21 _MEM_CAT = 'disabled-by-default-memory-infra' |
17 _START='requestStart' | 22 _START='requestStart' |
18 _LOADS='loadEventStart' | 23 _LOADS='loadEventStart' |
19 _LOADE='loadEventEnd' | 24 _LOADE='loadEventEnd' |
20 _UNLOAD='unloadEventEnd' | 25 _UNLOAD='unloadEventEnd' |
21 | 26 |
22 _MINIMALIST_TRACE = {'traceEvents': [ | 27 _MINIMALIST_TRACE_EVENTS = [ |
23 {'cat': _BLINK_CAT, 'name': _UNLOAD, 'ts': 10, 'args': {'frame': '0'}}, | 28 {'ph': 'R', 'cat': _BLINK_CAT, 'name': _UNLOAD, 'ts': 10000, |
24 {'cat': _BLINK_CAT, 'name': _START, 'ts': 20, 'args': {}, }, | 29 'args': {'frame': '0'}}, |
30 {'ph': 'R', 'cat': _BLINK_CAT, 'name': _START, 'ts': 20000, | |
31 'args': {}}, | |
25 {'cat': _MEM_CAT, 'name': 'periodic_interval', 'pid': 1, 'ph': 'v', | 32 {'cat': _MEM_CAT, 'name': 'periodic_interval', 'pid': 1, 'ph': 'v', |
26 'args': {'dumps': {'allocators': {'malloc': {'attrs': {'size':{ | 33 'ts': 1, 'args': {'dumps': {'allocators': {'malloc': {'attrs': {'size':{ |
27 'units': 'bytes', 'value': '1af2', }}}}}}}, | 34 'units': 'bytes', 'value': '1af2', }}}}}}}, |
28 {'cat': _BLINK_CAT, 'name': _LOADS, 'ts': 35, 'args': {'frame': '0'}}, | 35 {'ph': 'R', 'cat': _BLINK_CAT, 'name': _LOADS, 'ts': 35000, |
29 {'cat': _BLINK_CAT, 'name': _LOADE, 'ts': 40, 'args': {'frame': '0'}}, | 36 'args': {'frame': '0'}}, |
37 {'ph': 'R', 'cat': _BLINK_CAT, 'name': _LOADE, 'ts': 40000, | |
38 'args': {'frame': '0'}}, | |
30 {'cat': _MEM_CAT, 'name': 'periodic_interval', 'pid': 1, 'ph': 'v', | 39 {'cat': _MEM_CAT, 'name': 'periodic_interval', 'pid': 1, 'ph': 'v', |
31 'args': {'dumps': {'allocators': {'malloc': {'attrs': {'size':{ | 40 'ts': 1, 'args': {'dumps': {'allocators': {'malloc': {'attrs': {'size':{ |
32 'units': 'bytes', 'value': 'd704', }}}}}}}, | 41 'units': 'bytes', 'value': 'd704', }}}}}}}, |
33 {'cat': '__metadata', 'pid': 1, 'name': 'process_name', 'args': { | 42 {'ph': 'M', 'cat': '__metadata', 'pid': 1, 'name': 'process_name', 'ts': 1, |
34 'name': 'Browser'}}]} | 43 'args': {'name': 'Browser'}}] |
44 | |
45 | |
46 def TracingTrack(events): | |
47 return tracing.TracingTrack.FromJsonDict({'events': events}) | |
48 | |
49 | |
50 def LoadingTrace(events): | |
51 return loading_trace.LoadingTrace('http://a.com/', {}, | |
52 page_track.PageTrack(None), | |
mattcary
2016/02/19 14:41:05
Can just pass in None instead of a *Track created
gabadie
2016/02/19 15:04:35
Already tried and I can't otherwise the SaveToJson
| |
53 request_track.RequestTrack(None), | |
54 TracingTrack(events)) | |
35 | 55 |
36 | 56 |
37 class PageTrackTest(unittest.TestCase): | 57 class PageTrackTest(unittest.TestCase): |
38 def testGetBrowserPID(self): | 58 def testGetBrowserPID(self): |
39 def RunHelper(expected, trace): | 59 def RunHelper(expected, events): |
40 self.assertEquals(expected, puller._GetBrowserPID(trace)) | 60 self.assertEquals(expected, puller._GetBrowserPID(TracingTrack(events))) |
41 | 61 |
42 RunHelper(123, {'traceEvents': [ | 62 RunHelper(123, [ |
43 {'pid': 354, 'cat': 'whatever0'}, | 63 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': 'whatever0'}, |
44 {'pid': 354, 'cat': 'whatever1'}, | 64 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': 'whatever1'}, |
45 {'pid': 354, 'cat': '__metadata', 'name': 'thread_name'}, | 65 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': '__metadata', |
46 {'pid': 354, 'cat': '__metadata', 'name': 'process_name', 'args': { | 66 'name': 'thread_name'}, |
47 'name': 'Renderer'}}, | 67 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': '__metadata', |
48 {'pid': 123, 'cat': '__metadata', 'name': 'process_name', 'args': { | 68 'name': 'process_name', 'args': {'name': 'Renderer'}}, |
49 'name': 'Browser'}}, | 69 {'ph': 'M', 'ts': 0, 'pid': 123, 'cat': '__metadata', |
50 {'pid': 354, 'cat': 'whatever0'}]}) | 70 'name': 'process_name', 'args': {'name': 'Browser'}}, |
71 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': 'whatever0'}]) | |
51 | 72 |
52 with self.assertRaises(ValueError): | 73 with self.assertRaises(ValueError): |
53 RunHelper(123, {'traceEvents': [ | 74 RunHelper(123, [ |
54 {'pid': 354, 'cat': 'whatever0'}, | 75 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': 'whatever0'}, |
55 {'pid': 354, 'cat': 'whatever1'}]}) | 76 {'ph': 'M', 'ts': 0, 'pid': 354, 'cat': 'whatever1'}]) |
56 | 77 |
57 def testGetBrowserDumpEvents(self): | 78 def testGetBrowserDumpEvents(self): |
58 NAME = 'periodic_interval' | 79 NAME = 'periodic_interval' |
59 | 80 |
60 def RunHelper(trace_events, browser_pid): | 81 def RunHelper(trace_events, browser_pid): |
61 trace_events = copy.copy(trace_events) | 82 trace_events = copy.copy(trace_events) |
62 trace_events.append({ | 83 trace_events.append({ |
63 'pid': browser_pid, | 84 'pid': browser_pid, |
64 'cat': '__metadata', | 85 'cat': '__metadata', |
65 'name': 'process_name', | 86 'name': 'process_name', |
87 'ph': 'M', | |
88 'ts': 0, | |
66 'args': {'name': 'Browser'}}) | 89 'args': {'name': 'Browser'}}) |
67 return puller._GetBrowserDumpEvents({'traceEvents': trace_events}) | 90 return puller._GetBrowserDumpEvents(TracingTrack(trace_events)) |
68 | 91 |
69 TRACE_EVENTS = [ | 92 TRACE_EVENTS = [ |
70 {'pid': 354, 'ts': 1, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, | 93 {'pid': 354, 'ts': 1000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, |
71 {'pid': 354, 'ts': 2, 'cat': _MEM_CAT, 'ph': 'V'}, | 94 {'pid': 354, 'ts': 2000, 'cat': _MEM_CAT, 'ph': 'V'}, |
72 {'pid': 672, 'ts': 3, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, | 95 {'pid': 672, 'ts': 3000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, |
73 {'pid': 123, 'ts': 4, 'cat': _MEM_CAT, 'ph': 'v', 'name': 'foo'}, | 96 {'pid': 123, 'ts': 4000, 'cat': _MEM_CAT, 'ph': 'v', 'name': 'foo'}, |
74 {'pid': 123, 'ts': 5, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, | 97 {'pid': 123, 'ts': 5000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, |
75 {'pid': 123, 'ts': 6, 'cat': _MEM_CAT, 'ph': 'V'}, | 98 {'pid': 123, 'ts': 6000, 'cat': _MEM_CAT, 'ph': 'V'}, |
76 {'pid': 672, 'ts': 7, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, | 99 {'pid': 672, 'ts': 7000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, |
77 {'pid': 354, 'ts': 8, 'cat': _MEM_CAT, 'ph': 'v', 'name': 'foo'}, | 100 {'pid': 354, 'ts': 8000, 'cat': _MEM_CAT, 'ph': 'v', 'name': 'foo'}, |
78 {'pid': 123, 'ts': 9, 'cat': 'whatever1', 'ph': 'v', 'name': NAME}, | 101 {'pid': 123, 'ts': 9000, 'cat': 'whatever1', 'ph': 'v', 'name': NAME}, |
79 {'pid': 123, 'ts': 10, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, | 102 {'pid': 123, 'ts': 10000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}, |
80 {'pid': 354, 'ts': 11, 'cat': 'whatever0'}, | 103 {'pid': 354, 'ts': 11000, 'cat': 'whatever0', 'ph': 'R'}, |
81 {'pid': 672, 'ts': 12, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}] | 104 {'pid': 672, 'ts': 12000, 'cat': _MEM_CAT, 'ph': 'v', 'name': NAME}] |
82 | 105 |
83 self.assertTrue(_MEM_CAT in puller.CATEGORIES) | 106 self.assertTrue(_MEM_CAT in puller.CATEGORIES) |
84 | 107 |
85 bump_events = RunHelper(TRACE_EVENTS, 123) | 108 bump_events = RunHelper(TRACE_EVENTS, 123) |
86 self.assertEquals(2, len(bump_events)) | 109 self.assertEquals(2, len(bump_events)) |
87 self.assertEquals(5, bump_events[0]['ts']) | 110 self.assertEquals(5, bump_events[0].start_msec) |
88 self.assertEquals(10, bump_events[1]['ts']) | 111 self.assertEquals(10, bump_events[1].start_msec) |
89 | 112 |
90 bump_events = RunHelper(TRACE_EVENTS, 354) | 113 bump_events = RunHelper(TRACE_EVENTS, 354) |
91 self.assertEquals(1, len(bump_events)) | 114 self.assertEquals(1, len(bump_events)) |
92 self.assertEquals(1, bump_events[0]['ts']) | 115 self.assertEquals(1, bump_events[0].start_msec) |
93 | 116 |
94 bump_events = RunHelper(TRACE_EVENTS, 672) | 117 bump_events = RunHelper(TRACE_EVENTS, 672) |
95 self.assertEquals(3, len(bump_events)) | 118 self.assertEquals(3, len(bump_events)) |
96 self.assertEquals(3, bump_events[0]['ts']) | 119 self.assertEquals(3, bump_events[0].start_msec) |
97 self.assertEquals(7, bump_events[1]['ts']) | 120 self.assertEquals(7, bump_events[1].start_msec) |
98 self.assertEquals(12, bump_events[2]['ts']) | 121 self.assertEquals(12, bump_events[2].start_msec) |
99 | 122 |
100 with self.assertRaises(ValueError): | 123 with self.assertRaises(ValueError): |
101 RunHelper(TRACE_EVENTS, 895) | 124 RunHelper(TRACE_EVENTS, 895) |
102 | 125 |
103 def testGetWebPageTrackedEvents(self): | 126 def testGetWebPageTrackedEvents(self): |
104 self.assertTrue(_BLINK_CAT in puller.CATEGORIES) | 127 self.assertTrue(_BLINK_CAT in puller.CATEGORIES) |
105 | 128 |
106 trace_events = puller._GetWebPageTrackedEvents({'traceEvents': [ | 129 trace_events = puller._GetWebPageTrackedEvents(TracingTrack([ |
107 {'ts': 0, 'args': {}, 'cat': 'whatever', 'name': _START}, | 130 {'ph': 'R', 'ts': 0000, 'args': {}, 'cat': 'whatever', |
108 {'ts': 1, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _LOADS}, | 131 'name': _START}, |
109 {'ts': 2, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _LOADE}, | 132 {'ph': 'R', 'ts': 1000, 'args': {'frame': '0'}, 'cat': 'whatever', |
110 {'ts': 3, 'args': {}, 'cat': _BLINK_CAT, 'name': _START}, | 133 'name': _LOADS}, |
111 {'ts': 4, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADS}, | 134 {'ph': 'R', 'ts': 2000, 'args': {'frame': '0'}, 'cat': 'whatever', |
112 {'ts': 5, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADE}, | 135 'name': _LOADE}, |
113 {'ts': 6, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _UNLOAD}, | 136 {'ph': 'R', 'ts': 3000, 'args': {}, 'cat': _BLINK_CAT, |
114 {'ts': 7, 'args': {}, 'cat': _BLINK_CAT, 'name': _START}, | 137 'name': _START}, |
115 {'ts': 8, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADS}, | 138 {'ph': 'R', 'ts': 4000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, |
116 {'ts': 9, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADE}, | 139 'name': _LOADS}, |
117 {'ts': 10, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _UNLOAD}, | 140 {'ph': 'R', 'ts': 5000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, |
118 {'ts': 11, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _START}, | 141 'name': _LOADE}, |
119 {'ts': 12, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _LOADS}, | 142 {'ph': 'R', 'ts': 6000, 'args': {'frame': '0'}, 'cat': 'whatever', |
120 {'ts': 13, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _LOADE}, | 143 'name': _UNLOAD}, |
121 {'ts': 14, 'args': {}, 'cat': _BLINK_CAT, 'name': _START}, | 144 {'ph': 'R', 'ts': 7000, 'args': {}, 'cat': _BLINK_CAT, |
122 {'ts': 15, 'args': {}, 'cat': _BLINK_CAT, 'name': _START}, | 145 'name': _START}, |
123 {'ts': 16, 'args': {'frame': '1'}, 'cat': _BLINK_CAT, 'name': _LOADS}, | 146 {'ph': 'R', 'ts': 8000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, |
124 {'ts': 17, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADS}, | 147 'name': _LOADS}, |
125 {'ts': 18, 'args': {'frame': '1'}, 'cat': _BLINK_CAT, 'name': _LOADE}, | 148 {'ph': 'R', 'ts': 9000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, |
126 {'ts': 19, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADE}, | 149 'name': _LOADE}, |
127 {'ts': 20, 'args': {}, 'cat': 'whatever', 'name': _START}, | 150 {'ph': 'R', 'ts': 10000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, |
128 {'ts': 21, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _LOADS}, | 151 'name': _UNLOAD}, |
129 {'ts': 22, 'args': {'frame': '0'}, 'cat': 'whatever', 'name': _LOADE}, | 152 {'ph': 'R', 'ts': 11000, 'args': {'frame': '0'}, 'cat': 'whatever', |
130 {'ts': 23, 'args': {}, 'cat': _BLINK_CAT, 'name': _START}, | 153 'name': _START}, |
131 {'ts': 24, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADS}, | 154 {'ph': 'R', 'ts': 12000, 'args': {'frame': '0'}, 'cat': 'whatever', |
132 {'ts': 25, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, 'name': _LOADE}]}) | 155 'name': _LOADS}, |
156 {'ph': 'R', 'ts': 13000, 'args': {'frame': '0'}, 'cat': 'whatever', | |
157 'name': _LOADE}, | |
158 {'ph': 'R', 'ts': 14000, 'args': {}, 'cat': _BLINK_CAT, | |
159 'name': _START}, | |
160 {'ph': 'R', 'ts': 15000, 'args': {}, 'cat': _BLINK_CAT, | |
161 'name': _START}, | |
162 {'ph': 'R', 'ts': 16000, 'args': {'frame': '1'}, 'cat': _BLINK_CAT, | |
163 'name': _LOADS}, | |
164 {'ph': 'R', 'ts': 17000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, | |
165 'name': _LOADS}, | |
166 {'ph': 'R', 'ts': 18000, 'args': {'frame': '1'}, 'cat': _BLINK_CAT, | |
167 'name': _LOADE}, | |
168 {'ph': 'R', 'ts': 19000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, | |
169 'name': _LOADE}, | |
170 {'ph': 'R', 'ts': 20000, 'args': {}, 'cat': 'whatever', | |
171 'name': _START}, | |
172 {'ph': 'R', 'ts': 21000, 'args': {'frame': '0'}, 'cat': 'whatever', | |
173 'name': _LOADS}, | |
174 {'ph': 'R', 'ts': 22000, 'args': {'frame': '0'}, 'cat': 'whatever', | |
175 'name': _LOADE}, | |
176 {'ph': 'R', 'ts': 23000, 'args': {}, 'cat': _BLINK_CAT, | |
177 'name': _START}, | |
178 {'ph': 'R', 'ts': 24000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, | |
179 'name': _LOADS}, | |
180 {'ph': 'R', 'ts': 25000, 'args': {'frame': '0'}, 'cat': _BLINK_CAT, | |
181 'name': _LOADE}])) | |
133 | 182 |
134 self.assertEquals(3, len(trace_events)) | 183 self.assertEquals(3, len(trace_events)) |
135 self.assertEquals(14, trace_events['requestStart']['ts']) | 184 self.assertEquals(14, trace_events['requestStart'].start_msec) |
136 self.assertEquals(17, trace_events['loadEventStart']['ts']) | 185 self.assertEquals(17, trace_events['loadEventStart'].start_msec) |
137 self.assertEquals(19, trace_events['loadEventEnd']['ts']) | 186 self.assertEquals(19, trace_events['loadEventEnd'].start_msec) |
138 | 187 |
139 def testPullMetricsFromTrace(self): | 188 def testPullMetricsFromLoadingTrace(self): |
140 metrics = puller._PullMetricsFromTrace(_MINIMALIST_TRACE) | 189 metrics = puller._PullMetricsFromLoadingTrace(LoadingTrace( |
190 _MINIMALIST_TRACE_EVENTS)) | |
141 self.assertEquals(4, len(metrics)) | 191 self.assertEquals(4, len(metrics)) |
142 self.assertEquals(20, metrics['total_load']) | 192 self.assertEquals(20, metrics['total_load']) |
143 self.assertEquals(5, metrics['onload']) | 193 self.assertEquals(5, metrics['onload']) |
144 self.assertEquals(30971, metrics['browser_malloc_avg']) | 194 self.assertEquals(30971, metrics['browser_malloc_avg']) |
145 self.assertEquals(55044, metrics['browser_malloc_max']) | 195 self.assertEquals(55044, metrics['browser_malloc_max']) |
146 | 196 |
147 def testCommandLine(self): | 197 def testCommandLine(self): |
148 tmp_dir = tempfile.mkdtemp() | 198 tmp_dir = tempfile.mkdtemp() |
149 with open(os.path.join(tmp_dir, 'run_infos.json'), 'w') as out_file: | 199 with open(os.path.join(tmp_dir, 'run_infos.json'), 'w') as out_file: |
150 json.dump({'urls': ['a.com', 'b.com', 'c.org']}, out_file) | 200 json.dump({'urls': ['a.com', 'b.com', 'c.org']}, out_file) |
151 for dirname in ['1', '2', 'whatever']: | 201 for dirname in ['1', '2', 'whatever']: |
152 os.mkdir(os.path.join(tmp_dir, dirname)) | 202 os.mkdir(os.path.join(tmp_dir, dirname)) |
153 with open(os.path.join(tmp_dir, dirname, 'trace.json'), 'w') as out_file: | 203 LoadingTrace(_MINIMALIST_TRACE_EVENTS).SaveToJsonFile( |
154 json.dump(_MINIMALIST_TRACE, out_file) | 204 os.path.join(tmp_dir, dirname, 'trace.json')) |
155 | 205 |
156 process = subprocess.Popen(['python', puller.__file__, tmp_dir]) | 206 process = subprocess.Popen(['python', puller.__file__, tmp_dir]) |
157 process.wait() | 207 process.wait() |
158 shutil.rmtree(tmp_dir) | 208 shutil.rmtree(tmp_dir) |
159 | 209 |
160 self.assertEquals(0, process.returncode) | 210 self.assertEquals(0, process.returncode) |
161 | 211 |
162 | 212 |
163 if __name__ == '__main__': | 213 if __name__ == '__main__': |
164 unittest.main() | 214 unittest.main() |
OLD | NEW |