| Index: tracing/tracing/extras/chrome/estimated_input_latency_test.html
|
| diff --git a/tracing/tracing/extras/chrome/estimated_input_latency_test.html b/tracing/tracing/extras/chrome/estimated_input_latency_test.html
|
| index eaece9222cdce0df4f819414aaad96c98d755ca6..7a4b167f009886e4e898e5f409f8850923cfbf05 100644
|
| --- a/tracing/tracing/extras/chrome/estimated_input_latency_test.html
|
| +++ b/tracing/tracing/extras/chrome/estimated_input_latency_test.html
|
| @@ -8,6 +8,7 @@ found in the LICENSE file.
|
| <link rel="import" href="/tracing/base/assert_utils.html">
|
| <link rel="import" href="/tracing/core/test_utils.html">
|
| <link rel="import" href="/tracing/extras/chrome/estimated_input_latency.html">
|
| +<link rel="import" href="/tracing/metrics/system_health/loading_metric.html">
|
| <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html">
|
|
|
| <script>
|
| @@ -15,6 +16,7 @@ found in the LICENSE file.
|
|
|
| tr.b.unittest.testSuite(function() {
|
|
|
| + var getInteractiveTimestamps = tr.e.chrome.getInteractiveTimestamps;
|
| var getPostInteractiveTaskWindows = tr.e.chrome.getPostInteractiveTaskWindows;
|
| var getNavStartTimestamps = tr.e.chrome.getNavStartTimestamps;
|
| var assertRangeEquals = tr.b.assertRangeEquals;
|
| @@ -37,45 +39,135 @@ tr.b.unittest.testSuite(function() {
|
| });
|
| }
|
|
|
| + function newSchedulerTask(startTime, duration) {
|
| + return tr.c.TestUtils.newSliceEx({
|
| + cat: 'toplevel',
|
| + title: 'TaskQueueManager::ProcessTaskFromWorkQueue',
|
| + start: startTime,
|
| + duration: duration
|
| + });
|
| + }
|
| +
|
| + /**
|
| + * Adds a FrameLoader snapshot to rendererProcess that is used by test FMP
|
| + * candidate slices.
|
| + */
|
| + function addTestFrame(rendererProcess) {
|
| + rendererProcess.objects.addSnapshot(
|
| + 'ptr', 'loading', 'FrameLoader', 300, {
|
| + isLoadingMainFrame: true,
|
| + frame: {id_ref: '0xdeadbeef'},
|
| + documentLoaderURL: 'http://example.com'
|
| + });
|
| + }
|
| +
|
| + function addNavigationStart(mainThread, startNavTime) {
|
| + mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
|
| + cat: 'blink.user_timing',
|
| + title: 'navigationStart',
|
| + start: startNavTime,
|
| + duration: 0.0,
|
| + args: {frame: '0xdeadbeef'}
|
| + }));
|
| + }
|
| +
|
| + function addFMPCandidate(mainThread, fmpTime) {
|
| + mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
|
| + cat: 'loading',
|
| + title: 'firstMeaningfulPaintCandidate',
|
| + start: fmpTime,
|
| + duration: 0.0,
|
| + args: {frame: '0xdeadbeef'}
|
| + }));
|
| + }
|
| +
|
| + function addSchedulerTask(mainThread, startTime, duration) {
|
| + mainThread.sliceGroup.pushSlice(newSchedulerTask(startTime, duration));
|
| + }
|
| +
|
| + function addDummyTask(mainThread, startTime) {
|
| + mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
|
| + cat: 'dummy',
|
| + title: 'dummyTitle',
|
| + start: startTime,
|
| + duration: 0.0
|
| + }));
|
| + }
|
| +
|
| test('getNavStartTimestamps', () => {
|
| var model = createTestModel(rendererProcess => {
|
| var mainThread = rendererProcess.getOrCreateThread(MAIN_THREAD_ID);
|
| - mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
|
| - cat: 'blink.user_timing',
|
| - title: 'navigationStart',
|
| - start: 0,
|
| - duration: 0.0,
|
| - args: {frame: '0xdeadbeef'}
|
| - }));
|
| -
|
| - mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
|
| - cat: 'blink.user_timing',
|
| - title: 'navigationStart',
|
| - start: 10,
|
| - duration: 0.0,
|
| - args: {frame: '0xdeadbeef'}
|
| - }));
|
| -
|
| - mainThread.sliceGroup.pushSlice(tr.c.TestUtils.newSliceEx({
|
| - cat: 'blink.user_timing',
|
| - title: 'navigationStart',
|
| - start: 30,
|
| - duration: 0.0,
|
| - args: {frame: '0xdeadbeef'}
|
| - }));
|
| + addNavigationStart(mainThread, 0);
|
| + addNavigationStart(mainThread, 10);
|
| + addNavigationStart(mainThread, 30);
|
| });
|
|
|
| var chromeHelper = model.getOrCreateHelper(
|
| tr.model.helpers.ChromeModelHelper);
|
| var rendererHelper = chromeHelper.rendererHelpers[RENDERER_PROCESS_ID];
|
| var navStartTimestamps = getNavStartTimestamps(rendererHelper);
|
| - assert.equal(navStartTimestamps.length, 3);
|
|
|
| // It is ok to assert equality for floating point numbers here because
|
| // the timestamps should remain unmodified.
|
| assert.deepEqual(navStartTimestamps, [0, 10, 30]);
|
| });
|
|
|
| + /**
|
| + * Checks getInteractiveTimestamps works as intended. If the definition of
|
| + * TTI metric changes, this test may begin to fail and we may need to adjust
|
| + * our EIL implementation.
|
| + */
|
| + test('getInteractiveTimestamps', () => {
|
| + var model = createTestModel(rendererProcess => {
|
| + addTestFrame(rendererProcess);
|
| +
|
| + var mainThread = rendererProcess.getOrCreateThread(MAIN_THREAD_ID);
|
| + addNavigationStart(mainThread, 0);
|
| + addFMPCandidate(mainThread, 5000);
|
| +
|
| + addNavigationStart(mainThread, 100000);
|
| + addFMPCandidate(mainThread, 110000);
|
| +
|
| + // To detect when a page has become interactive, we need to find a large
|
| + // enough window of no long tasks. Adding a dummy task sufficiently far
|
| + // away extends the bounds of the model so that it can contain this
|
| + // window. In a non-test scenario, we always record traces for long enough
|
| + // that this is not an issue.
|
| + addDummyTask(mainThread, 900000);
|
| + });
|
| +
|
| + var interactiveTimestampsMap = getInteractiveTimestamps(model);
|
| + var interactiveTimestamps =
|
| + interactiveTimestampsMap.get(RENDERER_PROCESS_ID);
|
| + assert.deepEqual(
|
| + interactiveTimestamps.sort((a, b) => a - b), [5000, 110000]);
|
| + });
|
| +
|
| + test('getInteractiveTimestampsMultiRenderer', () => {
|
| + var model = tr.c.TestUtils.newModel(model => {
|
| + var rendererProcesses = [];
|
| + for (var pid = 1; pid <= 5; pid++) {
|
| + var rendererProcess = model.getOrCreateProcess(pid);
|
| + var mainThread = rendererProcess.getOrCreateThread(pid + 10);
|
| + mainThread.name = 'CrRendererMain';
|
| +
|
| + addTestFrame(rendererProcess);
|
| + addNavigationStart(mainThread, pid * 1000);
|
| + addFMPCandidate(mainThread, pid * 1000 + 2000);
|
| + addNavigationStart(mainThread, pid * 2000);
|
| + addFMPCandidate(mainThread, pid * 2000 + 2000);
|
| + addDummyTask(mainThread, 100000);
|
| + }
|
| + });
|
| +
|
| + var interactiveTimestampsMap = getInteractiveTimestamps(model);
|
| + for (var [pid, interactiveTimestamps] of interactiveTimestampsMap) {
|
| + assert.deepEqual(
|
| + interactiveTimestamps.sort((a, b) => a - b),
|
| + [pid * 1000 + 2000, pid * 2000 + 2000]);
|
| + }
|
| + });
|
| +
|
| test('singlePostInteractiveWindow', () => {
|
| var interactiveTimestamps = [50];
|
| var navStartTimestamps = [0];
|
|
|