def testGetDocumentUrl(self): trace = test_utils.LoadingTraceFromEvents([self._REQUEST], self._PAGE_EVENTS) lens = ContentClassificationLens(trace, [], []) self.assertEquals(self._DOCUMENT_URL, lens._GetDocumentUrl()) # Don't be fooled by redirects. request = copy.deepcopy(self._REQUEST) request.status = 302 request.document_url = 'http://www.bla.com' trace = test_utils.LoadingTraceFromEvents([request, self._REQUEST], self._PAGE_EVENTS) lens = ContentClassificationLens(trace, [], []) self.assertEquals(self._DOCUMENT_URL, lens._GetDocumentUrl())
def testConnectionMetrics(self): requests = [request_track.Request.FromJsonDict(copy.deepcopy(self._REQUEST)) for _ in xrange(3)] requests[0].url = 'http://chromium.org/' requests[0].protocol = 'http/1.1' requests[0].timing.connect_start = 12 requests[0].timing.connect_end = 42 requests[0].timing.ssl_start = 50 requests[0].timing.ssl_end = 70 requests[1].url = 'https://chromium.org/where-am-i/' requests[1].protocol = 'h2' requests[1].timing.connect_start = 22 requests[1].timing.connect_end = 73 requests[2].url = 'http://www.chromium.org/here/' requests[2].protocol = 'http/42' trace = test_utils.LoadingTraceFromEvents(requests) stats = metrics.ConnectionMetrics(trace) self.assertEqual(2, stats['connections']) self.assertEqual(81, stats['connection_cost_ms']) self.assertEqual(1, stats['ssl_connections']) self.assertEqual(20, stats['ssl_cost_ms']) self.assertEqual(1, stats['http11_requests']) self.assertEqual(1, stats['h2_requests']) self.assertEqual(0, stats['data_requests']) self.assertEqual(2, stats['domains'])
def testFirstTextPaintLens(self): loading_trace = test_utils.LoadingTraceFromEvents( [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], trace_events=[{ 'ts': 0, 'ph': 'I', 'cat': 'blink.some_other_user_timing', 'name': 'firstPaint' }, { 'ts': 9 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstishPaint' }, { 'ts': 12 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstPaint' }, { 'ts': 22 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstPaint' }]) lens = user_satisfied_lens.FirstTextPaintLens(loading_trace) self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequests()) self.assertEqual(1, lens.PostloadTimeMsec())
def testAdFrame(self): request = copy.deepcopy(self._REQUEST) request.frame_id = '123.123' trace = test_utils.LoadingTraceFromEvents( [request] * 10 + [self._REQUEST] * 5, self._PAGE_EVENTS) lens = ContentClassificationLens(trace, self._RULES, []) self.assertTrue(lens.IsAdFrame(request.frame_id, .5))
def CreateLoadingTrace(cls, trace_events=None): return test_utils.LoadingTraceFromEvents([ cls.FIRST_REDIRECT_REQUEST, cls.SECOND_REDIRECT_REQUEST, cls.REDIRECTED_REQUEST, cls.REQUEST, cls.JS_REQUEST, cls.JS_REQUEST_2, cls.JS_REQUEST_OTHER_FRAME, cls.JS_REQUEST_UNRELATED_FRAME ], cls.PAGE_EVENTS, trace_events)
def testAsyncScriptDependency(self): JS_REQUEST_WITH_ASYNC_STACK = Request.FromJsonDict({ 'url': 'http://bla.com/cat.js', 'request_id': '1234.14', 'initiator': { 'type': 'script', 'stack': { 'callFrames': [], 'parent': { 'callFrames': [{ 'url': 'http://bla.com/nyancat.js' }] } } }, 'timestamp': 10, 'timing': TimingFromDict({}) }) loading_trace = test_utils.LoadingTraceFromEvents( [TestRequests.JS_REQUEST, JS_REQUEST_WITH_ASYNC_STACK]) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(1, len(deps)) self._AssertDependencyIs(deps[0], TestRequests.JS_REQUEST.request_id, JS_REQUEST_WITH_ASYNC_STACK.request_id, 'script')
def testParserDependency(self): loading_trace = test_utils.LoadingTraceFromEvents( [TestRequests.REQUEST, TestRequests.JS_REQUEST]) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(1, len(deps)) self._AssertDependencyIs(deps[0], TestRequests.REQUEST.request_id, TestRequests.JS_REQUEST.request_id, 'parser')
def testScriptDependency(self): loading_trace = test_utils.LoadingTraceFromEvents( [self._JS_REQUEST, self._JS_REQUEST_2]) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(1, len(deps)) self._AssertDependencyIs(deps[0], self._JS_REQUEST.request_id, self._JS_REQUEST_2.request_id, 'script')
def testDependencyDifferentFrame(self): """Checks that a more recent request from another frame is ignored.""" loading_trace = test_utils.LoadingTraceFromEvents([ self._JS_REQUEST, self._JS_REQUEST_OTHER_FRAME, self._JS_REQUEST_2 ]) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(1, len(deps)) self._AssertDependencyIs(deps[0], self._JS_REQUEST.request_id, self._JS_REQUEST_2.request_id, 'script')
def testRedirectDependency(self): loading_trace = test_utils.LoadingTraceFromEvents( [self._REDIRECT_REQUEST, self._REDIRECTED_REQUEST]) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(1, len(deps)) (first, second, reason) = deps[0] self.assertEquals('redirect', reason) self.assertEquals(self._REDIRECT_REQUEST.request_id, first.request_id) self.assertEquals(self._REQUEST.request_id, second.request_id)
def testGetDocumentUrlSeveralChanges(self): request = copy.deepcopy(self._REQUEST) request.status = 200 request.document_url = 'http://www.blabla.com' request2 = copy.deepcopy(request) request2.document_url = 'http://www.blablabla.com' trace = test_utils.LoadingTraceFromEvents( [self._REQUEST, request, request2], self._PAGE_EVENTS) lens = ContentClassificationLens(trace, [], []) self.assertEquals(request2.document_url, lens._GetDocumentUrl())
def testDependencySameParentFrame(self): """Checks that a more recent request from an unrelated frame is ignored if there is one from a related frame.""" loading_trace = test_utils.LoadingTraceFromEvents([ TestRequests.JS_REQUEST_OTHER_FRAME, TestRequests.JS_REQUEST_UNRELATED_FRAME, TestRequests.JS_REQUEST_2 ], TestRequests.PAGE_EVENTS) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(1, len(deps)) self._AssertDependencyIs( deps[0], TestRequests.JS_REQUEST_OTHER_FRAME.request_id, TestRequests.JS_REQUEST_2.request_id, 'script')
def testCantGetNoSatisfaction(self): loading_trace = test_utils.LoadingTraceFromEvents( [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], trace_events=[{ 'ts': 0, 'ph': 'I', 'cat': 'not_my_cat', 'name': 'someEvent' }]) lens = user_satisfied_lens.FirstContentfulPaintLens(loading_trace) self.assertEqual(set(['0.1', '0.2', '0.3']), lens.CriticalRequests()) self.assertEqual(float('inf'), lens.PostloadTimeMsec())
def testSeveralDependencies(self): loading_trace = test_utils.LoadingTraceFromEvents([ self._REDIRECT_REQUEST, self._REDIRECTED_REQUEST, self._JS_REQUEST, self._JS_REQUEST_2 ]) request_dependencies_lens = RequestDependencyLens(loading_trace) deps = request_dependencies_lens.GetRequestDependencies() self.assertEquals(3, len(deps)) self._AssertDependencyIs(deps[0], self._REDIRECT_REQUEST.request_id, self._REQUEST.request_id, 'redirect') self._AssertDependencyIs(deps[1], self._REQUEST.request_id, self._JS_REQUEST.request_id, 'parser') self._AssertDependencyIs(deps[2], self._JS_REQUEST.request_id, self._JS_REQUEST_2.request_id, 'script')
def testGetRedirectChain(self): loading_trace = test_utils.LoadingTraceFromEvents( [TestRequests.FIRST_REDIRECT_REQUEST, TestRequests.SECOND_REDIRECT_REQUEST, TestRequests.REDIRECTED_REQUEST]) request_dependencies_lens = RequestDependencyLens(loading_trace) whole_chain = [TestRequests.FIRST_REDIRECT_REQUEST, TestRequests.SECOND_REDIRECT_REQUEST, TestRequests.REDIRECTED_REQUEST] chain = request_dependencies_lens.GetRedirectChain( TestRequests.FIRST_REDIRECT_REQUEST) self.assertListEqual(whole_chain, chain) chain = request_dependencies_lens.GetRedirectChain( TestRequests.SECOND_REDIRECT_REQUEST) self.assertListEqual(whole_chain[1:], chain) chain = request_dependencies_lens.GetRedirectChain( TestRequests.REDIRECTED_REQUEST) self.assertEquals(whole_chain[2:], chain)
def CreateLoadingTrace(cls, trace_events=None): # This creates a set of requests with the following dependency structure. # # 1234.redirect.1 -> 1234.redirect.2 # 1234.redirect.2 -> 1234.1 # 1234.1 -> 1234.12 # 1234.1 -> 1234.42 # 1234.1 -> 1234.56 # 1234.12 -> 1234.13 trace = test_utils.LoadingTraceFromEvents( [cls.FIRST_REDIRECT_REQUEST, cls.SECOND_REDIRECT_REQUEST, cls.REDIRECTED_REQUEST, cls.REQUEST, cls.JS_REQUEST, cls.JS_REQUEST_2, cls.JS_REQUEST_OTHER_FRAME, cls.JS_REQUEST_UNRELATED_FRAME], cls.PAGE_EVENTS, trace_events) # Serialize and deserialize so that clients can change events without # affecting future tests. return LoadingTrace.FromJsonDict(trace.ToJsonDict())
def testAdAndTrackingRequests(self): ad_request = copy.deepcopy(self._REQUEST) ad_request.request_id = '1234.2' ad_request.frame_id = '123.123' non_ad_request_non_ad_frame = copy.deepcopy(self._REQUEST) non_ad_request_non_ad_frame.request_id = '1234.3' non_ad_request_non_ad_frame.url = 'http://www.example.com' non_ad_request_non_ad_frame.frame_id = '123.456' non_ad_request_ad_frame = copy.deepcopy(self._REQUEST) non_ad_request_ad_frame.request_id = '1234.4' non_ad_request_ad_frame.url = 'http://www.example.com' non_ad_request_ad_frame.frame_id = ad_request.frame_id trace = test_utils.LoadingTraceFromEvents([ self._REQUEST, ad_request, non_ad_request_non_ad_frame, non_ad_request_ad_frame ], self._PAGE_EVENTS) lens = ContentClassificationLens(trace, self._RULES, []) self.assertSetEqual( set([self._REQUEST, ad_request, non_ad_request_ad_frame]), set(lens.AdAndTrackingRequests()))
def testUserSatisfiedLens(self): # We track all times in milliseconds, but raw trace events are in # microseconds. MILLI_TO_MICRO = 1000 loading_trace = test_utils.LoadingTraceFromEvents( [self._RequestAt(1), self._RequestAt(10), self._RequestAt(20)], trace_events=[{ 'ts': 0, 'ph': 'I', 'cat': 'blink.some_other_user_timing', 'name': 'firstContentfulPaint' }, { 'ts': 9 * MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstDiscontentPaint' }, { 'ts': 12 * MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstContentfulPaint' }, { 'ts': 22 * MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'firstContentfulPaint' }]) graph = loading_model.ResourceGraph(loading_trace) lens = user_satisfied_lens.UserSatisfiedLens(loading_trace, graph) for n in graph.Nodes(): if n.Request().frame_id == '123.20': self.assertFalse(lens.Filter(n)) else: self.assertTrue(lens.Filter(n))
def _ActivityLens(self, requests, raw_events): loading_trace = test_utils.LoadingTraceFromEvents( requests, None, raw_events) return ActivityLens(loading_trace)
def CreateTrace(self, requests, events, main_frame_id): loading_trace = test_utils.LoadingTraceFromEvents(requests, trace_events=events) loading_trace.tracing_track.SetMainFrameID(main_frame_id) loading_trace.url = 'http://www.dummy.com' return loading_trace
def testFirstSignificantPaintLens(self): loading_trace = test_utils.LoadingTraceFromEvents( [ self._RequestAt(1), self._RequestAt(10), self._RequestAt(15), self._RequestAt(20) ], trace_events=[{ 'ts': 0, 'ph': 'I', 'cat': 'blink', 'name': 'firstPaint' }, { 'ts': 9 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink.user_timing', 'name': 'FrameView::SynchronizedPaint' }, { 'ts': 18 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink', 'name': 'FrameView::SynchronizedPaint' }, { 'ts': 22 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'blink', 'name': 'FrameView::SynchronizedPaint' }, { 'ts': 5 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'foobar', 'name': 'biz', 'args': { 'counters': { 'LayoutObjectsThatHadNeverHadLayout': 10 } } }, { 'ts': 12 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'foobar', 'name': 'biz', 'args': { 'counters': { 'LayoutObjectsThatHadNeverHadLayout': 12 } } }, { 'ts': 15 * self.MILLI_TO_MICRO, 'ph': 'I', 'cat': 'foobar', 'name': 'biz', 'args': { 'counters': { 'LayoutObjectsThatHadNeverHadLayout': 10 } } }]) lens = user_satisfied_lens.FirstSignificantPaintLens(loading_trace) self.assertEqual(set(['0.1', '0.2']), lens.CriticalRequests()) self.assertEqual(7, lens.PostloadTimeMsec())
def testRequestQueuing(self): # http://1: queued at 5ms, request start at 10ms, ready at 11ms, # done at 12ms; blocked by 2. # http://2: queued at 4ms, request start at 4ms, ready at 5 ms, done at 9ms. trace_events = [{ 'args': { 'data': { 'request_url': self.URL_1, 'source_id': 1 } }, 'cat': QueuingLens.QUEUING_CATEGORY, 'id': 1, 'name': QueuingLens.ASYNC_NAME, 'ph': 'b', 'ts': 5 * self.MILLIS_TO_MICROS }, { 'args': { 'data': { 'source_id': 1 } }, 'cat': QueuingLens.QUEUING_CATEGORY, 'id': 1, 'name': QueuingLens.READY_NAME, 'ph': 'n', 'ts': 10 * self.MILLIS_TO_MICROS }, { 'args': { 'data': { 'source_id': 1 } }, 'cat': QueuingLens.QUEUING_CATEGORY, 'id': 1, 'name': QueuingLens.ASYNC_NAME, 'ph': 'e', 'ts': 12 * self.MILLIS_TO_MICROS }, { 'args': { 'data': { 'request_url': self.URL_2, 'source_id': 2 } }, 'cat': QueuingLens.QUEUING_CATEGORY, 'id': 2, 'name': QueuingLens.ASYNC_NAME, 'ph': 'b', 'ts': 4 * self.MILLIS_TO_MICROS }, { 'args': { 'data': { 'source_id': 2 } }, 'cat': QueuingLens.QUEUING_CATEGORY, 'id': 2, 'name': QueuingLens.READY_NAME, 'ph': 'n', 'ts': 5 * self.MILLIS_TO_MICROS }, { 'args': { 'data': { 'source_id': 2 } }, 'cat': QueuingLens.QUEUING_CATEGORY, 'id': 2, 'name': QueuingLens.ASYNC_NAME, 'ph': 'e', 'ts': 9 * self.MILLIS_TO_MICROS }] requests = [ request_track.Request.FromJsonDict({ 'url': self.URL_1, 'request_id': '0.1', 'timing': { 'request_time': 10 * self.MILLIS_TO_SECONDS, 'loading_finished': 2 } }), request_track.Request.FromJsonDict({ 'url': self.URL_2, 'request_id': '0.2', 'timing': { 'request_time': 4 * self.MILLIS_TO_SECONDS, 'loading_finished': 5 } }) ] trace = test_utils.LoadingTraceFromEvents(requests=requests, trace_events=trace_events) queue_info = QueuingLens(trace).GenerateRequestQueuing() self.assertEqual( set(['0.2']), set(rq.request_id for rq in queue_info[requests[0]].blocking)) self.assertEqual((5., 10., 12.), (queue_info[requests[0]].start_msec, queue_info[requests[0]].ready_msec, queue_info[requests[0]].end_msec)) self.assertEqual(0, len(queue_info[requests[1]].blocking)) self.assertEqual((4., 5., 9.), (queue_info[requests[1]].start_msec, queue_info[requests[1]].ready_msec, queue_info[requests[1]].end_msec))
def _NetworkActivityLens(self, requests): trace = test_utils.LoadingTraceFromEvents(requests) return NetworkActivityLens(trace)
def _MakeTrace(cls): request = request_track.Request.FromJsonDict( copy.deepcopy(cls._REQUEST)) return test_utils.LoadingTraceFromEvents([request])
def _GraphFromRequests(cls, requests): trace = test_utils.LoadingTraceFromEvents(requests) deps_lens = test_utils.SimpleLens(trace) return dependency_graph.RequestDependencyGraph(requests, deps_lens)
def testMainFrameIsNotAnAdFrame(self): trace = test_utils.LoadingTraceFromEvents([self._REQUEST], self._PAGE_EVENTS) lens = ContentClassificationLens(trace, self._RULES, []) self.assertFalse(lens.IsAdOrTrackingFrame(self._MAIN_FRAME_ID))
def testTrackingRequest(self): trace = test_utils.LoadingTraceFromEvents([self._REQUEST], self._PAGE_EVENTS) lens = ContentClassificationLens(trace, [], self._RULES) self.assertFalse(lens.IsAdRequest(self._REQUEST)) self.assertTrue(lens.IsTrackingRequest(self._REQUEST))