From fa76eebf85bbb2dc17a314d8b8da09a6d727a263 Mon Sep 17 00:00:00 2001 From: brokensound77 Date: Tue, 7 Mar 2023 11:58:06 -0700 Subject: [PATCH 1/2] cache rule loader; skip rule tests on RL failure --- tests/base.py | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/tests/base.py b/tests/base.py index f090f66b162..ecf00b8695d 100644 --- a/tests/base.py +++ b/tests/base.py @@ -5,26 +5,60 @@ """Shared resources for tests.""" -import os import unittest +from functools import lru_cache from typing import Union from detection_rules.rule import TOMLRule from detection_rules.rule_loader import DeprecatedCollection, DeprecatedRule, RuleCollection, production_filter +RULE_LOADER_FAIL = False +RULE_LOADER_FAIL_MSG = None +RULE_LOADER_FAIL_RAISED = False + + +@lru_cache +def default_rules() -> RuleCollection: + return RuleCollection.default() + + class BaseRuleTest(unittest.TestCase): """Base class for shared test cases which need to load rules""" @classmethod def setUpClass(cls): - os.environ["DR_NOTIFY_INTEGRATION_UPDATE_AVAILABLE"] = "1" - rc = RuleCollection.default() - cls.all_rules = rc.rules - cls.rule_lookup = rc.id_map - cls.production_rules = rc.filter(production_filter) - cls.deprecated_rules: DeprecatedCollection = rc.deprecated + global RULE_LOADER_FAIL, RULE_LOADER_FAIL_MSG + + # too noisy; refactor + # os.environ["DR_NOTIFY_INTEGRATION_UPDATE_AVAILABLE"] = "1" + + if not RULE_LOADER_FAIL: + try: + rc = default_rules() + cls.all_rules = rc.rules + cls.rule_lookup = rc.id_map + cls.production_rules = rc.filter(production_filter) + cls.deprecated_rules: DeprecatedCollection = rc.deprecated + except Exception as e: + RULE_LOADER_FAIL = True + RULE_LOADER_FAIL_MSG = str(e) @staticmethod def rule_str(rule: Union[DeprecatedRule, TOMLRule], trailer=' ->'): return f'{rule.id} - {rule.name}{trailer or ""}' + + def setUp(self) -> None: + global RULE_LOADER_FAIL, RULE_LOADER_FAIL_MSG, RULE_LOADER_FAIL_RAISED + + if RULE_LOADER_FAIL: + # limit the loader failure to just one run + # raise a dedicated test failure for the loader + if not RULE_LOADER_FAIL_RAISED: + RULE_LOADER_FAIL_RAISED = True + with self.subTest('Test that the rule loader loaded with no validation or other failures.'): + self.fail(f'Rule loader failure: \n{RULE_LOADER_FAIL_MSG}') + + self.skipTest('Rule loader failure') + else: + super(BaseRuleTest, self).setUp() From ed02774303012ebacc9c379d15578ee1a4abdb4c Mon Sep 17 00:00:00 2001 From: brokensound77 Date: Tue, 7 Mar 2023 15:40:51 -0700 Subject: [PATCH 2/2] Move global constants to class variables --- tests/base.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/tests/base.py b/tests/base.py index ecf00b8695d..1dc26c674bf 100644 --- a/tests/base.py +++ b/tests/base.py @@ -13,11 +13,6 @@ from detection_rules.rule_loader import DeprecatedCollection, DeprecatedRule, RuleCollection, production_filter -RULE_LOADER_FAIL = False -RULE_LOADER_FAIL_MSG = None -RULE_LOADER_FAIL_RAISED = False - - @lru_cache def default_rules() -> RuleCollection: return RuleCollection.default() @@ -26,14 +21,16 @@ def default_rules() -> RuleCollection: class BaseRuleTest(unittest.TestCase): """Base class for shared test cases which need to load rules""" + RULE_LOADER_FAIL = False + RULE_LOADER_FAIL_MSG = None + RULE_LOADER_FAIL_RAISED = False + @classmethod def setUpClass(cls): - global RULE_LOADER_FAIL, RULE_LOADER_FAIL_MSG - # too noisy; refactor # os.environ["DR_NOTIFY_INTEGRATION_UPDATE_AVAILABLE"] = "1" - if not RULE_LOADER_FAIL: + if not cls.RULE_LOADER_FAIL: try: rc = default_rules() cls.all_rules = rc.rules @@ -41,24 +38,22 @@ def setUpClass(cls): cls.production_rules = rc.filter(production_filter) cls.deprecated_rules: DeprecatedCollection = rc.deprecated except Exception as e: - RULE_LOADER_FAIL = True - RULE_LOADER_FAIL_MSG = str(e) + cls.RULE_LOADER_FAIL = True + cls.RULE_LOADER_FAIL_MSG = str(e) @staticmethod - def rule_str(rule: Union[DeprecatedRule, TOMLRule], trailer=' ->'): + def rule_str(rule: Union[DeprecatedRule, TOMLRule], trailer=' ->') -> str: return f'{rule.id} - {rule.name}{trailer or ""}' def setUp(self) -> None: - global RULE_LOADER_FAIL, RULE_LOADER_FAIL_MSG, RULE_LOADER_FAIL_RAISED - - if RULE_LOADER_FAIL: + if self.RULE_LOADER_FAIL: # limit the loader failure to just one run # raise a dedicated test failure for the loader - if not RULE_LOADER_FAIL_RAISED: - RULE_LOADER_FAIL_RAISED = True + if not self.RULE_LOADER_FAIL_RAISED: + self.RULE_LOADER_FAIL_RAISED = True with self.subTest('Test that the rule loader loaded with no validation or other failures.'): - self.fail(f'Rule loader failure: \n{RULE_LOADER_FAIL_MSG}') + self.fail(f'Rule loader failure: \n{self.RULE_LOADER_FAIL_MSG}') self.skipTest('Rule loader failure') else: - super(BaseRuleTest, self).setUp() + super().setUp()