1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
7 from telemetry
.testing
import simple_mock
9 from metrics
import webrtc_stats
16 "googFrameHeightInput":"480",
17 "googFrameWidthInput":"640",
18 "googFrameRateSent": "23",
25 "audioInputLevel":"2048",
27 "googCodecName":"opus",
34 "googFrameHeightInput":"480",
35 "googFrameWidthInput":"640",
36 "googFrameRateSent": "21",
43 "audioInputLevel":"1878",
45 "googCodecName":"opus",
52 "googAvailableSendBandwidth":"30000",
53 "googAvailableRecvBandwidth":"12345",
54 "googTargetEncBitrate":"10000"
61 "googFrameRateReceived": "23",
63 "packetsReceived":"8",
64 "googRenderDelayMs":"10",
65 "googMaxDecodeMs":"0",
71 "googFrameRateReceived": "23",
73 "packetsReceived":"1234",
74 "googRenderDelayMs":"102",
75 "googMaxDecodeMs":"150",
81 "googAvailableSendBandwidth":"40000",
82 "googAvailableRecvBandwidth":"22345",
83 "googTargetEncBitrate":"20000"
90 class FakeResults(object):
91 def __init__(self
, current_page
):
92 self
._received
_values
= []
93 self
._current
_page
= current_page
96 def received_values(self
):
97 return self
._received
_values
100 def current_page(self
):
101 return self
._current
_page
103 def AddValue(self
, value
):
104 self
._received
_values
.append(value
)
107 class WebRtcStatsUnittest(unittest
.TestCase
):
109 def _RunMetricOnJson(self
, json_to_return
):
110 stats_metric
= webrtc_stats
.WebRtcStatisticsMetric()
112 tab
= simple_mock
.MockObject()
113 page
= simple_mock
.MockObject()
115 stats_metric
.Start(page
, tab
)
117 tab
.ExpectCall('EvaluateJavaScript',
118 simple_mock
.DONT_CARE
).WillReturn(json_to_return
)
119 stats_metric
.Stop(page
, tab
)
121 page
.url
= simple_mock
.MockObject()
122 results
= FakeResults(page
)
123 stats_metric
.AddResults(tab
, results
)
126 def testExtractsValuesAsTimeSeries(self
):
127 results
= self
._RunMetricOnJson
(SAMPLE_JSON
)
129 self
.assertTrue(results
.received_values
,
130 'Expected values for googDecodeMs and others, got none.')
132 # This also ensures we're clever enough to tell video packetsSent from audio
134 self
.assertEqual(results
.received_values
[3].values
,
136 self
.assertEqual(results
.received_values
[5].values
,
139 def testExtractsInterestingMetricsOnly(self
):
140 results
= self
._RunMetricOnJson
(SAMPLE_JSON
)
142 self
.assertTrue(len(results
.received_values
) > 0)
143 self
.assertIn('peer_connection_0', results
.received_values
[0].name
,
144 'The result should be a ListOfScalarValues instance with '
145 'a name <peer connection id>_<statistic>.')
146 all_names
= [value
.name
for value
in results
.received_values
]
147 self
.assertIn('peer_connection_0_video_packets_sent', all_names
)
148 self
.assertNotIn('peer_connection_1_video_packets_sent', all_names
,
149 'Peer connection 1 does not have a video packets sent in '
150 'the JSON above, unlike peer connection 0 which does.')
151 self
.assertIn('peer_connection_0_video_goog_rtt', all_names
)
152 self
.assertIn('peer_connection_1_video_goog_rtt', all_names
)
153 # The audio_audio is intentional since the code distinguishes audio repots
154 # from video reports (even though audio_input_level is quite obvious).
155 self
.assertNotIn('peer_connection_0_audio_audio_input_level', all_names
,
156 'Input level is in the JSON for both connections but '
157 'should not be reported since it is not interesting.')
158 self
.assertNotIn('peer_connection_1_audio_audio_input_level', all_names
)
160 def testReturnsIfJsonIsEmpty(self
):
161 results
= self
._RunMetricOnJson
('[]')
162 self
.assertFalse(results
.received_values
)