|
| 1 | +"""Tests for the xAPI statements forwarding background task""" |
| 2 | + |
| 3 | +import asyncio |
| 4 | +import logging |
| 5 | + |
| 6 | +import pytest |
| 7 | +from httpx import RequestError |
| 8 | +from hypothesis import HealthCheck, settings |
| 9 | +from hypothesis import strategies as st |
| 10 | + |
| 11 | +from ralph.api.forwarding import ( |
| 12 | + ForwardingConfiguration, |
| 13 | + forward_xapi_statements, |
| 14 | + get_valid_xapi_forwarding, |
| 15 | +) |
| 16 | + |
| 17 | +from tests.fixtures.hypothesis_strategies import custom_builds, custom_given |
| 18 | + |
| 19 | + |
| 20 | +@custom_given(ForwardingConfiguration) |
| 21 | +def test_api_forwarding_get_valid_xapi_forwarding_with_valid_values(config): |
| 22 | + """Tests that the `get_valid_xapi_forwarding` function, given valid values, should |
| 23 | + return the expected list of valid configurations. |
| 24 | + """ |
| 25 | + |
| 26 | + assert len(get_valid_xapi_forwarding([config])) == 1 |
| 27 | + assert len(get_valid_xapi_forwarding([config, config])) == 2 |
| 28 | + |
| 29 | + |
| 30 | +@pytest.mark.parametrize( |
| 31 | + "values,expected", |
| 32 | + [ |
| 33 | + # Empty values should be ignored |
| 34 | + ([{}], []), |
| 35 | + # Non active forwarding should be ignored |
| 36 | + ( |
| 37 | + [ |
| 38 | + { |
| 39 | + "url": "http://localhost", |
| 40 | + "is_active": False, |
| 41 | + "basic_username": "username", |
| 42 | + "basic_password": "password", |
| 43 | + "max_retries": 1, |
| 44 | + "timeout": 10, |
| 45 | + } |
| 46 | + ], |
| 47 | + [], |
| 48 | + ), |
| 49 | + # Incomplete forwarding should be ignored |
| 50 | + ( |
| 51 | + [ |
| 52 | + # Incomplete |
| 53 | + { |
| 54 | + "url": "http://localhost", |
| 55 | + "is_active": True, |
| 56 | + }, |
| 57 | + # Valid |
| 58 | + { |
| 59 | + "url": "http://localhost", |
| 60 | + "is_active": True, |
| 61 | + "basic_username": "username", |
| 62 | + "basic_password": "password", |
| 63 | + "max_retries": 1, |
| 64 | + "timeout": 10, |
| 65 | + }, |
| 66 | + # Incomplete |
| 67 | + { |
| 68 | + "is_active": True, |
| 69 | + "basic_username": "username", |
| 70 | + "basic_password": "password", |
| 71 | + "max_retries": 1, |
| 72 | + }, |
| 73 | + ], |
| 74 | + [ |
| 75 | + ForwardingConfiguration( |
| 76 | + url="http://localhost", |
| 77 | + is_active=True, |
| 78 | + basic_username="username", |
| 79 | + basic_password="password", |
| 80 | + max_retries=1, |
| 81 | + timeout=10, |
| 82 | + ) |
| 83 | + ], |
| 84 | + ), |
| 85 | + ], |
| 86 | +) |
| 87 | +def test_api_forwarding_get_valid_xapi_forwarding_with_valid_and_invalid_values( |
| 88 | + values, expected, caplog |
| 89 | +): |
| 90 | + """Tests that the `get_valid_xapi_forwarding` function, given valid and invalid |
| 91 | + values, should return a list containing only valid values. |
| 92 | + """ |
| 93 | + |
| 94 | + with caplog.at_level(logging.DEBUG): |
| 95 | + assert get_valid_xapi_forwarding(values) == expected |
| 96 | + assert "Invalid RALPH_XAPI_FORWARDING.forwarder configuration value" in ( |
| 97 | + caplog.record_tuples[0][2] |
| 98 | + ) |
| 99 | + |
| 100 | + |
| 101 | +@settings(suppress_health_check=(HealthCheck.function_scoped_fixture,)) |
| 102 | +@pytest.mark.parametrize("statements", [[{}, {"id": 1}]]) |
| 103 | +@custom_given(custom_builds(ForwardingConfiguration, max_retries=st.just(1))) |
| 104 | +def test_api_forwarding_forward_xapi_statements_with_successful_request( |
| 105 | + monkeypatch, caplog, statements, config |
| 106 | +): |
| 107 | + """Tests the `forward_xapi_statements` function should log the forwarded statements |
| 108 | + count if the request was successful. |
| 109 | + """ |
| 110 | + |
| 111 | + class MockSuccessfulResponse: |
| 112 | + """Dummy Successful Response.""" |
| 113 | + |
| 114 | + @staticmethod |
| 115 | + def raise_for_status(): |
| 116 | + """Does not raise any exceptions.""" |
| 117 | + |
| 118 | + async def post_success(*args, **kwargs): # pylint: disable=unused-argument |
| 119 | + """Returns a MockSuccessfulResponse instance.""" |
| 120 | + |
| 121 | + return MockSuccessfulResponse() |
| 122 | + |
| 123 | + monkeypatch.setattr("ralph.api.forwarding.AsyncClient.post", post_success) |
| 124 | + monkeypatch.setattr("ralph.api.forwarding.VALID_XAPI_FORWARDING", [config]) |
| 125 | + |
| 126 | + with caplog.at_level(logging.DEBUG): |
| 127 | + asyncio.get_event_loop().run_until_complete(forward_xapi_statements(statements)) |
| 128 | + |
| 129 | + assert [ |
| 130 | + f"Forwarded {len(statements)} statements to {config.url} with success." |
| 131 | + ] == [message for source, _, message in caplog.record_tuples if source != "asyncio"] |
| 132 | + |
| 133 | + |
| 134 | +@settings(suppress_health_check=(HealthCheck.function_scoped_fixture,)) |
| 135 | +@pytest.mark.parametrize("statements", [[{}, {"id": 1}]]) |
| 136 | +@custom_given(custom_builds(ForwardingConfiguration, max_retries=st.just(3))) |
| 137 | +def test_api_forwarding_forward_xapi_statements_with_unsuccessful_request( |
| 138 | + monkeypatch, caplog, statements, config |
| 139 | +): |
| 140 | + """Tests the `forward_xapi_statements` function should log the the error if the |
| 141 | + request was successful. |
| 142 | + """ |
| 143 | + |
| 144 | + class MockUnsuccessfulResponse: |
| 145 | + """Dummy Failing Response.""" |
| 146 | + |
| 147 | + @staticmethod |
| 148 | + def raise_for_status(): |
| 149 | + """Dummy raise_for_status method that is always raising an exception.""" |
| 150 | + |
| 151 | + raise RequestError("Something went wrong.") |
| 152 | + |
| 153 | + async def post_fail(*args, **kwargs): # pylint: disable=unused-argument |
| 154 | + """Returns a MockUnsuccessfulResponse instance.""" |
| 155 | + |
| 156 | + return MockUnsuccessfulResponse() |
| 157 | + |
| 158 | + monkeypatch.setattr("ralph.api.forwarding.AsyncClient.post", post_fail) |
| 159 | + monkeypatch.setattr("ralph.api.forwarding.VALID_XAPI_FORWARDING", [config]) |
| 160 | + |
| 161 | + with caplog.at_level(logging.DEBUG): |
| 162 | + asyncio.get_event_loop().run_until_complete(forward_xapi_statements(statements)) |
| 163 | + |
| 164 | + assert ["Failed to forward xapi statements. Something went wrong."] == [ |
| 165 | + message for source, _, message in caplog.record_tuples if source != "asyncio" |
| 166 | + ] |
0 commit comments