github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/metrics/cells_test.py (about) 1 # 2 # Licensed to the Apache Software Foundation (ASF) under one or more 3 # contributor license agreements. See the NOTICE file distributed with 4 # this work for additional information regarding copyright ownership. 5 # The ASF licenses this file to You under the Apache License, Version 2.0 6 # (the "License"); you may not use this file except in compliance with 7 # the License. You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 # pytype: skip-file 19 20 import threading 21 import unittest 22 23 from apache_beam.metrics.cells import CounterCell 24 from apache_beam.metrics.cells import DistributionCell 25 from apache_beam.metrics.cells import DistributionData 26 from apache_beam.metrics.cells import GaugeCell 27 from apache_beam.metrics.cells import GaugeData 28 from apache_beam.metrics.metricbase import MetricName 29 30 31 class TestCounterCell(unittest.TestCase): 32 @classmethod 33 def _modify_counter(cls, d): 34 for i in range(cls.NUM_ITERATIONS): 35 d.inc(i) 36 37 NUM_THREADS = 5 38 NUM_ITERATIONS = 100 39 40 def test_parallel_access(self): 41 # We create NUM_THREADS threads that concurrently modify the counter. 42 threads = [] 43 c = CounterCell() 44 for _ in range(TestCounterCell.NUM_THREADS): 45 t = threading.Thread(target=TestCounterCell._modify_counter, args=(c, )) 46 threads.append(t) 47 t.start() 48 49 for t in threads: 50 t.join() 51 52 total = ( 53 self.NUM_ITERATIONS * (self.NUM_ITERATIONS - 1) // 2 * self.NUM_THREADS) 54 self.assertEqual(c.get_cumulative(), total) 55 56 def test_basic_operations(self): 57 c = CounterCell() 58 c.inc(2) 59 self.assertEqual(c.get_cumulative(), 2) 60 61 c.dec(10) 62 self.assertEqual(c.get_cumulative(), -8) 63 64 c.dec() 65 self.assertEqual(c.get_cumulative(), -9) 66 67 c.inc() 68 self.assertEqual(c.get_cumulative(), -8) 69 70 def test_start_time_set(self): 71 c = CounterCell() 72 c.inc(2) 73 74 name = MetricName('namespace', 'name1') 75 mi = c.to_runner_api_monitoring_info(name, 'transform_id') 76 self.assertGreater(mi.start_time.seconds, 0) 77 78 79 class TestDistributionCell(unittest.TestCase): 80 @classmethod 81 def _modify_distribution(cls, d): 82 for i in range(cls.NUM_ITERATIONS): 83 d.update(i) 84 85 NUM_THREADS = 5 86 NUM_ITERATIONS = 100 87 88 def test_parallel_access(self): 89 # We create NUM_THREADS threads that concurrently modify the distribution. 90 threads = [] 91 d = DistributionCell() 92 for _ in range(TestDistributionCell.NUM_THREADS): 93 t = threading.Thread( 94 target=TestDistributionCell._modify_distribution, args=(d, )) 95 threads.append(t) 96 t.start() 97 98 for t in threads: 99 t.join() 100 101 total = ( 102 self.NUM_ITERATIONS * (self.NUM_ITERATIONS - 1) // 2 * self.NUM_THREADS) 103 104 count = (self.NUM_ITERATIONS * self.NUM_THREADS) 105 106 self.assertEqual( 107 d.get_cumulative(), 108 DistributionData(total, count, 0, self.NUM_ITERATIONS - 1)) 109 110 def test_basic_operations(self): 111 d = DistributionCell() 112 d.update(10) 113 self.assertEqual(d.get_cumulative(), DistributionData(10, 1, 10, 10)) 114 115 d.update(2) 116 self.assertEqual(d.get_cumulative(), DistributionData(12, 2, 2, 10)) 117 118 d.update(900) 119 self.assertEqual(d.get_cumulative(), DistributionData(912, 3, 2, 900)) 120 121 def test_integer_only(self): 122 d = DistributionCell() 123 d.update(3.1) 124 d.update(3.2) 125 d.update(3.3) 126 self.assertEqual(d.get_cumulative(), DistributionData(9, 3, 3, 3)) 127 128 def test_start_time_set(self): 129 d = DistributionCell() 130 d.update(3.1) 131 132 name = MetricName('namespace', 'name1') 133 mi = d.to_runner_api_monitoring_info(name, 'transform_id') 134 self.assertGreater(mi.start_time.seconds, 0) 135 136 137 class TestGaugeCell(unittest.TestCase): 138 def test_basic_operations(self): 139 g = GaugeCell() 140 g.set(10) 141 self.assertEqual(g.get_cumulative().value, GaugeData(10).value) 142 143 g.set(2) 144 self.assertEqual(g.get_cumulative().value, 2) 145 146 def test_integer_only(self): 147 g = GaugeCell() 148 g.set(3.3) 149 self.assertEqual(g.get_cumulative().value, 3) 150 151 def test_combine_appropriately(self): 152 g1 = GaugeCell() 153 g1.set(3) 154 155 g2 = GaugeCell() 156 g2.set(1) 157 158 # THe second Gauge, with value 1 was the most recent, so it should be 159 # the final result. 160 result = g2.combine(g1) 161 self.assertEqual(result.data.value, 1) 162 163 def test_start_time_set(self): 164 g1 = GaugeCell() 165 g1.set(3) 166 167 name = MetricName('namespace', 'name1') 168 mi = g1.to_runner_api_monitoring_info(name, 'transform_id') 169 self.assertGreater(mi.start_time.seconds, 0) 170 171 172 if __name__ == '__main__': 173 unittest.main()