test: add missing analyzer unit tests and datafinder date validation#3783
test: add missing analyzer unit tests and datafinder date validation#3783SNO7E-G wants to merge 5 commits into
Conversation
|
/gemini review |
27321bc to
4c92dfd
Compare
|
@jaegeral |
jkppr
left a comment
There was a problem hiding this comment.
Thanks for the contribution. I have some comments below.
| @mock.patch("timesketch.lib.analyzers.interface.OpenSearchDataStore", MockDataStore) | ||
| def test_analyzer(self): | ||
| """Test analyzer.""" | ||
| # TODO: Write actual tests here. |
There was a problem hiding this comment.
The original TODO was sitting under a placeholder test_analyzer(self). The goal of that TODO was to test the analyzer's main run() method (which queries the datastore, groups events, and creates the Timesketch view), rather than just the is_suspicious() helper.
Currently, the run() method is completely untested. Would you be open to helping us write an integration test for it? It would look something like this:
- Populating the
MockDataStorewith a couple of mock events (one withattribute_type: 16and one with48). - Running
analyzer.run(). - Verifying that the events are updated/committed and the
NtfsTimestompview is added.
| self.assertFalse(analyzer.is_suspicious(file_info)) | ||
|
|
||
| @mock.patch("timesketch.lib.analyzers.interface.OpenSearchDataStore", MockDataStore) | ||
| def test_is_suspicious_within_threshold(self): |
There was a problem hiding this comment.
Isn't this already covered by the existing test_is_suspicious test? (Case 1, 4, and 5 - The existing tests already thoroughly prove that any analyzer.threshold (which includes analyzer.threshold - 1) is correctly ignored.)
| self.assertIsNone(fn_event.source.get("time_delta")) | ||
|
|
||
| @mock.patch("timesketch.lib.analyzers.interface.OpenSearchDataStore", MockDataStore) | ||
| def test_is_suspicious_timestomped(self): |
There was a problem hiding this comment.
Same here, this is also already covered by the test_is_suspicious if I'm not mistaken. (case 2 - It tests the exact same success path and attribute-setting behavior, just with different numbers.)
| self.assertEqual(si_event.source.get("time_deltas"), [large_diff]) | ||
|
|
||
| @mock.patch("timesketch.lib.analyzers.interface.OpenSearchDataStore", MockDataStore) | ||
| def test_is_suspicious_mixed_file_names(self): |
There was a problem hiding this comment.
Same here, this seems also to be already covered by test_is_suspicious. (case 3 & 4 - This is the exact same "mixed list with early exit" scenario that the new test is trying to cover.)
| } | ||
|
|
||
| result = analyzer.run() | ||
| self.assertIn("2 domains discovered", result) |
There was a problem hiding this comment.
Great job setting up MockDataStore and running analyzer.run().
Currently, the assertions only check the high-level summary string returned by run() (e.g., "2 domains discovered"). To ensure that the analyzer is actually modifying the events in the datastore as expected (and to prevent future code changes from silently breaking this), we should assert the actual event tags and attributes too.
| logger = logging.getLogger("timesketch.data_finder") | ||
|
|
||
|
|
||
| def _is_valid_iso_date(date_string): |
There was a problem hiding this comment.
That should work well. Would you mind adding a timesketch/lib/datafinder_test.py file with some unit tests that verify set_start_date() and set_and_date() accept valid ISO dates and correctly log warnings for invalid dates?
Hi Team 👋
This PR cleans up four
TODOcomments that have been sitting in the codebase fora while — all of them asking for test coverage or input validation that was never
implemented. Nothing drastic, just filling in the gaps.
Closes #3782
What's been bothering me (and hopefully you too)
The NTFS timestomp test file had this as its only test:
self.assertEqual(True, True)
The domain test file was 22 lines and only checked that the class could be
instantiated. The feature extraction test file had a
TODOcomment and nothingelse. And
DataFinderwas silently accepting any string as a date withoutever checking if it was actually ISO 8601.
What this PR does
ntfs_timestomp_test.py— 5 new behavioral tests foris_suspicious():std_info_event→ returns Falsefile_names→ returns Falsetime_delta/time_deltasset correctlydomain_test.py— 4 new MockDataStore-backed behavioral tests:"No domains to analyze."urlfield (nodomain) → correct domain extraction.cloudfront.net) → reported in CDN network countfeature_extraction_test.py— 3 new tests forFeatureExtractionSketchPlugin:plugin_name,feature_name,feature_configplugin_name→ returns"Feature extraction plugin name is empty"cleanlyValueErrormessagedatafinder.py— ISO 8601 date validation:_is_valid_iso_date()helper usingdatetime.fromisoformat()set_start_date()andset_end_date()now log a warning if the input isn't validTODOcommentsChecks
Closing issues
Closes Resolve inline TODOs: missing analyzer tests and datafinder date validation #3782