Skip to content

Commit

Permalink
Add setting to allow monitor not fail if stat is not present
Browse files Browse the repository at this point in the history
  • Loading branch information
rennerocha committed Dec 13, 2021
1 parent f2c3e45 commit dac6ebb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
29 changes: 28 additions & 1 deletion spidermon/contrib/scrapy/monitors.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,26 @@ class MyCustomStatMonitor(BaseStatMonitor):
def get_threshold(self):
item_scraped_count = self.stats.get("item_scraped_count")
return item_scraped_count * 0.01"""
return item_scraped_count * 0.01
By default, if the stat can't be found in job statistics, the monitor will fail.
If you want the monitor to be skipped in that case, you should set ``fail_if_stat_missing``
attribute as ``False``.
The following monitor will not fail if the job doesn't have a ``numerical_job_statistic``
value in its statistics:
.. code-block:: python
class MyCustomStatMonitor(BaseStatMonitor):
stat_name = "numerical_job_statistic"
threshold_setting = "CUSTOM_STAT_THRESHOLD"
assert_type = ">="
fail_if_stat_missing = False
"""

fail_if_stat_missing = True

def run(self, result):
has_threshold_config = any(
Expand Down Expand Up @@ -113,6 +132,14 @@ def test_stat_monitor(self):
"!=": self.assertNotEqual,
}
threshold = self._get_threshold_value()

if self.stat_name not in self.stats:
message = f"Unable to find '{self.stat_name}' in job stats."
if self.fail_if_stat_missing:
self.fail(message)
else:
self.skipTest(message)

value = self.stats.get(self.stat_name)

assertion_method = assertions.get(self.assert_type)
Expand Down
2 changes: 1 addition & 1 deletion spidermon/results/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def addFailure(self, test, error):
@monitors_step_required
def addSkip(self, test, reason):
super().addSkip(test, reason)
self.step[test].status = settings.MONITOR.STATUS.FAILURE
self.step[test].status = settings.MONITOR.STATUS.SKIPPED
self.step[test].reason = reason

@monitors_step_required
Expand Down
51 changes: 51 additions & 0 deletions tests/contrib/scrapy/monitors/test_base_stat_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,54 @@ class TestBaseStatMonitor(BaseStatMonitor):
== f"Expecting '{TestBaseStatMonitor.stat_name}' to be '{TestBaseStatMonitor.assert_type}' "
f"to '{expected_threshold}'. Current value: '{obtained_value}'",
)


def test_fail_if_stat_can_not_be_found(make_data):
class TestBaseStatMonitor(BaseStatMonitor):
stat_name = "test_statistic"
threshold_setting = "THRESHOLD_SETTING"
assert_type = ">="

data = make_data({"THRESHOLD_SETTING": 100})
runner = data.pop("runner")
data["stats"] = {"other_stats": 1}
monitor_suite = MonitorSuite(monitors=[TestBaseStatMonitor])

runner.run(monitor_suite, **data)
assert runner.result.monitor_results[0].status == settings.MONITOR.STATUS.FAILURE


def test_success_if_stat_can_not_be_found_but_monitor_configured_to_not_ignore_it(
make_data,
):
class TestBaseStatMonitor(BaseStatMonitor):
stat_name = "test_statistic"
threshold_setting = "THRESHOLD_SETTING"
assert_type = ">="
fail_if_stat_missing = True

data = make_data({"THRESHOLD_SETTING": 100})
runner = data.pop("runner")
data["stats"] = {"other_stats": 1}
monitor_suite = MonitorSuite(monitors=[TestBaseStatMonitor])

runner.run(monitor_suite, **data)
assert runner.result.monitor_results[0].status == settings.MONITOR.STATUS.FAILURE


def test_skipped_if_stat_can_not_be_found_but_monitor_configured_to_be_ignore(
make_data,
):
class TestBaseStatMonitor(BaseStatMonitor):
stat_name = "test_statistic"
threshold_setting = "THRESHOLD_SETTING"
assert_type = ">="
fail_if_stat_missing = False

data = make_data({"THRESHOLD_SETTING": 100})
runner = data.pop("runner")
data["stats"] = {"other_stats": 1}
monitor_suite = MonitorSuite(monitors=[TestBaseStatMonitor])

runner.run(monitor_suite, **data)
assert runner.result.monitor_results[0].status == settings.MONITOR.STATUS.SKIPPED

0 comments on commit dac6ebb

Please sign in to comment.