| # | |
| # 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() |