Repository: aristanetworks/anta
Pull request #1200 (2025-05-14 09:24:05)

feat(anta.tests): Added test case to verify bad syslog events
# Description

Added test case to verify bad syslog events

Fixes #https://github.com/aristanetworks/avd-internal/issues/254

# Checklist:

- [X] My code follows the style guidelines of this project
- [X] I have performed a self-review of my code
- [X] I have run pre-commit for code linting and typing (`pre-commit run`)
- [ ] I have made corresponding changes to the documentation
- [X] I have added tests that prove my fix is effective or that my feature works
- [X] New and existing unit tests pass locally with my changes (`tox -e testenv`)


codspeed-hq[bot]: <!-- __CODSPEED_PERFORMANCE_REPORT_COMMENT__ -->
<!-- __CODSPEED_INSTRUMENTATION_PERFORMANCE_REPORT_COMMENT__ -->

## [CodSpeed Performance Report](https://codspeed.io/aristanetworks/anta/branches/vitthalmagadum%3AAI%2Fbad_syslog)

### Merging #1200 will **not alter performance**

<sub>Comparing <code>vitthalmagadum:AI/bad_syslog</code> (1d41c27) with <code>main</code> (fe04213)</sub>



### Summary

`✅ 26` untouched benchmarks  




sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


github-actions[bot]: Conflicts have been resolved. A maintainer will review the pull request shortly.
sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=aristanetworks_anta&pullRequest=1200&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=aristanetworks_anta&pullRequest=1200&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [91.7% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)


sonarqubecloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=aristanetworks_anta&pullRequest=1200&metric=new_coverage&view=list) (required ≥ 80%)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=aristanetworks_anta&pullRequest=1200)



Patch:
diff --git a/anta/input_models/logging.py b/anta/input_models/logging.py
index 977f1ab0..56835ce4 100644
--- a/anta/input_models/logging.py
+++ b/anta/input_models/logging.py
@@ -5,17 +5,46 @@
 
 from __future__ import annotations
 
-from pydantic import BaseModel, Field
+from typing import TYPE_CHECKING, Annotated, Literal
+
+from pydantic import BaseModel, Field, model_validator
 
 from anta.custom_types import LogSeverityLevel, RegexString
 
+if TYPE_CHECKING:
+    import sys
+
+    if sys.version_info >= (3, 11):
+        from typing import Self
+    else:
+        from typing_extensions import Self
+
 
 class LoggingQuery(BaseModel):
     """Logging query model representing the logging details."""
 
-    regex_match: RegexString
-    """Log regex pattern to be searched in last log entries."""
-    last_number_messages: int = Field(ge=1, le=9999)
-    """Last number of messages to check in the logging buffers."""
+    regex_match: RegexString | list[RegexString]
+    """Log regex pattern(s) to be searched in last log entries."""
+    last_number_messages: Annotated[int, Field(ge=1, le=9999)] | None = None
+    """Last number of messages to check in the logging buffers. Takes precedence over `last_number_time_units`."""
+    last_number_time_units: Annotated[int, Field(ge=1, le=9999)] | None = None
+    """Number of time units to look in the logging buffers.
+
+    The actual duration is determined based on the selected `time_unit` (e.g. 5 "days", 10 "minutes")."""
+    time_unit: Literal["days", "hours", "minutes", "seconds"] = "days"
+    """Unit of time to be used with `last_number_time_units`."""
     severity_level: LogSeverityLevel = "informational"
     """Log severity level."""
+    fail_on_match: bool = False
+    """If `True`, the test fails if regex patterns are found. Otherwise, the test fails if patterns are not found instead."""
+
+    @model_validator(mode="after")
+    def validate_inputs(self) -> Self:
+        """Validate the inputs provided to the LoggingQuery class.
+
+        Either `last_number_messages` or `last_number_time_units` must be provided, not both.
+        """
+        if (self.last_number_messages is None) == (self.last_number_time_units is None):
+            msg = "Exactly one of 'last_number_messages' or 'last_number_time_units' must be provided"
+            raise ValueError(msg)
+        return self


Test patch:
diff --git a/anta/tests/logging.py b/anta/tests/logging.py
index cbc19bf9..b2ce7968 100644
--- a/anta/tests/logging.py
+++ b/anta/tests/logging.py
@@ -437,12 +437,17 @@ class VerifyLoggingErrors(AntaTest):
 
 
 class VerifyLoggingEntries(AntaTest):
