github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/testing/metric_result_matchers_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 """Unit tests for the metric_result_matchers.""" 19 20 # pytype: skip-file 21 22 import unittest 23 24 from hamcrest import assert_that as hc_assert_that 25 from hamcrest import anything 26 from hamcrest import equal_to 27 from hamcrest.core.core.isnot import is_not 28 from hamcrest.library.number.ordering_comparison import greater_than 29 from hamcrest.library.text.isequal_ignoring_case import equal_to_ignoring_case 30 31 from apache_beam.metrics.cells import DistributionData 32 from apache_beam.metrics.cells import DistributionResult 33 from apache_beam.metrics.execution import MetricKey 34 from apache_beam.metrics.execution import MetricResult 35 from apache_beam.metrics.metricbase import MetricName 36 from apache_beam.testing.metric_result_matchers import DistributionMatcher 37 from apache_beam.testing.metric_result_matchers import MetricResultMatcher 38 39 EVERYTHING_DISTRIBUTION = { 40 'namespace': 'myNamespace', 41 'name': 'myName', 42 'step': 'myStep', 43 'attempted': { 44 'distribution': { 45 'sum': 12, 46 'count': 5, 47 'min': 0, 48 'max': 6, 49 } 50 }, 51 'committed': { 52 'distribution': { 53 'sum': 12, 54 'count': 5, 55 'min': 0, 56 'max': 6, 57 } 58 }, 59 'labels': { 60 'pcollection': 'myCollection', 'myCustomKey': 'myCustomValue' 61 } 62 } 63 64 EVERYTHING_COUNTER = { 65 'namespace': 'myNamespace', 66 'name': 'myName', 67 'step': 'myStep', 68 'attempted': { 69 'counter': 42 70 }, 71 'committed': { 72 'counter': 42 73 }, 74 'labels': { 75 'pcollection': 'myCollection', 'myCustomKey': 'myCustomValue' 76 } 77 } 78 79 80 def _create_metric_result(data_dict): 81 step = data_dict['step'] if 'step' in data_dict else '' 82 labels = data_dict['labels'] if 'labels' in data_dict else {} 83 values = {} 84 for key in ['attempted', 'committed']: 85 if key in data_dict: 86 if 'counter' in data_dict[key]: 87 values[key] = data_dict[key]['counter'] 88 elif 'distribution' in data_dict[key]: 89 distribution = data_dict[key]['distribution'] 90 values[key] = DistributionResult( 91 DistributionData( 92 distribution['sum'], 93 distribution['count'], 94 distribution['min'], 95 distribution['max'], 96 )) 97 attempted = values['attempted'] if 'attempted' in values else None 98 committed = values['committed'] if 'committed' in values else None 99 100 metric_name = MetricName(data_dict['namespace'], data_dict['name']) 101 metric_key = MetricKey(step, metric_name, labels) 102 return MetricResult(metric_key, committed, attempted) 103 104 105 class MetricResultMatchersTest(unittest.TestCase): 106 def test_matches_all_for_counter(self): 107 metric_result = _create_metric_result(EVERYTHING_COUNTER) 108 matcher = MetricResultMatcher( 109 namespace='myNamespace', 110 name='myName', 111 step='myStep', 112 labels={ 113 'pcollection': 'myCollection', 'myCustomKey': 'myCustomValue' 114 }, 115 attempted=42, 116 committed=42) 117 hc_assert_that(metric_result, matcher) 118 119 def test_matches_none_for_counter(self): 120 metric_result = _create_metric_result(EVERYTHING_COUNTER) 121 matcher = MetricResultMatcher( 122 namespace=is_not(equal_to('invalidNamespace')), 123 name=is_not(equal_to('invalidName')), 124 step=is_not(equal_to('invalidStep')), 125 labels={ 126 is_not(equal_to('invalidPcollection')): anything(), 127 is_not(equal_to('invalidCustomKey')): is_not( 128 equal_to('invalidCustomValue')) 129 }, 130 attempted=is_not(equal_to(1000)), 131 committed=is_not(equal_to(1000))) 132 hc_assert_that(metric_result, matcher) 133 134 def test_matches_all_for_distribution(self): 135 metric_result = _create_metric_result(EVERYTHING_DISTRIBUTION) 136 matcher = MetricResultMatcher( 137 namespace='myNamespace', 138 name='myName', 139 step='myStep', 140 labels={ 141 'pcollection': 'myCollection', 'myCustomKey': 'myCustomValue' 142 }, 143 committed=DistributionMatcher( 144 sum_value=12, count_value=5, min_value=0, max_value=6), 145 attempted=DistributionMatcher( 146 sum_value=12, count_value=5, min_value=0, max_value=6), 147 ) 148 hc_assert_that(metric_result, matcher) 149 150 def test_matches_none_for_distribution(self): 151 metric_result = _create_metric_result(EVERYTHING_DISTRIBUTION) 152 matcher = MetricResultMatcher( 153 namespace=is_not(equal_to('invalidNamespace')), 154 name=is_not(equal_to('invalidName')), 155 step=is_not(equal_to('invalidStep')), 156 labels={ 157 is_not(equal_to('invalidPcollection')): anything(), 158 is_not(equal_to('invalidCustomKey')): is_not( 159 equal_to('invalidCustomValue')) 160 }, 161 committed=is_not( 162 DistributionMatcher( 163 sum_value=120, count_value=50, min_value=100, max_value=60)), 164 attempted=is_not( 165 DistributionMatcher( 166 sum_value=120, count_value=50, min_value=100, max_value=60)), 167 ) 168 hc_assert_that(metric_result, matcher) 169 170 def test_matches_key_but_not_value(self): 171 metric_result = _create_metric_result(EVERYTHING_COUNTER) 172 matcher = is_not( 173 MetricResultMatcher(labels={'pcollection': 'invalidCollection'})) 174 hc_assert_that(metric_result, matcher) 175 176 def test_matches_counter_with_custom_matchers(self): 177 metric_result = _create_metric_result(EVERYTHING_COUNTER) 178 matcher = is_not( 179 MetricResultMatcher( 180 namespace=equal_to_ignoring_case('MYNAMESPACE'), 181 name=equal_to_ignoring_case('MYNAME'), 182 step=equal_to_ignoring_case('MYSTEP'), 183 labels={ 184 equal_to_ignoring_case('PCOLLECTION'): equal_to_ignoring_case( 185 'MYCUSTOMVALUE'), 186 'myCustomKey': equal_to_ignoring_case('MYCUSTOMVALUE') 187 }, 188 committed=greater_than(0), 189 attempted=greater_than(0))) 190 hc_assert_that(metric_result, matcher) 191 192 def test_matches_distribution_with_custom_matchers(self): 193 metric_result = _create_metric_result(EVERYTHING_DISTRIBUTION) 194 matcher = is_not( 195 MetricResultMatcher( 196 namespace=equal_to_ignoring_case('MYNAMESPACE'), 197 name=equal_to_ignoring_case('MYNAME'), 198 step=equal_to_ignoring_case('MYSTEP'), 199 labels={ 200 equal_to_ignoring_case('PCOLLECTION'): equal_to_ignoring_case( 201 'MYCUSTOMVALUE'), 202 'myCustomKey': equal_to_ignoring_case('MYCUSTOMVALUE') 203 }, 204 committed=is_not( 205 DistributionMatcher( 206 sum_value=greater_than(-1), 207 count_value=greater_than(-1), 208 min_value=greater_than(-1), 209 max_value=greater_than(-1))), 210 attempted=is_not( 211 DistributionMatcher( 212 sum_value=greater_than(-1), 213 count_value=greater_than(-1), 214 min_value=greater_than(-1), 215 max_value=greater_than(-1))), 216 )) 217 hc_assert_that(metric_result, matcher) 218 219 def test_counter_does_not_match_distribution_and_doesnt_crash(self): 220 metric_result = _create_metric_result(EVERYTHING_COUNTER) 221 matcher = is_not( 222 MetricResultMatcher( 223 committed=DistributionMatcher( 224 sum_value=120, count_value=50, min_value=100, max_value=60), 225 attempted=DistributionMatcher( 226 sum_value=120, count_value=50, min_value=100, max_value=60), 227 )) 228 hc_assert_that(metric_result, matcher) 229 230 def test_distribution_does_not_match_counter_and_doesnt_crash(self): 231 metric_result = _create_metric_result(EVERYTHING_DISTRIBUTION) 232 matcher = is_not(MetricResultMatcher(attempted=42, committed=42)) 233 hc_assert_that(metric_result, matcher) 234 235 236 if __name__ == '__main__': 237 unittest.main()