docs: def assert_metric(self, name, value=None, tags=None, count=None, at_least=1, hostname=None, metric_type=None):
          """
          Assert a metric was processed by this stub
          """
          self._asserted.add(name)
          tags = normalize_tags(tags, sort=True)
  
          candidates = []
          for metric in self.metrics(name):
              if value is not None and not self.is_aggregate(metric.type) and value != metric.value:
                  continue
  
              if tags and tags != sorted(metric.tags):
                  continue
  
              if hostname and hostname != metric.hostname:
                  continue
  
              if metric_type is not None and metric_type != metric.type:
                  continue
  
              candidates.append(metric)
  
          if value is not None and candidates and all(self.is_aggregate(m.type) for m in candidates):
              got = sum(m.value for m in candidates)
              msg = "Expected count value for '{}': {}, got {}".format(name, value, got)
              assert value == got, msg
  
          if count is not None:
              msg = "Needed exactly {} candidates for '{}', got {}".format(count, name, len(candidates))
              assert len(candidates) == count, msg
          else:
              msg = "Needed at least {} candidates for '{}', got {}".format(at_least, name, len(candidates))
              assert len(candidates) >= at_least, msg