-    """Verifies that the expected log string is present in the last specified log messages.
+    """Verifies that log strings are present or absent in the logging buffer.
 
     Expected Results
     ----------------
-    * Success: The test will pass if the expected log string for the mentioned severity level is present in the last specified log messages.
-    * Failure: The test will fail if the specified log string is not present in the last specified log messages.
+    * Success:
+        - If `fail_on_match` is `False` (default): the test will pass if all specified patterns are found in the log output.
+        - If `fail_on_match` is `True`: the test will pass if none of the specified patterns are found in the log output.
+
+    * Failure:
+        - If `fail_on_match` is `False`: the test will fail if any of the specified patterns are missing from the log output.
+        - If `fail_on_match` is `True`: the test will fail if any of the specified patterns are found in the log output.
 
     Examples
     --------
@@ -453,16 +458,18 @@ class VerifyLoggingEntries(AntaTest):
             - regex_match: ".*ACCOUNTING-5-EXEC: cvpadmin ssh.*"
               last_number_messages: 30
               severity_level: alerts
-            - regex_match: ".*SPANTREE-6-INTERFACE_ADD:.*"
-              last_number_messages: 10
+            - regex_match:
+                - ".*SPANTREE-6-INTERFACE_ADD:.*"
+                - ".*ACCOUNTING-5-EXEC: cvpadmin ssh.*"
+              last_number_time_units: 3
+              time_unit: hours
               severity_level: critical
