|
1 | 1 | import logging |
| 2 | +import re |
2 | 3 | from datetime import datetime |
3 | 4 | from typing import Dict, List, Union |
4 | 5 |
|
|
17 | 18 | "count_pods", |
18 | 19 | "pod_is_not_available", |
19 | 20 | "count_min_pods", |
| 21 | + "should_be_found_in_logs", |
20 | 22 | ] |
21 | 23 | logger = logging.getLogger("chaostoolkit") |
22 | 24 |
|
@@ -370,3 +372,43 @@ def count_min_pods( |
370 | 372 | label_selector=label_selector, phase=phase, ns=ns, secrets=secrets |
371 | 373 | ) |
372 | 374 | return count >= min_count |
| 375 | + |
| 376 | + |
| 377 | +def should_be_found_in_logs( |
| 378 | + pattern: str, |
| 379 | + all_containers: bool = True, |
| 380 | + value: Dict[str, str] = None, |
| 381 | + secrets: Secrets = None, |
| 382 | +) -> bool: |
| 383 | + """ |
| 384 | + Lookup for the first occurence of `pattern` in the logs of each container |
| 385 | + fetched by the `read_pod_logs` probe. |
| 386 | +
|
| 387 | + If `all_containers` is set the match must occur on all continers. Otherwise, |
| 388 | + allow for only a subset of containers to match the search. |
| 389 | + """ |
| 390 | + if not value: |
| 391 | + raise ActivityFailed("no logs to search from") |
| 392 | + |
| 393 | + c_pattern = re.compile(pattern) |
| 394 | + |
| 395 | + matched: list[re.Match] = [] |
| 396 | + |
| 397 | + for container_name in value: |
| 398 | + logs = value[container_name] |
| 399 | + m = c_pattern.search(logs) |
| 400 | + if m: |
| 401 | + logger.debug( |
| 402 | + f"Container '{container_name}' matched at position {m.span()}" |
| 403 | + ) |
| 404 | + matched.append(m) |
| 405 | + continue |
| 406 | + |
| 407 | + logger.debug(f"Container '{container_name}' did not match") |
| 408 | + |
| 409 | + if all_containers and (len(matched) != len(value)): |
| 410 | + return False |
| 411 | + elif not matched: |
| 412 | + return False |
| 413 | + |
| 414 | + return True |
0 commit comments