def test__make_request_failure(requests_wrapper):
    log = mock.MagicMock()

    instance = copy.deepcopy(common.MOCK_CONFIG["instances"][0])
    instance["paginated_limit"] = 4

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi.connect"):
        api = ApiFactory.create(log, instance, requests_wrapper)

    response_mock = mock.MagicMock()
    with mock.patch("datadog_checks.openstack_controller.api.requests.get",
                    return_value=response_mock):
        response_mock.raise_for_status.side_effect = requests.exceptions.HTTPError
        response_mock.status_code = 401
        with pytest.raises(AuthenticationNeeded):
            api._make_request("", {})

        response_mock.status_code = 409
        with pytest.raises(InstancePowerOffFailure):
            api._make_request("", {})

        response_mock.status_code = 500
        with pytest.raises(requests.exceptions.HTTPError):
            api._make_request("", {})

        response_mock.raise_for_status.side_effect = Exception
        with pytest.raises(Exception):
            api._make_request("", {})
def test__get_paginated_list(requests_wrapper):

    log = mock.MagicMock()

    instance = copy.deepcopy(common.MOCK_CONFIG["instances"][0])
    instance["paginated_limit"] = 4

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi.connect"):
        api = ApiFactory.create(log, instance, requests_wrapper)
    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # First call: 3 exceptions -> failure
                requests.exceptions.HTTPError,
                requests.exceptions.HTTPError,
                requests.exceptions.HTTPError,
            ],
    ):
        # First call
        with pytest.raises(RetryLimitExceeded):
            api._get_paginated_list("url", "obj", {})
        assert log.debug.call_count == 3
        log.reset_mock()

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # Second call: all good, 1 page with 4 results, one with 1
                {
                    "obj": [{
                        "id": 0
                    }, {
                        "id": 1
                    }, {
                        "id": 2
                    }, {
                        "id": 3
                    }],
                    "obj_links": "test"
                },
                {
                    "obj": [{
                        "id": 4
                    }]
                },
            ],
    ):
        # Second call
        assert api.paginated_limit == 4
        result = api._get_paginated_list("url", "obj", {})
        assert log.debug.call_count == 0
        assert result == [{
            "id": 0
        }, {
            "id": 1
        }, {
            "id": 2
        }, {
            "id": 3
        }, {
            "id": 4
        }]

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # Third call: 1 exception, limit is divided once by 2
                requests.exceptions.HTTPError,
                {
                    "obj": [{
                        "id": 0
                    }, {
                        "id": 1
                    }],
                    "obj_links": "test"
                },
                {
                    "obj": [{
                        "id": 2
                    }, {
                        "id": 3
                    }],
                    "obj_links": "test"
                },
                {
                    "obj": [{
                        "id": 4
                    }]
                },
            ],
    ):
        # Third call
        result = api._get_paginated_list("url", "obj", {})
        assert log.debug.call_count == 1
        assert result == [{
            "id": 0
        }, {
            "id": 1
        }, {
            "id": 2
        }, {
            "id": 3
        }, {
            "id": 4
        }]
        log.reset_mock()

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # Fourth call: 1 AuthenticationNeeded exception -> no retries
                AuthenticationNeeded,
                # Fifth call: any other exception -> no retries
                Exception,
            ],
    ):
        with pytest.raises(AuthenticationNeeded):
            api._get_paginated_list("url", "obj", {})
        with pytest.raises(Exception):
            api._get_paginated_list("url", "obj", {})
def test__get_paginated_list():

    log = mock.MagicMock()

    instance = copy.deepcopy(common.MOCK_CONFIG["instances"][0])
    instance["paginated_limit"] = 4

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi.connect"):
        api = ApiFactory.create(log, None, instance)
    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # First call: 3 exceptions -> failure
                Exception,
                Exception,
                Exception,
            ]):
        # First call
        with pytest.raises(Exception):
            api._get_paginated_list("url", "obj", {})
        assert log.debug.call_count == 3
        log.reset_mock()

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # Second call: all good, 1 page with 4 results, one with 1
                {
                    "obj": [{
                        "id": 0
                    }, {
                        "id": 1
                    }, {
                        "id": 2
                    }, {
                        "id": 3
                    }],
                    "obj_links": "test"
                },
                {
                    "obj": [{
                        "id": 4
                    }]
                },
            ]):
        # Second call
        assert api.paginated_limit == 4
        result = api._get_paginated_list("url", "obj", {})
        assert log.debug.call_count == 0
        assert result == [{
            "id": 0
        }, {
            "id": 1
        }, {
            "id": 2
        }, {
            "id": 3
        }, {
            "id": 4
        }]

    with mock.patch(
            "datadog_checks.openstack_controller.api.SimpleApi._make_request",
            side_effect=[
                # Third call: 1 exception, limit is divided once by 2
                Exception,
                {
                    "obj": [{
                        "id": 0
                    }, {
                        "id": 1
                    }],
                    "obj_links": "test"
                },
                {
                    "obj": [{
                        "id": 2
                    }, {
                        "id": 3
                    }],
                    "obj_links": "test"
                },
                {
                    "obj": [{
                        "id": 4
                    }]
                }
            ]):
        # Third call
        result = api._get_paginated_list("url", "obj", {})
        assert log.debug.call_count == 1
        assert result == [{
            "id": 0
        }, {
            "id": 1
        }, {
            "id": 2
        }, {
            "id": 3
        }, {
            "id": 4
        }]