blob: d2c1e38a7d23530f0d82cb792bf3fdbbe5783549 [file] [log] [blame]
# Copyright 2013 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.
import os
import unittest
from telemetry import story
from telemetry import page as page_module
from telemetry import value
from telemetry.value import improvement_direction
from telemetry.value import list_of_scalar_values
from telemetry.value import none_values
class StatisticComputationTest(unittest.TestCase):
def testVariance(self):
self.assertAlmostEqual(
list_of_scalar_values.Variance([]), 0)
self.assertAlmostEqual(
list_of_scalar_values.Variance([3]), 0)
self.assertAlmostEqual(
list_of_scalar_values.Variance([600, 470, 170, 430, 300]), 27130)
def testStandardDeviation(self):
self.assertAlmostEqual(
list_of_scalar_values.StandardDeviation([]), 0)
self.assertAlmostEqual(
list_of_scalar_values.StandardDeviation([1]), 0)
self.assertAlmostEqual(
list_of_scalar_values.StandardDeviation([600, 470, 170, 430, 300]),
164.71186, places=4)
def testPooledVariance(self):
self.assertAlmostEqual(
list_of_scalar_values.PooledStandardDeviation([[], [], []]), 0)
self.assertAlmostEqual(
list_of_scalar_values.PooledStandardDeviation([[1], [], [3], []]), 0)
self.assertAlmostEqual(
list_of_scalar_values.PooledStandardDeviation([[1], [2], [3], [4]]), 0)
self.assertAlmostEqual(list_of_scalar_values.PooledStandardDeviation(
[[600, 470, 170, 430, 300], # variance = 27130, std = 164.7
[4000, 4020, 4230], # variance = 16233, std = 127.41
[260, 700, 800, 900, 0, 120, 150]]), # variance = 136348, std = 369.2
282.7060, # SQRT((27130 4 + 16233*2 + 136348*6)/12)
places=4)
self.assertAlmostEqual(list_of_scalar_values.PooledStandardDeviation(
[[600, 470, 170, 430, 300],
[4000, 4020, 4230],
[260, 700, 800, 900, 0, 120, 150]],
list_of_variances=[100000, 200000, 300000]),
465.47466, # SQRT((100000*4 + 200000* 2 + 300000*6)/12)
places=4)
class TestBase(unittest.TestCase):
def setUp(self):
story_set = story.StorySet(base_dir=os.path.dirname(__file__))
story_set.AddStory(
page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
story_set.AddStory(
page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
story_set.AddStory(
page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
self.story_set = story_set
@property
def pages(self):
return self.story_set.stories
class ValueTest(TestBase):
def testRepr(self):
page = self.pages[0]
v = list_of_scalar_values.ListOfScalarValues(
page, 'x', 'unit', [10, 9, 9, 7], important=True, description='desc',
tir_label='my_ir', std=42,
improvement_direction=improvement_direction.DOWN)
expected = ('ListOfScalarValues(http://www.bar.com/, x, unit, '
'[10, 9, 9, 7], important=True, description=desc, '
'tir_label=my_ir, std=42, '
'improvement_direction=down, grouping_keys={})')
self.assertEquals(expected, str(v))
def testListSamePageMerging(self):
page0 = self.pages[0]
v0 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
[10, 9, 9, 7], description='list-based metric',
improvement_direction=improvement_direction.DOWN)
v1 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
[300, 302, 303, 304], description='list-based metric',
improvement_direction=improvement_direction.DOWN)
self.assertTrue(v1.IsMergableWith(v0))
vM = (list_of_scalar_values.ListOfScalarValues.
MergeLikeValuesFromSamePage([v0, v1]))
self.assertEquals(page0, vM.page)
self.assertEquals('x', vM.name)
self.assertEquals('unit', vM.units)
self.assertEquals(True, vM.important)
self.assertEquals([10, 9, 9, 7, 300, 302, 303, 304], vM.values)
# Values from the same page use regular standard deviation.
self.assertAlmostEqual(156.88849, vM.std, places=4)
self.assertEquals('list-based metric', vM.description)
self.assertEquals(improvement_direction.DOWN, vM.improvement_direction)
def testListDifferentPageMerging(self):
page0 = self.pages[0]
page1 = self.pages[1]
v0 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
[10, 9, 9, 7], improvement_direction=improvement_direction.DOWN)
v1 = list_of_scalar_values.ListOfScalarValues(
page1, 'x', 'unit',
[300, 302, 303, 304], improvement_direction=improvement_direction.DOWN)
self.assertTrue(v1.IsMergableWith(v0))
vM = (list_of_scalar_values.ListOfScalarValues.
MergeLikeValuesFromDifferentPages([v0, v1]))
self.assertEquals(None, vM.page)
self.assertEquals('x', vM.name)
self.assertEquals('unit', vM.units)
self.assertEquals(True, vM.important)
self.assertEquals([10, 9, 9, 7, 300, 302, 303, 304], vM.values)
# Values from different pages use pooled standard deviation.
# SQRT((19/12 * 3 + 35/12 * 3)/6) = 1.5
self.assertAlmostEqual(1.5, vM.std)
self.assertEquals(improvement_direction.DOWN, vM.improvement_direction)
def testListWithNoneValueMerging(self):
page0 = self.pages[0]
v0 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
[1, 2], improvement_direction=improvement_direction.UP)
v1 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
None, none_value_reason='n',
improvement_direction=improvement_direction.UP)
self.assertTrue(v1.IsMergableWith(v0))
vM = (list_of_scalar_values.ListOfScalarValues.
MergeLikeValuesFromSamePage([v0, v1]))
self.assertEquals(None, vM.values)
expected_none_value_reason = (
'Merging values containing a None value results in a None value. '
'None values: [ListOfScalarValues(http://www.bar.com/, x, unit, None, '
'important=True, description=None, tir_label=None, std=None,'
' improvement_direction=up, grouping_keys={})]')
self.assertEquals(expected_none_value_reason, vM.none_value_reason)
self.assertEquals(improvement_direction.UP, vM.improvement_direction)
def testListWithNoneValueMustHaveNoneReason(self):
page0 = self.pages[0]
self.assertRaises(none_values.NoneValueMissingReason,
lambda: list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit', None,
improvement_direction=improvement_direction.DOWN))
def testListWithNoneReasonMustHaveNoneValue(self):
page0 = self.pages[0]
self.assertRaises(none_values.ValueMustHaveNoneValue,
lambda: list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit', [1, 2],
none_value_reason='n',
improvement_direction=improvement_direction.UP))
def testAsDict(self):
v = list_of_scalar_values.ListOfScalarValues(
None, 'x', 'unit', [1, 2],
important=False, improvement_direction=improvement_direction.DOWN)
d = v.AsDictWithoutBaseClassEntries()
self.assertEquals(d['values'], [1, 2])
self.assertAlmostEqual(d['std'], 0.7071, places=4)
def testMergedValueAsDict(self):
page0 = self.pages[0]
v0 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
[10, 9, 9, 7], improvement_direction=improvement_direction.DOWN)
v1 = list_of_scalar_values.ListOfScalarValues(
page0, 'x', 'unit',
[300, 302, 303, 304], improvement_direction=improvement_direction.DOWN)
self.assertTrue(v1.IsMergableWith(v0))
vM = (list_of_scalar_values.ListOfScalarValues.
MergeLikeValuesFromSamePage([v0, v1]))
d = vM.AsDict()
self.assertEquals(d['values'], [10, 9, 9, 7, 300, 302, 303, 304])
# Values from the same page use regular standard deviation.
self.assertAlmostEqual(d['std'], 156.88849, places=4)
def testNoneValueAsDict(self):
v = list_of_scalar_values.ListOfScalarValues(
None, 'x', 'unit', None,
important=False, none_value_reason='n',
improvement_direction=improvement_direction.UP)
d = v.AsDictWithoutBaseClassEntries()
self.assertEquals(d, {
'values': None,
'none_value_reason': 'n',
'std': None
})
def testFromDictInts(self):
d = {
'type': 'list_of_scalar_values',
'name': 'x',
'units': 'unit',
'values': [1, 2],
'std': 0.7071,
'improvement_direction': improvement_direction.DOWN
}
v = value.Value.FromDict(d, {})
self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
self.assertEquals(v.values, [1, 2])
self.assertEquals(v.std, 0.7071)
self.assertEquals(improvement_direction.DOWN, v.improvement_direction)
def testFromDictFloats(self):
d = {
'type': 'list_of_scalar_values',
'name': 'x',
'units': 'unit',
'values': [1.3, 2.7, 4.5, 2.1, 3.4],
'std': 0.901,
'improvement_direction': improvement_direction.UP
}
v = value.Value.FromDict(d, {})
self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
self.assertEquals(v.values, [1.3, 2.7, 4.5, 2.1, 3.4])
self.assertEquals(v.std, 0.901)
def testFromDictWithoutImprovementDirection(self):
d = {
'type': 'list_of_scalar_values',
'name': 'x',
'units': 'unit',
'values': [1, 2],
'std': 0.7071,
}
v = value.Value.FromDict(d, {})
self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
self.assertIsNone(v.improvement_direction)
def testFromDictNoneValue(self):
d = {
'type': 'list_of_scalar_values',
'name': 'x',
'units': 'unit',
'values': None,
'std': None,
'none_value_reason': 'n',
'improvement_direction': improvement_direction.DOWN
}
v = value.Value.FromDict(d, {})
self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
self.assertEquals(v.values, None)
self.assertEquals(v.none_value_reason, 'n')