|
23 | 23 | # SOFTWARE. |
24 | 24 | # |
25 | 25 | ############################################################################### |
| 26 | +import types |
| 27 | + |
26 | 28 | import pytest |
27 | 29 |
|
28 | 30 | from nodescraper.connection.inband.inband import CommandArtifact |
@@ -141,3 +143,136 @@ def test_data_model(): |
141 | 143 | assert dmesg_data2.dmesg_content == ( |
142 | 144 | "2023-06-01T01:00:00,685236-05:00 test message1\n2023-06-01T02:30:00,685106-05:00 test message2" |
143 | 145 | ) |
| 146 | + |
| 147 | + |
| 148 | +class DummyRes: |
| 149 | + def __init__(self, command="", stdout="", exit_code=0, stderr=""): |
| 150 | + self.command = command |
| 151 | + self.stdout = stdout |
| 152 | + self.exit_code = exit_code |
| 153 | + self.stderr = stderr |
| 154 | + |
| 155 | + |
| 156 | +def get_collector(monkeypatch, run_map, system_info, conn_mock): |
| 157 | + c = DmesgCollector( |
| 158 | + system_info=system_info, |
| 159 | + system_interaction_level=SystemInteractionLevel.INTERACTIVE, |
| 160 | + connection=conn_mock, |
| 161 | + ) |
| 162 | + c.result = types.SimpleNamespace(artifacts=[], message=None) |
| 163 | + c._events = [] |
| 164 | + |
| 165 | + def _log_event(**kw): |
| 166 | + c._events.append(kw) |
| 167 | + |
| 168 | + def _run_sut_cmd(cmd, *args, **kwargs): |
| 169 | + return run_map(cmd, *args, **kwargs) |
| 170 | + |
| 171 | + monkeypatch.setattr(c, "_log_event", _log_event, raising=True) |
| 172 | + monkeypatch.setattr(c, "_run_sut_cmd", _run_sut_cmd, raising=True) |
| 173 | + return c |
| 174 | + |
| 175 | + |
| 176 | +def test_collect_rotations_good_path(monkeypatch, system_info, conn_mock): |
| 177 | + ls_out = ( |
| 178 | + "\n".join( |
| 179 | + [ |
| 180 | + "/var/log/dmesg_log", |
| 181 | + "/var/log/dmesg.1", |
| 182 | + "/var/log/dmesg.2.gz", |
| 183 | + "/var/log/dmesg.10.gz", |
| 184 | + ] |
| 185 | + ) |
| 186 | + + "\n" |
| 187 | + ) |
| 188 | + |
| 189 | + def run_map(cmd, **kwargs): |
| 190 | + if cmd.startswith("ls -1 /var/log/dmesg"): |
| 191 | + return DummyRes(command=cmd, stdout=ls_out, exit_code=0) |
| 192 | + if cmd.startswith("cat '"): |
| 193 | + if "/var/log/dmesg.1'" in cmd: |
| 194 | + return DummyRes(command=cmd, stdout="dmesg.1 content\n", exit_code=0) |
| 195 | + if "/var/log/dmesg_log'" in cmd: |
| 196 | + return DummyRes(command=cmd, stdout="dmesg content\n", exit_code=0) |
| 197 | + if "gzip -dc" in cmd and "/var/log/dmesg.2.gz" in cmd: |
| 198 | + return DummyRes(command=cmd, stdout="gz2 content\n", exit_code=0) |
| 199 | + if "gzip -dc" in cmd and "/var/log/dmesg.10.gz" in cmd: |
| 200 | + return DummyRes(command=cmd, stdout="gz10 content\n", exit_code=0) |
| 201 | + return DummyRes(command=cmd, stdout="", exit_code=1, stderr="unexpected") |
| 202 | + |
| 203 | + c = get_collector(monkeypatch, run_map, system_info, conn_mock) |
| 204 | + |
| 205 | + c._collect_dmesg_rotations() |
| 206 | + |
| 207 | + names = {a.filename for a in c.result.artifacts} |
| 208 | + assert names == { |
| 209 | + "rotated_dmesg_log.log", |
| 210 | + "rotated_dmesg.1.log", |
| 211 | + "rotated_dmesg.2.gz.log", |
| 212 | + "rotated_dmesg.10.gz.log", |
| 213 | + } |
| 214 | + |
| 215 | + descs = [e["description"] for e in c._events] |
| 216 | + assert "Collected dmesg rotated files" in descs |
| 217 | + |
| 218 | + |
| 219 | +def test_collect_rotations_no_files(monkeypatch, system_info, conn_mock): |
| 220 | + def run_map(cmd, **kwargs): |
| 221 | + if cmd.startswith("ls -1 /var/log/dmesg"): |
| 222 | + return DummyRes(command=cmd, stdout="", exit_code=0) |
| 223 | + return DummyRes(command=cmd, stdout="", exit_code=1) |
| 224 | + |
| 225 | + c = get_collector(monkeypatch, run_map, system_info, conn_mock) |
| 226 | + |
| 227 | + c._collect_dmesg_rotations() |
| 228 | + |
| 229 | + assert c.result.artifacts == [] |
| 230 | + |
| 231 | + events = c._events |
| 232 | + assert any( |
| 233 | + e["description"].startswith("No /var/log/dmesg files found") |
| 234 | + and e["priority"].name == "WARNING" |
| 235 | + for e in events |
| 236 | + ) |
| 237 | + |
| 238 | + |
| 239 | +def test_collect_rotations_gz_failure(monkeypatch, system_info, conn_mock): |
| 240 | + ls_out = "/var/log/dmesg.2.gz\n" |
| 241 | + |
| 242 | + def run_map(cmd, **kwargs): |
| 243 | + if cmd.startswith("ls -1 /var/log/dmesg"): |
| 244 | + return DummyRes(command=cmd, stdout=ls_out, exit_code=0) |
| 245 | + if "gzip -dc" in cmd and "/var/log/dmesg.2.gz" in cmd: |
| 246 | + return DummyRes(command=cmd, stdout="", exit_code=1, stderr="gzip: not found") |
| 247 | + return DummyRes(command=cmd, stdout="", exit_code=1) |
| 248 | + |
| 249 | + c = get_collector(monkeypatch, run_map, system_info, conn_mock) |
| 250 | + |
| 251 | + c._collect_dmesg_rotations() |
| 252 | + |
| 253 | + assert c.result.artifacts == [] |
| 254 | + |
| 255 | + fail_events = [ |
| 256 | + e for e in c._events if e["description"] == "Some dmesg files could not be collected." |
| 257 | + ] |
| 258 | + assert fail_events, "Expected a failure event" |
| 259 | + failed = fail_events[-1]["data"]["failed"] |
| 260 | + assert any(item["path"].endswith("/var/log/dmesg.2.gz") for item in failed) |
| 261 | + |
| 262 | + |
| 263 | +def test_collect_data_integration(monkeypatch, system_info, conn_mock): |
| 264 | + def run_map(cmd, **kwargs): |
| 265 | + if cmd == DmesgCollector.DMESG_CMD: |
| 266 | + return DummyRes(command=cmd, stdout="DMESG OUTPUT\n", exit_code=0) |
| 267 | + if cmd.startswith("ls -1 /var/log/dmesg"): |
| 268 | + return DummyRes(command=cmd, stdout="/var/log/dmesg\n", exit_code=0) |
| 269 | + if cmd.startswith("cat '") and "/var/log/dmesg'" in cmd: |
| 270 | + return DummyRes(command=cmd, stdout="dmesg file content\n", exit_code=0) |
| 271 | + return DummyRes(command=cmd, stdout="", exit_code=1) |
| 272 | + |
| 273 | + c = get_collector(monkeypatch, run_map, system_info, conn_mock) |
| 274 | + |
| 275 | + result, data = c.collect_data() |
| 276 | + |
| 277 | + assert isinstance(data, DmesgData) |
| 278 | + assert data.dmesg_content == "DMESG OUTPUT\n" |
0 commit comments