def get_fp_data_files(): """get FP data files by fp dir name.""" data = {} for fp_dir in get_fp_dirs(): fp_dir_name = os.path.basename(fp_dir) relative_dir_name = os.path.join('false_positives', fp_dir_name) data[fp_dir_name] = combine_sources( *get_data_files(relative_dir_name).values()) return data
def test_true_positives(self): """Test that expected results return against true positives.""" mismatched_ecs = [] mappings = load_etc_dump('rule-mapping.yml') for rule in rule_loader.get_production_rules(): if isinstance(rule.contents.data, KQLRuleData): if rule.id not in mappings: continue mapping = mappings[rule.id] expected = mapping['count'] sources = mapping.get('sources') rta_file = mapping['rta_name'] # ensure sources is defined and not empty; schema allows it to not be set since 'pending' bypasses self.assertTrue( sources, 'No sources defined for: {} - {} '.format( rule.id, rule.name)) msg = 'Expected TP results did not match for: {} - {}'.format( rule.id, rule.name) data_files = [ get_data_files('true_positives', rta_file).get(s) for s in sources ] data_file = combine_sources(*data_files) results = self.evaluate(data_file, rule, expected, msg) ecs_versions = set( [r.get('ecs', {}).get('version') for r in results]) rule_ecs = set(rule.metadata.get('ecs_version').copy()) if not ecs_versions & rule_ecs: msg = '{} - {} ecs_versions ({}) not in source data versions ({})'.format( rule.id, rule.name, ', '.join(rule_ecs), ', '.join(ecs_versions)) mismatched_ecs.append(msg) if mismatched_ecs: msg = 'Rules detected with source data from ecs versions not listed within the rule: \n{}'.format( '\n'.join(mismatched_ecs)) warnings.warn(msg)