[StreamingAlgorithms] result() returns None if data is missing
Make StreamingAlgorithm.result() returning None instead of raising RallyException in case if no (or not enough) data has been processed. This change was discussed at Dec' 21st on Rally weekly meeting. Change-Id: I5c1eec47a0e190ec6ccd351b0c3bd866f4544b35
This commit is contained in:
parent
d188a5ba3b
commit
339adba2a9
@ -18,8 +18,6 @@ import math
|
|||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from rally.common.i18n import _
|
|
||||||
from rally import exceptions
|
|
||||||
from rally.task.processing import utils
|
from rally.task.processing import utils
|
||||||
|
|
||||||
|
|
||||||
@ -62,11 +60,9 @@ class MeanComputation(StreamingAlgorithm):
|
|||||||
self.total += other.total
|
self.total += other.total
|
||||||
|
|
||||||
def result(self):
|
def result(self):
|
||||||
if self.count == 0:
|
if self.count:
|
||||||
message = _("Unable to calculate the mean: "
|
return self.total / self.count
|
||||||
"no values processed so far.")
|
return None
|
||||||
raise exceptions.RallyException(message)
|
|
||||||
return self.total / self.count
|
|
||||||
|
|
||||||
|
|
||||||
class StdDevComputation(StreamingAlgorithm):
|
class StdDevComputation(StreamingAlgorithm):
|
||||||
@ -90,6 +86,8 @@ class StdDevComputation(StreamingAlgorithm):
|
|||||||
self.dev_sum = self.dev_sum + (value - mean_prev) * (value - self.mean)
|
self.dev_sum = self.dev_sum + (value - mean_prev) * (value - self.mean)
|
||||||
|
|
||||||
def merge(self, other):
|
def merge(self, other):
|
||||||
|
if not other.mean_computation.count:
|
||||||
|
return
|
||||||
dev_sum1 = self.dev_sum
|
dev_sum1 = self.dev_sum
|
||||||
count1 = self.count
|
count1 = self.count
|
||||||
mean1 = self.mean
|
mean1 = self.mean
|
||||||
@ -107,10 +105,9 @@ class StdDevComputation(StreamingAlgorithm):
|
|||||||
self.count * self.mean ** 2)
|
self.count * self.mean ** 2)
|
||||||
|
|
||||||
def result(self):
|
def result(self):
|
||||||
|
# NOTE(amaretskiy): Need at least two values to be processed
|
||||||
if self.count < 2:
|
if self.count < 2:
|
||||||
message = _("Unable to calculate the standard deviation: "
|
return None
|
||||||
"need at least two values to be processed.")
|
|
||||||
raise exceptions.RallyException(message)
|
|
||||||
return math.sqrt(self.dev_sum / (self.count - 1))
|
return math.sqrt(self.dev_sum / (self.count - 1))
|
||||||
|
|
||||||
|
|
||||||
@ -131,9 +128,6 @@ class MinComputation(StreamingAlgorithm):
|
|||||||
self.add(other._value)
|
self.add(other._value)
|
||||||
|
|
||||||
def result(self):
|
def result(self):
|
||||||
if self._value is None:
|
|
||||||
raise exceptions.RallyException(
|
|
||||||
_("No values have been processed"))
|
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
|
|
||||||
@ -154,9 +148,6 @@ class MaxComputation(StreamingAlgorithm):
|
|||||||
self.add(other._value)
|
self.add(other._value)
|
||||||
|
|
||||||
def result(self):
|
def result(self):
|
||||||
if self._value is None:
|
|
||||||
raise exceptions.RallyException(
|
|
||||||
_("No values have been processed"))
|
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
|
|
||||||
@ -185,10 +176,9 @@ class PercentileComputation(StreamingAlgorithm):
|
|||||||
def result(self):
|
def result(self):
|
||||||
results = list(
|
results = list(
|
||||||
map(lambda x: x[1], self._graph_zipper.get_zipped_graph()))
|
map(lambda x: x[1], self._graph_zipper.get_zipped_graph()))
|
||||||
if not results:
|
if results:
|
||||||
raise exceptions.RallyException(
|
return utils.percentile(results, self._percent)
|
||||||
_("No values have been processed"))
|
return None
|
||||||
return utils.percentile(results, self._percent)
|
|
||||||
|
|
||||||
|
|
||||||
class IncrementComputation(StreamingAlgorithm):
|
class IncrementComputation(StreamingAlgorithm):
|
||||||
|
@ -44,7 +44,7 @@ class MaxAverageDuration(sla.SLA):
|
|||||||
|
|
||||||
def merge(self, other):
|
def merge(self, other):
|
||||||
self.avg_comp.merge(other.avg_comp)
|
self.avg_comp.merge(other.avg_comp)
|
||||||
self.avg = self.avg_comp.result()
|
self.avg = self.avg_comp.result() or 0.0
|
||||||
self.success = self.avg <= self.criterion_value
|
self.success = self.avg <= self.criterion_value
|
||||||
return self.success
|
return self.success
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ import six
|
|||||||
|
|
||||||
from rally.common import costilius
|
from rally.common import costilius
|
||||||
from rally.common import streaming_algorithms as streaming
|
from rally.common import streaming_algorithms as streaming
|
||||||
from rally import exceptions
|
|
||||||
from rally.task.processing import utils
|
from rally.task.processing import utils
|
||||||
|
|
||||||
|
|
||||||
@ -324,10 +323,7 @@ class MainStatsTable(Chart):
|
|||||||
for i in range(len(self.table)):
|
for i in range(len(self.table)):
|
||||||
row = [self.table[i][0][1]]
|
row = [self.table[i][0][1]]
|
||||||
# no results if all iterations failed
|
# no results if all iterations failed
|
||||||
try:
|
no_result = not self.table[i][-2][1].result()
|
||||||
no_result = self.table[i][-2][1].result() == 0.0
|
|
||||||
except exceptions.RallyException:
|
|
||||||
no_result = True
|
|
||||||
row.extend(x[2](x[1], no_result) for x in self.table[i][1:])
|
row.extend(x[2](x[1], no_result) for x in self.table[i][1:])
|
||||||
rows.append(row)
|
rows.append(row)
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import ddt
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from rally.common import streaming_algorithms as algo
|
from rally.common import streaming_algorithms as algo
|
||||||
from rally import exceptions
|
|
||||||
from tests.unit import test
|
from tests.unit import test
|
||||||
|
|
||||||
|
|
||||||
@ -27,7 +26,7 @@ class MeanComputationTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_empty_stream(self):
|
def test_empty_stream(self):
|
||||||
mean_computation = algo.MeanComputation()
|
mean_computation = algo.MeanComputation()
|
||||||
self.assertRaises(exceptions.RallyException, mean_computation.result)
|
self.assertIsNone(mean_computation.result())
|
||||||
|
|
||||||
def test_one_value(self):
|
def test_one_value(self):
|
||||||
mean_computation = algo.MeanComputation()
|
mean_computation = algo.MeanComputation()
|
||||||
@ -68,12 +67,12 @@ class StdDevComputationTestCase(test.TestCase):
|
|||||||
|
|
||||||
def test_empty_stream(self):
|
def test_empty_stream(self):
|
||||||
std_computation = algo.StdDevComputation()
|
std_computation = algo.StdDevComputation()
|
||||||
self.assertRaises(exceptions.RallyException, std_computation.result)
|
self.assertIsNone(std_computation.result())
|
||||||
|
|
||||||
def test_one_value(self):
|
def test_one_value(self):
|
||||||
std_computation = algo.StdDevComputation()
|
std_computation = algo.StdDevComputation()
|
||||||
std_computation.add(10.0)
|
std_computation.add(10.0)
|
||||||
self.assertRaises(exceptions.RallyException, std_computation.result)
|
self.assertIsNone(std_computation.result())
|
||||||
|
|
||||||
def test_two_values(self):
|
def test_two_values(self):
|
||||||
std_computation = algo.StdDevComputation()
|
std_computation = algo.StdDevComputation()
|
||||||
@ -127,10 +126,10 @@ class MinComputationTestCase(test.TestCase):
|
|||||||
self.assertRaises(TypeError, comp.add, None)
|
self.assertRaises(TypeError, comp.add, None)
|
||||||
self.assertRaises(TypeError, comp.add, "str")
|
self.assertRaises(TypeError, comp.add, "str")
|
||||||
|
|
||||||
def test_result_raises(self):
|
def test_result_empty(self):
|
||||||
comp = algo.MinComputation()
|
comp = algo.MinComputation()
|
||||||
self.assertRaises(TypeError, comp.result, 1)
|
self.assertRaises(TypeError, comp.result, 1)
|
||||||
self.assertRaises(exceptions.RallyException, comp.result)
|
self.assertIsNone(comp.result())
|
||||||
|
|
||||||
def test_merge(self):
|
def test_merge(self):
|
||||||
single_min_algo = algo.MinComputation()
|
single_min_algo = algo.MinComputation()
|
||||||
@ -166,10 +165,10 @@ class MaxComputationTestCase(test.TestCase):
|
|||||||
self.assertRaises(TypeError, comp.add, None)
|
self.assertRaises(TypeError, comp.add, None)
|
||||||
self.assertRaises(TypeError, comp.add, "str")
|
self.assertRaises(TypeError, comp.add, "str")
|
||||||
|
|
||||||
def test_result_raises(self):
|
def test_result_empty(self):
|
||||||
comp = algo.MaxComputation()
|
comp = algo.MaxComputation()
|
||||||
self.assertRaises(TypeError, comp.result, 1)
|
self.assertRaises(TypeError, comp.result, 1)
|
||||||
self.assertRaises(exceptions.RallyException, comp.result)
|
self.assertIsNone(comp.result())
|
||||||
|
|
||||||
def test_merge(self):
|
def test_merge(self):
|
||||||
single_max_algo = algo.MaxComputation()
|
single_max_algo = algo.MaxComputation()
|
||||||
@ -241,10 +240,10 @@ class PercentileComputationTestCase(test.TestCase):
|
|||||||
comp = algo.PercentileComputation(0.50, 100)
|
comp = algo.PercentileComputation(0.50, 100)
|
||||||
self.assertRaises(TypeError, comp.add)
|
self.assertRaises(TypeError, comp.add)
|
||||||
|
|
||||||
def test_result_raises(self):
|
def test_result_empty(self):
|
||||||
self.assertRaises(TypeError, algo.PercentileComputation)
|
self.assertRaises(TypeError, algo.PercentileComputation)
|
||||||
comp = algo.PercentileComputation(0.50, 100)
|
comp = algo.PercentileComputation(0.50, 100)
|
||||||
self.assertRaises(exceptions.RallyException, comp.result)
|
self.assertIsNone(comp.result())
|
||||||
|
|
||||||
|
|
||||||
class IncrementComputationTestCase(test.TestCase):
|
class IncrementComputationTestCase(test.TestCase):
|
||||||
|
Loading…
Reference in New Issue
Block a user