fbe5836d86
- Adds new median metric both on CLI and HTML reports. - Adds supports for table header that consolidates units from each metric, and gives a title. - Re-organizes metrics based on order statistics (min, percentiles, max) then its followed by aggregate statistics metrics. - Includes unit tests. Change-Id: Icd154c9f00b5e9d6df11797685fe8f92c4fdbb1b
164 lines
5.4 KiB
Python
164 lines
5.4 KiB
Python
# Copyright 2014: Mirantis Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from rally.benchmark.processing import utils
|
|
from rally import exceptions
|
|
from tests.unit import test
|
|
|
|
|
|
class MathTestCase(test.TestCase):
|
|
|
|
def test_percentile(self):
|
|
lst = list(range(1, 101))
|
|
result = utils.percentile(lst, 0.1)
|
|
self.assertEqual(result, 10.9)
|
|
|
|
def test_percentile_value_none(self):
|
|
result = utils.percentile(None, 0.1)
|
|
self.assertIsNone(result)
|
|
|
|
def test_percentile_equal(self):
|
|
lst = list(range(1, 101))
|
|
result = utils.percentile(lst, 1)
|
|
self.assertEqual(result, 100)
|
|
|
|
def test_mean(self):
|
|
lst = list(range(1, 100))
|
|
result = utils.mean(lst)
|
|
self.assertEqual(result, 50.0)
|
|
|
|
def test_mean_empty_list(self):
|
|
lst = []
|
|
self.assertRaises(exceptions.InvalidArgumentsException,
|
|
utils.mean, lst)
|
|
|
|
def test_median_single_value(self):
|
|
lst = [5]
|
|
result = utils.median(lst)
|
|
self.assertEqual(5, result)
|
|
|
|
def test_median_odd_sized_list(self):
|
|
lst = [1, 2, 3, 4, 5]
|
|
result = utils.median(lst)
|
|
self.assertEqual(3, result)
|
|
|
|
def test_median_even_sized_list(self):
|
|
lst = [1, 2, 3, 4]
|
|
result = utils.median(lst)
|
|
self.assertEqual(2.5, result)
|
|
|
|
def test_median_empty_list(self):
|
|
lst = []
|
|
self.assertRaises(ValueError,
|
|
utils.median, lst)
|
|
|
|
lst = None
|
|
self.assertRaises(ValueError,
|
|
utils.median, lst)
|
|
|
|
def _compare_items_lists(self, list1, list2):
|
|
"""Items lists comparison, compatible with Python 2.6/2.7.
|
|
|
|
:param list1: items list [(a1, b1), (a2, b2) ...]
|
|
:param list2: items list [(a1, b1), (a2, b2) ...]
|
|
"""
|
|
compare_float = lambda f1, f2: abs(f2 - f2) < 0.1
|
|
for a, b in zip(list1, list2):
|
|
a1, a2, b1, b2 = (a + b)
|
|
self.assertEqual(a1, b1)
|
|
if type(a2) is float:
|
|
# Float representation is defferent in Python 2.6/2.7,
|
|
# so we need to be sure that values are close to each other
|
|
self.assertTrue(compare_float(a2, b2))
|
|
else:
|
|
self.assertEqual(a2, b2)
|
|
|
|
def test_compress(self):
|
|
data64 = range(64)
|
|
data4 = [4, 2, 1, 3]
|
|
mixed = [2, "5", None, 0.5]
|
|
alt_normalize = str
|
|
alt_merge = lambda a, b: str(a) + str(b)
|
|
compress = lambda lst: [(k + 1, float(v)) for k, v in enumerate(lst)]
|
|
|
|
# Long list
|
|
self.assertEqual(utils.compress(data64), compress(data64))
|
|
self._compare_items_lists(
|
|
utils.compress(data64, limit=4),
|
|
[(17, 15.0), (33, 31.01), (49, 47.0), (64, 62.0)])
|
|
self.assertEqual(
|
|
utils.compress(data64, limit=4,
|
|
normalize=alt_normalize, merge=alt_merge),
|
|
[(17, "012345678910111213141516"),
|
|
(33, "17181920212223242526272829303132"),
|
|
(49, "33343536373839404142434445464748"),
|
|
(64, "495051525354555657585960616263")])
|
|
|
|
# Short list
|
|
self.assertEqual(utils.compress(data4, limit=2),
|
|
[(3, 2.0), (4, 3.0)])
|
|
self.assertEqual(utils.compress(data4, normalize=alt_normalize),
|
|
[(1, "4"), (2, "2"), (3, "1"), (4, "3")])
|
|
|
|
# List with mixed data types
|
|
self.assertEqual(utils.compress(mixed),
|
|
[(1, 2.0), (2, 5.0), (3, 0.0), (4, 0.5)])
|
|
self.assertEqual(utils.compress(mixed, normalize=str),
|
|
[(1, "2"), (2, "5"), (3, "None"), (4, "0.5")])
|
|
self.assertRaises(TypeError, utils.compress, mixed, normalize=int)
|
|
self.assertEqual(
|
|
utils.compress(mixed, normalize=alt_normalize, merge=alt_merge),
|
|
[(1, "2"), (2, "5"), (3, "None"), (4, "0.5")])
|
|
|
|
|
|
class AtomicActionsDataTestCase(test.TestCase):
|
|
|
|
def test_get_atomic_actions_data(self):
|
|
raw_data = [
|
|
{
|
|
"error": [],
|
|
"duration": 3,
|
|
"atomic_actions": {
|
|
"action1": 1,
|
|
"action2": 2
|
|
}
|
|
},
|
|
{
|
|
"error": ["some", "error", "occurred"],
|
|
"duration": 1.9,
|
|
"atomic_actions": {
|
|
"action1": 0.5,
|
|
"action2": 1.4
|
|
}
|
|
},
|
|
{
|
|
"error": [],
|
|
"duration": 8,
|
|
"atomic_actions": {
|
|
"action1": 4,
|
|
"action2": 4
|
|
}
|
|
}
|
|
]
|
|
|
|
atomic_actions_data = {
|
|
"action1": [1, 0.5, 4],
|
|
"action2": [2, 1.4, 4],
|
|
"total": [3, 8]
|
|
}
|
|
|
|
output = utils.get_atomic_actions_data(raw_data)
|
|
self.assertEqual(output, atomic_actions_data)
|