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