def test_run(self, requests_mock):
        requests_mock.get = get_request_mock
        requests_mock.post = mock.Mock(return_value=mock.MagicMock(
            status_code=201))

        bridge = RiskIndicatorBridge(self.config)

        sleep_mock = mock.Mock()
        sleep_mock.side_effect = StopIteration
        with mock.patch("openprocurement.bot.risk_indicators.bridge.sleep",
                        sleep_mock):
            try:
                bridge.run()
            except StopIteration:
                pass

        requests_mock.post.assert_called_once_with(
            'https://audit-api-dev.prozorro.gov.ua/api/2.4/monitorings',
            headers={
                'Authorization': 'Bearer 11111111111111111111111111111111'
            },
            json={
                "data": {
                    'reasons': ['indicator'],
                    'procuringStages': ['planning'],
                    'tender_id': '4',
                    'riskIndicators': ['1', '4'],
                    'riskIndicatorsTotalImpact': 0.099,
                    'riskIndicatorsRegion': u"Севастополь",
                }
            },
            timeout=bridge.request_timeout)
    def test_start_monitoring(self, requests_mock):
        post_mock = mock.Mock(return_value=mock.MagicMock(status_code=201))
        requests_mock.post = post_mock

        bridge = RiskIndicatorBridge(self.config)

        details = {
            "id": "f" * 32,
            'status': 'active.auction',
            "indicators": indicators,
            "indicatorsInfo": indicators_info,
        }
        risk_info = {"tenderScore": 0.55, "region": u"Ухтырка"}

        bridge.start_monitoring(risk_info, details)
        post_mock.assert_called_once_with(
            'https://audit-api-dev.prozorro.gov.ua/api/2.4/monitorings',
            headers={
                'Authorization': 'Bearer 11111111111111111111111111111111'
            },
            json={
                'data': {
                    'reasons': ['indicator'],
                    'procuringStages': ['awarding'],
                    'tender_id': 'f' * 32,
                    "riskIndicators": ['1', '4'],
                    "riskIndicatorsTotalImpact": 0.55,
                    "riskIndicatorsRegion": risk_info["region"],
                }
            },
            timeout=bridge.request_timeout)
    def test_request_risk_api_without_proxy(self, requests_mock):
        get_mock = mock.Mock(return_value=mock.MagicMock(status_code=200))
        requests_mock.get = get_mock

        bridge = RiskIndicatorBridge(self.config)
        bridge.request(bridge.indicators_host + "some-path/")

        get_mock.assert_called_once_with(bridge.indicators_host + "some-path/",
                                         timeout=bridge.request_timeout)
    def test_request_tender_api_with_proxy(self, requests_mock):
        get_mock = mock.Mock(return_value=mock.MagicMock(status_code=200))
        requests_mock.get = get_mock

        new_config = deepcopy(self.config)
        new_config["main"]["indicators_proxy"] = "http://127.0.0.1:8080"

        bridge = RiskIndicatorBridge(new_config)
        bridge.request(bridge.monitors_host + "some-path/")

        get_mock.assert_called_once_with(
            bridge.monitors_host + "some-path/",
            timeout=bridge.request_timeout,
        )
    def test_process_risks_exception(self, process_risks_mock):
        process_risks_mock.side_effect = Exception("Shit happens")

        bridge = RiskIndicatorBridge(self.config)

        sleep_mock = mock.Mock()
        sleep_mock.side_effect = StopIteration
        with mock.patch("openprocurement.bot.risk_indicators.bridge.sleep",
                        sleep_mock):
            try:
                bridge.run()
            except StopIteration:
                pass

        sleep_mock.assert_called_once_with(bridge.queue_error_interval)
    def test_request_exception(self, requests_mock):
        requests_mock.get.side_effect = Exception("Shit happens")

        bridge = RiskIndicatorBridge(self.config)
        bridge.request_retries = 2

        try:
            bridge.request("http://localhost")
        except bridge.TerminateExecutionException as e:
            print(str(e))
        else:
            raise AssertionError("TerminateExecutionException expected")

        self.assertEqual(len(requests_mock.get.call_args_list), 2)
        requests_mock.get.assert_called_with('http://localhost',
                                             timeout=bridge.request_timeout)
    def test_request_json_exception(self, requests_mock):
        requests_mock.get.return_value = requests.Response()
        requests_mock.get.return_value.status_code = 200

        bridge = RiskIndicatorBridge(self.config)
        bridge.request_retries = 2

        try:
            bridge.request("http://localhost")
        except bridge.TerminateExecutionException as e:
            print(str(e))
        else:
            raise AssertionError("TerminateExecutionException expected")

        self.assertEqual(len(requests_mock.get.call_args_list), 2)
        requests_mock.get.assert_called_with('http://localhost',
                                             timeout=bridge.request_timeout)
    def test_process_risk_exception(self, process_risk_mock):
        process_risk_mock.side_effect = Exception("Shit happens")

        bridge = RiskIndicatorBridge(self.config)

        with mock.patch(
                "openprocurement.bot.risk_indicators.bridge.RiskIndicatorBridge.queue",
                range(12)):

            sleep_mock = mock.Mock()
            sleep_mock.side_effect = StopIteration
            with mock.patch("openprocurement.bot.risk_indicators.bridge.sleep",
                            sleep_mock):
                try:
                    bridge.run()
                except StopIteration:
                    pass

        sleep_mock.assert_called_once_with(
            (bridge.run_interval - timedelta(seconds=1)).seconds)
def main(config_path=None):
    if config_path is None:
        if len(sys.argv) < 2:
            logger.critical("Config is not provided")
            return
        config_path = sys.argv[1]

    if not os.path.isfile(config_path):
        logger.critical('Invalid configuration file')
        return

    try:
        with open(config_path) as config_file_obj:
            config = yaml.load(config_file_obj.read())
    except Exception as e:
        logger.critical('Invalid configuration file')
        logger.critical(str(e))
        return

    try:
        logging.config.dictConfig(config)
        RiskIndicatorBridge(config).run()
    except Exception as e:
        logger.critical("Unhandled exception: {}".format(e))