def testCheckAllSendsNotification(self, tableMock, botoDynamoDB2Mock,
                                      requestsGetMock):

        # Mock API to return pre-defined models in lieu of making an API call to
        # a live taurus models HTTP endpoint
        requestsGetMock.return_value = Mock(status_code=200,
                                            json=Mock(return_value=MODELS))

        # Mock boto dynamodb queries by returning locally cached metric data.
        # See data/*-data.pickle
        # Disable pylint warning about unused, and improperly named arguments
        # pylint: disable=W0613,C0103
        def query2SideEffect(uid__eq, timestamp__gte):
            return METRIC_DATA_BY_ID[uid__eq]

        tableMock.return_value = (Mock(query_2=Mock(
            side_effect=query2SideEffect, __name__=str(id(query2SideEffect)))))

        with self.assertRaises(LatencyMonitorError) as exc:
            ModelLatencyChecker().checkAllModelLatency()

        self.assertEqual(
            exc.exception.message,
            "The following models have exceeded the acceptable threshold for time si"
            "nce last timestamp in taurus.metric_data.test DynamoDB table:\n    Late"
            "ncyMonitorErrorParams(model_name=TWITTER.TWEET.HANDLE.SPG.VOLUME, model"
            "_uid=0021c2d17c0a4eb4965b6cb315c1d2e9, threshold=32548.9007552 seconds,"
            " last_timestamp=2015-11-01 16:12:53+00:00)\n    LatencyMonitorErrorPara"
            "ms(model_name=XIGNITE.TRI.VOLUME, model_uid=00261089e61b4af1a1e4b3d0c06"
            "aa84a, threshold=32889.8983336 seconds, last_timestamp=2015-10-30 19:55"
            ":00+00:00)\n    LatencyMonitorErrorParams(model_name=XIGNITE.BK.CLOSING"
            "PRICE, model_uid=018662cc75b14860b72319d92883c896, threshold=32889.8983"
            "336 seconds, last_timestamp=2015-10-30 19:55:00+00:00)")
    def testMissingMonitorConfPathArgRaisesParserError(self):

        # Assert that not specifying a required --monitorConfPath option will
        # result in a parser error, and consequently a sys.exit(), as indicated by
        # the SystemExit exception
        with self.assertRaises(SystemExit):
            ModelLatencyChecker().checkAllModelLatency()
    def testMarketHours(self, tableMock, botoDynamoDB2Mock, requestsGetMock):

        # Mock API to return pre-defined models in lieu of making an API call to
        # a live taurus models HTTP endpoint
        requestsGetMock.return_value = Mock(status_code=200,
                                            json=Mock(return_value=MODELS))

        # Mock boto dynamodb queries by returning locally cached metric data.
        # See data/*-data.pickle
        # Disable pylint warning about unused, and improperly named arguments
        # pylint: disable=W0613,C0103
        def query2SideEffect(uid__eq, timestamp__gte):
            return METRIC_DATA_BY_ID[uid__eq]

        tableMock.return_value = (Mock(query_2=Mock(
            side_effect=query2SideEffect, __name__=str(id(query2SideEffect)))))

        # This should not raise an exception
        with patch(
                "taurus_monitoring.latency_monitor.model_latency_monitor.isOuts"
                "ideMarketHours",
                Mock(wraps=isOutsideMarketHours)) as isOutsideMarketHoursMock:
            ModelLatencyChecker().checkAllModelLatency()

        self.assertTrue(isOutsideMarketHoursMock.called)

        # Now, check to see if we attempted to query dynamodb
        stockModelUIDs = [model["uid"] for model in MODELS]

        for (_, kwargs) in tableMock.return_value.query_2.call_args_list:
            for uid in stockModelUIDs:
                if kwargs["uid__eq"] == uid:
                    self.fail(
                        "Dynamodb was queried for a stock model after hours")
    def testCheckAllModelLatencyGracefullyHandlesAPIFailure(
            self, requestsGetMock):

        # Mock API to return 500 status in lieu of making an API call to a live
        # taurus models HTTP endpoint
        requestsGetMock.return_value = Mock(status_code=500)

        with self.assertRaises(LatencyMonitorError) as exc:
            ModelLatencyChecker().checkAllModelLatency()

        self.assertIn((
            "Unable to query Taurus API for active models: Unexpected HTTP response"
            " status (500) from taurusModelsUrl"), exc.exception.message)
 def testRegisterCheckRegisteredOnlyCheckAllModelLatency(self):
     modelLatencyChecker = ModelLatencyChecker()
     self.assertEqual(len(modelLatencyChecker.checks), 1)
     self.assertSetEqual(
         set(fn.func_name for fn in modelLatencyChecker.checks),
         set(["checkAllModelLatency"]))