Beispiel #1
0
 def testAggregationNoValues(self):
   """Single metric with no values."""
   slices = (
       InstanceMetricData("id", ()),
   )
   result = aggregation.aggregate(slices)
   self.assertEqual(len(result), 0)
Beispiel #2
0
  def testGetStatisticsMultpleInstances(self, ec2InstanceMetricGetterMock,
                                        getAutostackFromMetricMock,
                                        _engineFactoryMock):

    metricID = "abc"
    class MetricRowSpec(object):
      uid = None
      datasource = None
    metricRowMock = Mock(
        spec_set=MetricRowSpec,
        uid=metricID,
        datasource="autostack")
    autostackMock = Mock()
    getAutostackFromMetricMock.return_value = autostackMock

    metricGetterMock = Mock()
    ec2InstanceMetricGetterMock.return_value = metricGetterMock
    metricGetterMock.collectMetricStatistics.return_value = [
        InstanceMetricData(
            instanceID="tempID1",
            records=[MetricRecord(timestamp=None,
                                  value={"min": 5.0, "max": 20.0})]),
        InstanceMetricData(
            instanceID="tempID2",
            records=[MetricRecord(timestamp=None,
                                  value={"min": 15.0, "max": 30.0})]),
    ]

    # Call the function under test
    stats = aggregation.getStatistics(metricRowMock)

    # Validate stats
    self.assertSetEqual(set(stats.keys()), set(("min", "max")))
    # Make sure to include 20% buffer on range
    self.assertAlmostEqual(stats["min"], 7.0)
    self.assertAlmostEqual(stats["max"], 28.0)

    # Validate mocks were called correctly
    self.assertEqual(getAutostackFromMetricMock.call_args[0][1], metricID)

    metricGetterMock.collectMetricStatistics.assert_called_once_with(
        autostackMock, metricRowMock)
    metricGetterMock.close.assert_called_once()
Beispiel #3
0
 def testAggregationMultipleMetricsAligned(self):
   """Multiple metrics with matching timestamps."""
   timestamp2 = datetime.datetime.utcnow()
   timestamp1 = timestamp2 - datetime.timedelta(minutes=5)
   slices = (
       InstanceMetricData("id1", (
           MetricRecord(timestamp1, 100.0),
           MetricRecord(timestamp2, 50.0),
       )),
       InstanceMetricData("id2", (
           MetricRecord(timestamp1, 80.0),
           MetricRecord(timestamp2, 30.0),
       )),
   )
   result = aggregation.aggregate(slices)
   self.assertEqual(len(result), 2)
   self.assertIsInstance(result[0], tuple)
   self.assertIsInstance(result[1], tuple)
   self.assertSequenceEqual(result[0], (timestamp1, 90.0))
   self.assertSequenceEqual(result[1], (timestamp2, 40.0))
Beispiel #4
0
 def testAggregationSingleValue(self):
   """Single metric with single value."""
   timestamp = datetime.datetime.utcnow()
   slices = (
       InstanceMetricData("id", (
           MetricRecord(timestamp, 100.0),
       )),
   )
   result = aggregation.aggregate(slices)
   self.assertEqual(len(result), 1)
   self.assertIsInstance(result[0], tuple)
   self.assertSequenceEqual(result[0], (timestamp, 100.0))
Beispiel #5
0
 def testAggregationMultipleValues(self):
   """Single metric with multiple values at different timestamps."""
   timestamp2 = datetime.datetime.utcnow()
   timestamp1 = timestamp2 - datetime.timedelta(minutes=5)
   slices = (
       InstanceMetricData("id", (
           MetricRecord(timestamp1, 100.0),
           MetricRecord(timestamp2, 50.0),
       )),
   )
   result = aggregation.aggregate(slices)
   self.assertEqual(len(result), 2)
   self.assertIsInstance(result[0], tuple)
   self.assertIsInstance(result[1], tuple)
   self.assertSequenceEqual(result[0], (timestamp1, 100.0))
   self.assertSequenceEqual(result[1], (timestamp2, 50.0))
    def testMetricNotFoundFromSetLastTimestamp(self, engineMock, repoMock,
                                               ec2InstanceMetricGetterMock,
                                               _metricStreamerMock):
        """Test handling of ObjectNotFoundError when calling
    repository.setMetricLastTimestamp in _processAutostackMetricRequests.
    In this case, we expect _processAutostackMetricRequests to skip this
    collection and continue processing the next one(s)
    """

        # Ignore attemting to look for MySQL transient errors.
        # We're not testing those here.
        repoMock.retryOnTransientErrors.side_effect = lambda f: f

        # Define metric to skip over
        errMetric = Mock(spec_set=self.MetricRowSpec)
        errMetric.name = "errMetric"

        errInstanceID = "i-00000"
        errRefID = 0  # index into requests sequence
        errRequest = AutostackMetricRequest(
            refID=errRefID,
            autostack=Mock(spec_set=self.AutostackRowSpec),
            metric=errMetric)

        errMetricRecord = MetricRecord(timestamp=datetime.datetime.utcnow(),
                                       value=2)
        errData = InstanceMetricData(instanceID=errInstanceID,
                                     records=[errMetricRecord])

        errCollection = MetricCollection(refID=errRefID,
                                         slices=[errData],
                                         timeRange=self.timeRange,
                                         nextMetricTime=self.timeRange.end)

        # Define "ok" metric
        okMetric = Mock(spec_set=self.MetricRowSpec)
        okMetric.name = "okMetric"

        okInstanceID = "i-11111"
        okRefID = 1  # index into requests sequence
        okRequest = AutostackMetricRequest(
            refID=okRefID,
            autostack=Mock(spec_set=self.AutostackRowSpec),
            metric=okMetric)

        okDataValue = 111
        okMetricRecord = MetricRecord(timestamp=datetime.datetime.utcnow(),
                                      value=okDataValue)
        okData = InstanceMetricData(instanceID=okInstanceID,
                                    records=[okMetricRecord])

        okCollection = MetricCollection(refID=okRefID,
                                        slices=[okData],
                                        timeRange=self.timeRange,
                                        nextMetricTime=self.timeRange.end)

        # Make setMetricLastTimestamp error on first call (error metric) and pass
        # on second call (ok metric)
        repoMock.setMetricLastTimestamp.side_effect = (
            app_exceptions.ObjectNotFoundError("Expected: things happen"),
            None)

        requests = [errRequest, okRequest]
        collections = [errCollection, okCollection]
        metricGetterInstanceMock = ec2InstanceMetricGetterMock.return_value
        metricGetterInstanceMock.collectMetricData.return_value = iter(
            collections)

        streamedData = []
        _metricStreamerMock.return_value.streamMetricData.side_effect = (
            lambda data, *args, **kwargs: streamedData.append(data))

        aggSvc = aggregator_service.AggregatorService()
        with patch.object(aggregator_service,
                          "getAggregationFn",
                          autospec=True,
                          return_value=None):
            aggSvc._processAutostackMetricRequests(
                engine=engineMock,
                requests=requests,
                modelSwapper=Mock(spec_set=ModelSwapperInterface))

        self.assertEqual(len(streamedData), 1)
        self.assertEqual(len(streamedData[0]), 1)
        self.assertEqual(streamedData[0][0][1], okDataValue)