blob: a688d8a5ff4b79b7fd26ab8c00a3bc694778c7e7 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#
"""Unit tests for Histogram."""
import unittest
from mock import patch
from apache_beam.utils.histogram import Histogram
from apache_beam.utils.histogram import LinearBucket
class HistogramTest(unittest.TestCase):
@patch('apache_beam.utils.histogram._LOGGER')
def test_out_of_range(self, mock_logger):
histogram = Histogram(LinearBucket(0, 20, 5))
histogram.record(100)
mock_logger.warning.assert_called_with(
'record is out of upper bound %s: %s', 100, 100)
self.assertEqual(histogram.total_count(), 1)
def test_boundary_buckets(self):
histogram = Histogram(LinearBucket(0, 20, 5))
histogram.record(0)
histogram.record(99.9)
self.assertEqual(histogram._buckets[0], 1)
self.assertEqual(histogram._buckets[4], 1)
def test_fractional_buckets(self):
histogram1 = Histogram(LinearBucket(0, 10 / 3, 3))
histogram1.record(3.33)
histogram1.record(6.66)
self.assertEqual(histogram1._buckets[0], 1)
self.assertEqual(histogram1._buckets[1], 1)
histogram2 = Histogram(LinearBucket(0, 10 / 3, 3))
histogram2.record(3.34)
histogram2.record(6.67)
self.assertEqual(histogram2._buckets[1], 1)
self.assertEqual(histogram2._buckets[2], 1)
def test_p50(self):
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
self.assertEqual(histogram1.p50(), 4.2)
histogram2 = Histogram(LinearBucket(0, 0.02, 50))
histogram2.record(0, 0, 0)
self.assertEqual(histogram2.p50(), 0.01)
def test_p90(self):
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
self.assertEqual(histogram1.p90(), 8.2)
histogram2 = Histogram(LinearBucket(0, 0.02, 50))
histogram2.record(0, 0, 0)
self.assertAlmostEqual(histogram2.p90(), 0.018, places=3)
def test_p99(self):
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
self.assertEqual(histogram1.p99(), 9.18)
histogram2 = Histogram(LinearBucket(0, 0.02, 50))
histogram2.record(0, 0, 0)
self.assertAlmostEqual(histogram2.p99(), 0.02, places=3)
def test_p90_negative(self):
histogram1 = Histogram(LinearBucket(-10, 0.2, 50))
histogram1.record(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10)
self.assertEqual(histogram1.p90(), -1.8)
histogram2 = Histogram(LinearBucket(-1, 0.02, 50))
histogram2.record(-1, -1, -1)
self.assertEqual(histogram2.p90(), -0.982)
def test_p90_negative_to_positive(self):
histogram1 = Histogram(LinearBucket(-5, 0.2, 50))
histogram1.record(-1, -2, -3, -4, -5, 0, 1, 2, 3, 4)
self.assertEqual(histogram1.p90(), 3.2)
histogram2 = Histogram(LinearBucket(-0.5, 0.02, 50))
histogram2.record(-0.5, -0.5, -0.5)
self.assertEqual(histogram2.p90(), -0.482)
def test_p50_negative_infinity(self):
histogram = Histogram(LinearBucket(0, 0.2, 50))
histogram.record(-1, -2, -3, -4, -5, 0, 1, 2, 3, 4)
self.assertEqual(histogram.p50(), float('-inf'))
self.assertIn('P50: <0', histogram.get_percentile_info())
def test_p50_positive_infinity(self):
histogram = Histogram(LinearBucket(0, 0.2, 50))
histogram.record(6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
self.assertEqual(histogram.p50(), float('inf'))
self.assertIn('P50: >=10', histogram.get_percentile_info())
def test_empty_p99(self):
histogram = Histogram(LinearBucket(0, 0.2, 50))
with self.assertRaises(RuntimeError) as cm:
histogram.p99()
self.assertEqual(str(cm.exception), 'histogram has no record.')
def test_clear(self):
histogram = Histogram(LinearBucket(0, 0.2, 50))
histogram.record(-1, 1, 2, 3)
self.assertEqual(histogram.total_count(), 4)
self.assertEqual(histogram._buckets[5], 1)
histogram.clear()
self.assertEqual(histogram.total_count(), 0)
self.assertEqual(histogram._buckets.get(5, 0), 0)
def test_equal(self):
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram2 = Histogram(LinearBucket(0, 0.2, 50))
self.assertEqual(histogram1, histogram2)
self.assertEqual(hash(histogram1), hash(histogram2))
histogram1 = Histogram(LinearBucket(0, 0.2, 5))
histogram2 = Histogram(LinearBucket(0, 0.2, 50))
self.assertNotEqual(histogram1, histogram2)
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram2 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(1)
histogram2.record(1)
self.assertEqual(histogram1, histogram2)
self.assertEqual(hash(histogram1), hash(histogram2))
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram2 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(1)
histogram2.record(10)
self.assertNotEqual(histogram1, histogram2)
def test_copy(self):
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(0, 1, 2, 3, 4)
histogram2 = histogram1.copy()
self.assertEqual(histogram1, histogram2)
histogram1.record(5, 6, 7, 8, 9)
self.assertNotEqual(histogram1, histogram2)
def test_combine(self):
histogram1 = Histogram(LinearBucket(0, 0.2, 50))
histogram1.record(0, 1, 2, 3, 4)
histogram2 = Histogram(LinearBucket(0, 0.2, 50))
histogram2.record(5, 6, 7, 8, 9)
histogram = Histogram(LinearBucket(0, 0.2, 50))
histogram.record(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
self.assertEqual(histogram1.combine(histogram2), histogram)
if __name__ == '__main__':
unittest.main()