+              fail_on_match: True
     ```
     """
 
     categories: ClassVar[list[str]] = ["logging"]
-    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
-        AntaTemplate(template="show logging {last_number_messages} {severity_level}", ofmt="text", use_cache=False)
-    ]
+    commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show logging {log_history_depth} {severity_level}", ofmt="text", use_cache=False)]
 
     class Input(AntaTest.Input):
         """Input model for the VerifyLoggingEntries test."""
@@ -471,8 +478,16 @@ class VerifyLoggingEntries(AntaTest):
         """List of logging entries and regex match."""
 
     def render(self, template: AntaTemplate) -> list[AntaCommand]:
-        """Render the template for last number messages and log severity level in the input."""
-        return [template.render(last_number_messages=entry.last_number_messages, severity_level=entry.severity_level) for entry in self.inputs.logging_entries]
+        """Render the template for log history depth and log severity level in the input."""
+        commands: list[AntaCommand] = []
+        for entry in self.inputs.logging_entries:
+            log_history_depth: str | int = ""
+            if entry.last_number_messages:
+                log_history_depth = entry.last_number_messages
+            elif entry.last_number_time_units:
+                log_history_depth = f"last {entry.last_number_time_units} {entry.time_unit}"
+            commands.append(template.render(log_history_depth=log_history_depth, severity_level=entry.severity_level))
+        return commands
 
     @AntaTest.anta_test
     def test(self) -> None:
@@ -480,7 +495,16 @@ class VerifyLoggingEntries(AntaTest):
         self.result.is_success()
         for command_output, logging_entry in zip(self.instance_commands, self.inputs.logging_entries):
             output = command_output.text_output
-            if not re.search(logging_entry.regex_match, output):
-                self.result.is_failure(
-                    f"Pattern: `{logging_entry.regex_match}` - Not found in last {logging_entry.last_number_messages} {logging_entry.severity_level} log entries"
-                )
+            log_history_depth = command_output.params.log_history_depth
+            patterns_to_check = logging_entry.regex_match if isinstance(logging_entry.regex_match, list) else [logging_entry.regex_match]
+
+            for pattern in patterns_to_check:
+                match_found = re.search(pattern, output)
+
+                # Fails if any of the regex patterns are found
+                if logging_entry.fail_on_match and match_found:
+                    self.result.is_failure(f"Unexpected Pattern: `{pattern}` - Found in last {log_history_depth} {logging_entry.severity_level} log entries")
+
+                # Fails if any of the regex patterns not found
+                if not logging_entry.fail_on_match and not match_found:
+                    self.result.is_failure(f"Pattern: `{pattern}` - Not found in last {log_history_depth} {logging_entry.severity_level} log entries")
diff --git a/examples/tests.yaml b/examples/tests.yaml
index 035dc322..06985e6d 100644
--- a/examples/tests.yaml
+++ b/examples/tests.yaml
@@ -394,14 +394,18 @@ anta.tests.logging:
   - VerifyLoggingAccounting:
       # Verifies if AAA accounting logs are generated.
   - VerifyLoggingEntries:
-      # Verifies that the expected log string is present in the last specified log messages.
+      # Verifies that log strings are present or absent in the logging buffer.
       logging_entries:
         - regex_match: ".*ACCOUNTING-5-EXEC: cvpadmin ssh.*"
           last_number_messages: 30
           severity_level: alerts
-        - regex_match: ".*SPANTREE-6-INTERFACE_ADD:.*"
-          last_number_messages: 10
+        - regex_match:
+            - ".*SPANTREE-6-INTERFACE_ADD:.*"
+            - ".*ACCOUNTING-5-EXEC: cvpadmin ssh.*"
+          last_number_time_units: 3
+          time_unit: hours
           severity_level: critical
+          fail_on_match: True
   - VerifyLoggingErrors:
       # Verifies there are no syslog messages with a severity of ERRORS or higher.
   - VerifyLoggingHostname:
diff --git a/tests/units/anta_tests/test_logging.py b/tests/units/anta_tests/test_logging.py
index 6407f37a..d99a6497 100644
--- a/tests/units/anta_tests/test_logging.py
+++ b/tests/units/anta_tests/test_logging.py
@@ -226,6 +226,45 @@ DATA: AntaUnitTestDataDict = {
         },
         "expected": {"result": AntaTestStatus.SUCCESS},
     },
+    (VerifyLoggingEntries, "success-list-of-regex"): {
+        "eos_data": [
+            "Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-6-TERMINATE_RUNNING_PROCESS: Terminating deconfigured/reconfigured process 'SystemInitMonitor'"
+            " (PID=859)\n Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-6-PROCESS_TERMINATED: 'SystemInitMonitor' (PID=859, status=9) has terminated."
+            "Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-7-WORKER_WARMSTART_DONE: ProcMgr worker warm start done. (PID=547)",
+        ],
+        "inputs": {
+            "logging_entries": [
+                {"regex_match": [".*PROCMGR-6-PROCESS_TERMINATED:.*", ".*ProcMgr worker warm start.*"], "last_number_messages": 3},
+            ]
+        },
+        "expected": {"result": AntaTestStatus.SUCCESS},
+    },
+    (VerifyLoggingEntries, "success-fail-on-match-true"): {
+        "eos_data": [
+            "Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-6-TERMINATE_RUNNING_PROCESS: Terminating deconfigured/reconfigured process 'SystemInitMonitor'"
+            " (PID=859)\n Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-6-PROCESS2_TERMINATED: 'SystemInitMonitor' (PID=859, status=9) has terminated.",
+            "Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-7-WORKER_WARMSTART_DONE: ProcMgr worker2 warm start done. (PID=547)",
+        ],
+        "inputs": {
+            "logging_entries": [
+                {"regex_match": ".*PROCMGR-6-PROCESS_TERMINATED:.*", "last_number_messages": 3, "fail_on_match": True},
+                {"regex_match": ".*ProcMgr worker warm start.*", "last_number_messages": 2, "severity_level": "debugging", "fail_on_match": True},
+            ]
+        },
+        "expected": {"result": AntaTestStatus.SUCCESS},
+    },
+    (VerifyLoggingEntries, "success-list-of-regex-fail-on-match-true"): {
+        "eos_data": [
+            "Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-6-TERMINATE_RUNNING_PROCESS: Terminating deconfigured/reconfigured process 'SystemInitMonitor'"
+            " (PID=859)\n Mar 13 04:10:45 s1-leaf1 ProcMgr: %PROCMGR-6-PROCESS2_TERMINATED: 'SystemInitMonitor' (PID=859, status=9) has terminated.",
+        ],
+        "inputs": {
+            "logging_entries": [
+                {"regex_match": [".*PROCMGR-6-PROCESS_TERMINATED:.*", ".*ProcMgr worker warm start.*"], "last_number_messages": 3, "fail_on_match": True},
+            ]
+        },
+        "expected": {"result": AntaTestStatus.SUCCESS},
+    },
     (VerifyLoggingEntries, "failure-log-str-not-found"): {
         "eos_data": [
             "Mar 12 04:34:01 s1-leaf1 ProcMgr: %PROCMGR-7-WORKER_WARMSTART_DONE: ProcMgr worker warm start done. (PID=559)\nMar 12 04:34:01 "
@@ -248,4 +287,65 @@ DATA: AntaUnitTestDataDict = {
             ],
         },
     },
+    (VerifyLoggingEntries, "failure-list-of-regex"): {
+        "eos_data": [
+            "Mar 12 04:34:01 s1-leaf1 ProcMgr: %PROCMGR-7-WORKER_WARMSTART_DONE: ProcMgr worker2 warm start done. (PID=559)\nMar 12 04:34:01 "
+            "s1-leaf1 ProcMgr: %PROCMGR-6-PROCESS_TERMINATED: 'SystemInitMonitor' (PID=867, status=9) has terminated."
+            "Mar 13 03:58:12 s1-leaf1 ConfigAgent: %SYS-5-CONFIG_SESSION_ABORTED: User cvpsystem aborted\n             "
+            "configuration session capiVerify-612-612b34a2ffbf11ef96ba3a348d538ba0 on TerminAttr (localhost)\n "
+            "Mar 13 04:10:45 s1-leaf1 SystemInitMonitor: %SYS-5-SYSTEM_INITIALIZED: System is initialized",
+        ],
+        "inputs": {
+            "logging_entries": [
+                {"regex_match": [".ACCOUNTING-5-EXEC: cvpadmin ssh.", ".*ProcMgr worker warm start.*"], "last_number_messages": 3},
+            ]
+        },
+        "expected": {
+            "result": AntaTestStatus.FAILURE,
+            "messages": [
+                "Pattern: `.ACCOUNTING-5-EXEC: cvpadmin ssh.` - Not found in last 3 informational log entries",
+                "Pattern: `.*ProcMgr worker warm start.*` - Not found in last 3 informational log entries",
+            ],
+        },
+    },
+    (VerifyLoggingEntries, "failure-list-of-regex-fail-on-match"): {
+        "eos_data": [
+            "Mar 12 04:34:01 s1-leaf1 ProcMgr: %PROCMGR-7-WORKER_WARMSTART_DONE: ProcMgr worker warm start done. (PID=559)\nMar 12 04:34:01 "
+            "s1-leaf1 ProcMgr: %PROCMGR-6-PROCESS_TERMINATED: 'SystemInitMonitor' (PID=867, status=9) has terminated."
+            "Mar 13 03:58:12 s1-leaf1 ConfigAgent: %SYS-5-CONFIG_SESSION_ABORTED: User cvpsystem aborted\n             "
+            "configuration session capiVerify-612-612b34a2ffbf11ef96ba3a348d538ba0 on TerminAttr (localhost)\n "
+            "Mar 13 04:10:45 s1-leaf1 SystemInitMonitor: %SYS-5-SYSTEM_INITIALIZED: System is initialized",
+        ],
+        "inputs": {
+            "logging_entries": [
+                {"regex_match": [".ACCOUNTING-5-EXEC: cvpadmin ssh.", ".*ProcMgr worker warm start.*"], "last_number_messages": 3, "fail_on_match": True},
+            ]
+        },
+        "expected": {
+            "result": AntaTestStatus.FAILURE,
+            "messages": [
+                "Unexpected Pattern: `.*ProcMgr worker warm start.*` - Found in last 3 informational log entries",
+            ],
+        },
+    },
+    (VerifyLoggingEntries, "failure-last-time-units"): {
+        "eos_data": [
+            "Mar 12 04:34:01 s1-leaf1 ProcMgr: %PROCMGR-7-WORKER_WARMSTART_DONE: ProcMgr worker warm start done. (PID=559)\nMar 12 04:34:01 "
+            "s1-leaf1 ProcMgr: %PROCMGR-6-PROCESS_TERMINATED: 'SystemInitMonitor' (PID=867, status=9) has terminated."
+            "Mar 13 03:58:12 s1-leaf1 ConfigAgent: %SYS-5-CONFIG_SESSION_ABORTED: User cvpsystem aborted\n             "
+            "configuration session capiVerify-612-612b34a2ffbf11ef96ba3a348d538ba0 on TerminAttr (localhost)\n "
+            "Mar 13 04:10:45 s1-leaf1 SystemInitMonitor: %SYS-5-SYSTEM_INITIALIZED: System is initialized",
+        ],
+        "inputs": {
+            "logging_entries": [
+                {"regex_match": [".ACCOUNTING-5-EXEC: cvpadmin ssh.", ".*ProcMgr worker warm start.*"], "last_number_time_units": 3, "fail_on_match": True},
+            ]
+        },
+        "expected": {
+            "result": AntaTestStatus.FAILURE,
+            "messages": [
+                "Unexpected Pattern: `.*ProcMgr worker warm start.*` - Found in last last 3 days informational log entries",
+            ],
+        },
+    },
 }