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()
 def testAggregationNoValues(self):
   """Single metric with no values."""
   slices = (
       InstanceMetricData("id", ()),
   )
   result = aggregation.aggregate(slices)
   self.assertEqual(len(result), 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))
 def testAggregationMultipleMetricsAlignedSum(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, aggregationFn=sum)
     self.assertEqual(len(result), 2)
     self.assertIsInstance(result[0], tuple)
     self.assertIsInstance(result[1], tuple)
     self.assertSequenceEqual(result[0], (timestamp1, 180.0))
     self.assertSequenceEqual(result[1], (timestamp2, 80.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 testAggregationMultipleMetricsMisaligned(self):
     """Multiple metrics with both matching and non-matching timestamps."""
     timestamp3 = datetime.datetime.utcnow()
     timestamp2 = timestamp3 - datetime.timedelta(minutes=5)
     timestamp1 = timestamp2 - datetime.timedelta(minutes=5)
     slices = (
         InstanceMetricData("id1", (
             MetricRecord(timestamp1, 100.0),
             MetricRecord(timestamp2, 50.0),
         )),
         InstanceMetricData("id2", (
             MetricRecord(timestamp2, 80.0),
             MetricRecord(timestamp3, 30.0),
         )),
     )
     result = aggregation.aggregate(slices)
     self.assertEqual(len(result), 3)
     self.assertIsInstance(result[0], tuple)
     self.assertIsInstance(result[1], tuple)
     self.assertIsInstance(result[2], tuple)
     self.assertSequenceEqual(result[0], (timestamp1, 100.0))
     self.assertSequenceEqual(result[1], (timestamp2, 65.0))
     self.assertSequenceEqual(result[2], (timestamp3, 30.0))
Exemple #7
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)