|
3 | 3 | """ |
4 | 4 |
|
5 | 5 | import gzip |
| 6 | +import json |
6 | 7 | import os |
| 8 | +import re |
7 | 9 | from contextlib import contextmanager |
8 | 10 | from unittest.mock import AsyncMock, MagicMock, patch |
9 | 11 |
|
@@ -120,6 +122,66 @@ def test_clickhouse_backend(_, tmp_path): |
120 | 122 | assert "Run duration was" in result.output |
121 | 123 |
|
122 | 124 |
|
| 125 | +@patch( |
| 126 | + "xapi_db_load.backends.base_async_backend.clickhouse_connect", |
| 127 | + new_callable=AsyncMock, |
| 128 | +) |
| 129 | +@patch( |
| 130 | + "xapi_db_load.backends.vector.getLogger", |
| 131 | + new_callable=MagicMock, |
| 132 | +) |
| 133 | +def test_vector_backend(mock_get_logger, _, tmp_path): |
| 134 | + """ |
| 135 | + Run a test through the Vector backend, currently this just checks that the |
| 136 | + output indicates success. |
| 137 | + """ |
| 138 | + test_path = "xapi_db_load/tests/fixtures/small_vector_config.yaml" |
| 139 | + |
| 140 | + runner = CliRunner() |
| 141 | + |
| 142 | + with override_config(test_path, tmp_path): |
| 143 | + result = runner.invoke( |
| 144 | + load_db, |
| 145 | + f"--config_file {test_path}", |
| 146 | + catch_exceptions=False, |
| 147 | + ) |
| 148 | + |
| 149 | + # This test should create 300 xAPI log statemetns |
| 150 | + assert mock_get_logger.return_value.info.call_count == 300 |
| 151 | + |
| 152 | + last_logged_statement = mock_get_logger.return_value.info.call_args.args[0] |
| 153 | + |
| 154 | + # We check to make sure Vector's regex will parse what we're sending. We want it to match both |
| 155 | + # the LMS and our local logger formatter. |
| 156 | + # This is how things are generally formatted in the LMS |
| 157 | + test_str_1 = f"2026-02-24 20:26:13,006 INFO 42 [xapi_tracking] [user None] [ip 172.19.0.1] logger.py:41 - {last_logged_statement}" |
| 158 | + |
| 159 | + # This returns our message formatted with the abbreviated version we use for size and speed purposes |
| 160 | + formatter = mock_get_logger.return_value.addHandler.call_args.args[0].formatter |
| 161 | + test_str_2 = formatter._fmt.format( |
| 162 | + name="xapi_tracking", message=last_logged_statement |
| 163 | + ) |
| 164 | + |
| 165 | + # This is a direct copy and paste from Aspects' Vector common-post.toml |
| 166 | + msg_regex = r"^.* \[xapi_tracking\] [^{}]* (?P<tracking_message>\{.*\})$" |
| 167 | + |
| 168 | + # Quick test to make sure that what's being stored is at least parseable |
| 169 | + for s in (test_str_1, test_str_2): |
| 170 | + try: |
| 171 | + statement = re.match(msg_regex, s).groups()[0] |
| 172 | + json.loads(statement) |
| 173 | + except Exception as e: |
| 174 | + print(e) |
| 175 | + print("Exception! Regex testing: ") |
| 176 | + print(s) |
| 177 | + raise |
| 178 | + |
| 179 | + assert "Insert xAPI Events complete." in result.output |
| 180 | + assert "Insert Initial Enrollments complete." in result.output |
| 181 | + assert "ALL TASKS DONE!" in result.output |
| 182 | + assert "Run duration was" in result.output |
| 183 | + |
| 184 | + |
123 | 185 | @patch("xapi_db_load.backends.ralph.requests", new_callable=AsyncMock) |
124 | 186 | @patch( |
125 | 187 | "xapi_db_load.backends.base_async_backend.clickhouse_connect", |
|
0 commit comments