Skip to content

Commit 3c97376

Browse files
committed
More tests with mongomock
- Add a test for report doc insert calls - Add tests for perform_search
1 parent 73147e9 commit 3c97376

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import pathlib
2+
import random
3+
import sys
4+
from unittest import mock
5+
from unittest.mock import patch
6+
7+
import bson
8+
import mongomock
9+
import pymongo
10+
import pytest
11+
12+
from lib.cuckoo.common.config import ConfigMeta
13+
from modules.reporting.mongodb_constants import CALLS_COLL
14+
15+
TEST_DB_NAME = "cuckoo_test"
16+
17+
18+
@pytest.fixture
19+
def mongodb_enabled(custom_conf_path: pathlib.Path):
20+
"""Enable mongodb.
21+
22+
Use sys.modules.pop to ensure target gets imported
23+
as if for the first time.
24+
"""
25+
with open(custom_conf_path / "reporting.conf", "wt") as fil:
26+
print(f"[mongodb]\nenabled = yes\ndb = {TEST_DB_NAME}", file=fil)
27+
ConfigMeta.refresh()
28+
sys.modules.pop("modules.reporting.report_doc", None)
29+
yield
30+
# Pop the module again, to reset the state for other tests.
31+
sys.modules.pop("modules.reporting.report_doc", None)
32+
33+
34+
@pytest.fixture
35+
def mongodb_mock_client(request):
36+
with mongomock.patch(servers=(("127.0.0.1", 27017),)):
37+
client = pymongo.MongoClient(host=f"mongodb://127.0.0.1/{TEST_DB_NAME}")
38+
request.instance.mongo_client = client
39+
with mock.patch("dev_utils.mongodb.conn", new=client):
40+
yield
41+
42+
43+
@pytest.mark.usefixtures("mongodb_enabled", "db", "mongodb_mock_client")
44+
class TestReportDoc:
45+
def test_insert_calls_mongodb(self):
46+
"""Test the insert_calls function."""
47+
from modules.reporting.report_doc import insert_calls
48+
49+
pid0, pid1 = random.randint(1, 1000), random.randint(1, 1000)
50+
report = {
51+
"behavior": {
52+
"processes": [
53+
{
54+
"process_id": pid0,
55+
"calls": [
56+
{
57+
"timestamp": "2025-01-01 01:01:01",
58+
},
59+
],
60+
},
61+
{
62+
"process_id": pid1,
63+
"calls": [
64+
{
65+
"timestamp": "2025-02-02 02:02:02",
66+
},
67+
],
68+
},
69+
]
70+
}
71+
}
72+
with patch("modules.reporting.report_doc.CHUNK_CALL_SIZE", new=1):
73+
result = insert_calls(report, mongodb=True)
74+
assert isinstance(result, list)
75+
assert result[0]["process_id"] == pid0
76+
assert result[1]["process_id"] == pid1
77+
expected_calls = [
78+
result[0]["calls"][0],
79+
result[1]["calls"][0],
80+
]
81+
collection = self.mongo_client[TEST_DB_NAME][CALLS_COLL]
82+
for item in expected_calls:
83+
assert isinstance(item, bson.objectid.ObjectId)
84+
obj = collection.find_one({"_id": item})
85+
assert obj is not None

tests/test_web_utils.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,39 @@
22
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
33
# See the file 'docs/LICENSE' for copying permission.
44

5+
import pathlib
6+
import random
7+
import sys
58
import tempfile
9+
from unittest import mock
610

711
import httpretty
12+
import mongomock
13+
import pymongo
814
import pytest
915

16+
from lib.cuckoo.common.config import ConfigMeta
1017
from lib.cuckoo.common.path_utils import path_delete, path_write_file
1118
from lib.cuckoo.common.web_utils import _download_file, force_int, get_file_content, parse_request_arguments
19+
from modules.reporting.mongodb_constants import ANALYSIS_COLL
20+
21+
TEST_DB_NAME = "cuckoo_test_db"
22+
23+
24+
@pytest.fixture
25+
def mongodb_enabled(custom_conf_path: pathlib.Path):
26+
with open(custom_conf_path / "reporting.conf", "wt") as fil:
27+
print(f"[mongodb]\nenabled = yes\ndb = {TEST_DB_NAME}", file=fil)
28+
ConfigMeta.refresh()
29+
yield
30+
31+
32+
@pytest.fixture
33+
def mongodb_mock_client():
34+
with mongomock.patch(servers=(("127.0.0.1", 27017),)):
35+
client = pymongo.MongoClient(host=f"mongodb://127.0.0.1/{TEST_DB_NAME}")
36+
with mock.patch("dev_utils.mongodb.conn", new=client):
37+
yield client
1238

1339

1440
@pytest.fixture
@@ -90,3 +116,56 @@ def test_parse_request_arguments(mock_request):
90116
def test_force_int():
91117
assert force_int(value="1") == 1
92118
assert force_int(value="$") == 0
119+
120+
121+
def test_perform_search_invalid_ttp():
122+
sys.modules.pop("lib.cuckoo.common.web_utils", None)
123+
from lib.cuckoo.common.web_utils import perform_search
124+
125+
with pytest.raises(ValueError) as exc:
126+
_ = perform_search(term="ttp", value="SPOONS")
127+
assert "Invalid TTP" in str(exc)
128+
129+
130+
def test_perform_search_not_in_search_term_map():
131+
sys.modules.pop("lib.cuckoo.common.web_utils", None)
132+
from lib.cuckoo.common.web_utils import perform_search, search_term_map
133+
134+
term = "Unexpected"
135+
assert term not in search_term_map
136+
actual_result = perform_search(term=term, value="not in search term map")
137+
assert actual_result is None
138+
139+
140+
def test_perform_search_invalid_int_value():
141+
sys.modules.pop("lib.cuckoo.common.web_utils", None)
142+
from lib.cuckoo.common.web_utils import normalized_int_terms, perform_search
143+
144+
term = random.choice(normalized_int_terms)
145+
non_integer_value = "not an integer"
146+
with pytest.raises(ValueError) as exc:
147+
_ = perform_search(term=term, value=non_integer_value)
148+
assert non_integer_value in str(exc)
149+
150+
151+
@pytest.mark.usefixtures("mongodb_enabled")
152+
def test_perform_search_mongo(mongodb_mock_client):
153+
sys.modules.pop("lib.cuckoo.common.web_utils", None)
154+
from lib.cuckoo.common.web_utils import perform_search, search_term_map
155+
156+
term = "tlp"
157+
value = "red"
158+
assert term in search_term_map
159+
assert search_term_map[term] == "info.tlp"
160+
id = random.randint(1, 1000)
161+
analysis = {
162+
"info": {
163+
"id": id,
164+
term: value,
165+
}
166+
}
167+
mongodb_mock_client[TEST_DB_NAME][ANALYSIS_COLL].insert_one(analysis)
168+
result = perform_search(term=term, value=value)
169+
assert len(result) == 1
170+
assert result[0]["info"][term] == value
171+
assert result[0]["info"]["id"] == id

0 commit comments

Comments
 (0)