Chromium Code Reviews| Index: tracing/tracing/metrics/vr/frame_cycle_duration_metric_test.html |
| diff --git a/tracing/tracing/metrics/vr/frame_cycle_duration_metric_test.html b/tracing/tracing/metrics/vr/frame_cycle_duration_metric_test.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..daab01aaff7a79046ca612b9a2b52dd9fcade2e4 |
| --- /dev/null |
| +++ b/tracing/tracing/metrics/vr/frame_cycle_duration_metric_test.html |
| @@ -0,0 +1,139 @@ |
| +<!DOCTYPE html> |
| +<!-- |
| +Copyright 2017 The Chromium Authors. All rights reserved. |
| +Use of this source code is governed by a BSD-style license that can be |
| +found in the LICENSE file. |
| +--> |
| + |
| +<link rel="import" href="/tracing/core/test_utils.html"> |
| +<link rel="import" href="/tracing/metrics/vr/frame_cycle_duration_metric.html"> |
| +<link rel="import" href="/tracing/model/model.html"> |
| +<link rel="import" href="/tracing/value/histogram_set.html"> |
| + |
| +<script> |
| +'use strict'; |
| +tr.b.unittest.testSuite(function() { |
|
benjhayden
2017/08/30 18:38:39
I highly recommend reading go/unit-test-practices
tiborg
2017/08/30 22:12:29
Very good read! Would you also suggest splitting t
|
| + const TOLERANCE = 1e-6; |
| + |
| + function createSlice(duration, currentTime) { |
|
benjhayden
2017/08/30 18:38:39
This can be inlined into the sole caller.
tiborg
2017/08/30 22:12:29
Done.
|
| + const option = { |
| + cat: 'gpu', |
| + title: duration.title, |
| + start: currentTime, |
| + end: currentTime + duration.wall, |
| + cpuStart: currentTime, |
| + cpuEnd: currentTime + duration.cpu, |
| + }; |
| + return tr.c.TestUtils.newSliceEx(option); |
| + } |
| + |
| + function createSubSlices(durations, currentTime, sliceGroup) { |
| + if (durations === undefined) { |
| + return []; |
| + } |
| + const slices = []; |
| + durations.forEach(function(duration) { |
|
benjhayden
2017/08/30 18:38:39
Please use for..of instead of forEach:
for (const
tiborg
2017/08/30 22:12:29
Done.
|
| + const slice = createSlice(duration, currentTime); |
| + currentTime += Math.max(duration.wall, duration.cpu) + 1; |
| + slice.subSlices = createSubSlices(duration.sub, currentTime, sliceGroup); |
| + sliceGroup.pushSlice(slice); |
| + slices.push(slice); |
| + }); |
| + return slices; |
| + } |
| + |
| + function createModel(durations) { |
|
benjhayden
2017/08/30 18:38:39
This can be inlined into the sole caller.
tiborg
2017/08/30 22:12:29
Done.
|
| + const model = tr.c.TestUtils.newModel(function(model) { |
| + const process = model.getOrCreateProcess(1); |
| + const thread = process.getOrCreateThread(2); |
| + const group = thread.sliceGroup; |
| + createSubSlices(durations, 0, group); |
| + group.createSubSlices(); |
| + }); |
| + return model; |
| + } |
| + |
| + function getValues(name, histograms) { |
|
benjhayden
2017/08/30 18:38:39
Callers should call getHistogramNamed directly wit
tiborg
2017/08/30 22:12:29
Done.
|
| + return { |
| + wall: histograms.getHistogramNamed(name + ' (Wall Duration)'), |
| + cpu: histograms.getHistogramNamed(name + ' (CPU Duration)'), |
| + }; |
| + } |
| + |
| + function getAvg(durations) { |
|
benjhayden
2017/08/30 18:38:39
This doesn't look necessary. All callers can be re
tiborg
2017/08/30 22:12:29
Done.
|
| + const sum = durations.reduce(function(a, b) { return a + b; }); |
| + return sum / durations.length; |
| + } |
| + |
| + test('frameCycleDurationMetric', function() { |
| + const durations = [ |
| + { |
| + title: 'VrShellGl::DrawFrame', |
| + wall: 25, |
| + cpu: 12, |
| + sub: [ |
| + {title: 'VrShellGl::AcquireFrame', wall: 2, cpu: 2}, |
| + {title: 'VrShellGl::AcquireFrame', wall: 2.5, cpu: 1.5}, |
| + {title: 'VrShellGl::UpdateController', wall: 1, cpu: 0.5}, |
| + {title: 'VrShellGl::UpdateController', wall: 0.5, cpu: 0.4}, |
| + { |
| + title: 'VrShellGl::DrawWorldElements', |
| + wall: 5, |
| + cpu: 3, |
| + sub: [ |
| + {title: 'VrShellGl::DrawUiView', wall: 1.5, cpu: 1}, |
| + {title: 'VrShellGl::DrawUiView', wall: 2, cpu: 1.5}, |
| + ] |
| + }, |
| + {title: 'VrShellGl::DrawWorldElements', wall: 6, cpu: 3}, |
| + {title: 'VrShellGl::DrawFrameSubmitWhenReady', wall: 3, cpu: 0.5}, |
| + { |
| + title: 'VrShellGl::DrawFrameSubmitWhenReady', |
| + wall: 3.5, |
| + cpu: 0.5 |
| + }, |
| + ] |
| + }, |
| + {title: 'VrShellGl::DrawFrame', wall: 20, cpu: 10}, |
| + ]; |
| + const histograms = new tr.v.HistogramSet(); |
| + const model = createModel(durations); |
| + |
| + tr.metrics.vr.frameCycleDurationMetric(histograms, model); |
| + |
| + const drawFrameValues = getValues('draw_frame', histograms); |
| + assert.closeTo(drawFrameValues.wall.average, getAvg([25, 20]), |
| + TOLERANCE); |
| + assert.closeTo(drawFrameValues.cpu.average, getAvg([12, 10]), TOLERANCE); |
| + |
| + const acquireFrameValues = getValues('acquire_frame', histograms); |
| + assert.closeTo(acquireFrameValues.wall.average, getAvg([2, 2.5]), |
| + TOLERANCE); |
| + assert.closeTo(acquireFrameValues.cpu.average, getAvg([2, 1.5]), |
| + TOLERANCE); |
| + |
| + const updateControllerValues = getValues('update_controller', histograms); |
| + assert.closeTo(updateControllerValues.wall.average, getAvg([1, 0.5]), |
| + TOLERANCE); |
| + assert.closeTo(updateControllerValues.cpu.average, getAvg([0.5, 0.4]), |
| + TOLERANCE); |
| + |
| + const drawWorldElementsValues = |
| + getValues('draw_world_elements', histograms); |
| + assert.closeTo(drawWorldElementsValues.wall.average, getAvg([5, 6]), |
| + TOLERANCE); |
| + assert.closeTo(drawWorldElementsValues.cpu.average, getAvg([3, 3]), |
| + TOLERANCE); |
| + |
| + const submitFrameValues = getValues('submit_frame', histograms); |
| + assert.closeTo(submitFrameValues.wall.average, getAvg([3, 3.5]), |
| + TOLERANCE); |
| + assert.closeTo(submitFrameValues.cpu.average, getAvg([0.5, 0.5]), |
| + TOLERANCE); |
| + |
| + const drawUiValues = getValues('draw_ui', histograms); |
| + assert.closeTo(drawUiValues.wall.average, getAvg([1.5, 2]), TOLERANCE); |
| + assert.closeTo(drawUiValues.cpu.average, getAvg([1, 1.5]), TOLERANCE); |
| + }); |
| +}); |
| +</script> |