Skip to content

Commit 912255c

Browse files
test(queries): add unit tests for query modules (#1609)
* test(queries): add unit tests for query modules - Add tests for build, checkout, issues and test query modules Part of #1498 * test(queries): add unit tests for remaining query modules - Add tests for hardware, notifications and tree modules Closes #1498
1 parent e8013a5 commit 912255c

File tree

8 files changed

+1274
-0
lines changed

8 files changed

+1274
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from unittest.mock import patch
2+
3+
from kernelCI_app.queries.build import get_build_details, get_build_tests
4+
5+
from kernelCI_app.tests.unitTests.queries.conftest import (
6+
setup_mock_filter_values_queryset,
7+
setup_mock_query_builder,
8+
)
9+
10+
11+
class TestGetBuildDetails:
12+
@patch("kernelCI_app.queries.build.Query")
13+
def test_get_build_details_success(self, mock_query_class):
14+
expected_result = [{"id": "build", "checkout_id": "checkout"}]
15+
mock_query = setup_mock_query_builder(mock_query_class, expected_result)
16+
17+
result = get_build_details("build")
18+
19+
assert result == expected_result
20+
mock_query.where.assert_called_once_with(**{"builds.id__eq": "build"})
21+
22+
@patch("kernelCI_app.queries.build.Query")
23+
def test_get_build_details_empty_result(self, mock_query_class):
24+
setup_mock_query_builder(mock_query_class, [])
25+
26+
result = get_build_details("build")
27+
28+
assert result == []
29+
30+
31+
class TestGetBuildTests:
32+
@patch("kernelCI_app.queries.build.Tests")
33+
def test_get_build_tests_success(self, mock_tests_model):
34+
expected_result = [{"id": "test", "status": "PASS"}]
35+
setup_mock_filter_values_queryset(mock_tests_model, expected_result)
36+
37+
result = get_build_tests("build")
38+
39+
assert result == expected_result
40+
mock_tests_model.objects.filter.assert_called_once_with(build_id="build")
41+
42+
@patch("kernelCI_app.queries.build.Tests")
43+
def test_get_build_tests_empty_result(self, mock_tests_model):
44+
setup_mock_filter_values_queryset(mock_tests_model, [])
45+
46+
result = get_build_tests("build")
47+
48+
assert result == []
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from unittest.mock import patch
2+
3+
from kernelCI_app.queries.checkout import get_origins
4+
5+
from kernelCI_app.tests.unitTests.queries.conftest import setup_mock_cursor
6+
7+
8+
class TestGetOrigins:
9+
@patch("kernelCI_app.queries.checkout.get_query_cache")
10+
def test_get_origins_from_cache(self, mock_get_cache):
11+
cached_data = [{"origin": "maestro", "table": "checkouts"}]
12+
mock_get_cache.return_value = cached_data
13+
14+
result = get_origins(7)
15+
16+
assert result == cached_data
17+
18+
@patch("kernelCI_app.queries.checkout.get_query_cache")
19+
@patch("kernelCI_app.queries.checkout.set_query_cache")
20+
@patch("kernelCI_app.queries.checkout.dict_fetchall")
21+
@patch("kernelCI_app.queries.checkout.connection")
22+
def test_get_origins_from_database(
23+
self, mock_connection, mock_dict_fetchall, mock_set_cache, mock_get_cache
24+
):
25+
mock_get_cache.return_value = None
26+
expected_result = [{"origin": "maestro", "table": "checkouts"}]
27+
mock_dict_fetchall.return_value = expected_result
28+
29+
mock_cursor = setup_mock_cursor(mock_connection)
30+
31+
result = get_origins(7)
32+
33+
assert result == expected_result
34+
mock_cursor.execute.assert_called_once()
35+
mock_set_cache.assert_called_once()
36+
37+
@patch("kernelCI_app.queries.checkout.get_query_cache")
38+
@patch("kernelCI_app.queries.checkout.set_query_cache")
39+
@patch("kernelCI_app.queries.checkout.dict_fetchall")
40+
@patch("kernelCI_app.queries.checkout.connection")
41+
def test_get_origins_empty_result_does_not_cache(
42+
self, mock_connection, mock_dict_fetchall, mock_set_cache, mock_get_cache
43+
):
44+
mock_get_cache.return_value = None
45+
mock_dict_fetchall.return_value = []
46+
47+
setup_mock_cursor(mock_connection)
48+
49+
result = get_origins(7)
50+
51+
assert result == []
52+
mock_set_cache.assert_not_called()
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from unittest.mock import MagicMock, Mock
2+
3+
from kernelCI_app.typeModels.hardwareDetails import Tree
4+
5+
6+
def setup_mock_cursor(mock_connection):
7+
mock_cursor = MagicMock()
8+
mock_connection.cursor.return_value.__enter__.return_value = mock_cursor
9+
return mock_cursor
10+
11+
12+
def setup_mock_queryset(mock_model, return_value):
13+
mock_queryset = Mock()
14+
mock_queryset.values.return_value = mock_queryset
15+
mock_queryset.filter.return_value = mock_queryset
16+
mock_queryset.order_by.return_value = mock_queryset
17+
mock_queryset.first.return_value = return_value
18+
mock_model.objects.values.return_value = mock_queryset
19+
return mock_queryset
20+
21+
22+
def setup_mock_test_queryset(mock_tests_model):
23+
mock_queryset = Mock()
24+
mock_queryset.values.return_value = mock_queryset
25+
mock_queryset.filter.return_value = mock_queryset
26+
mock_queryset.order_by.return_value = mock_queryset
27+
mock_sliced = Mock()
28+
mock_sliced.__iter__ = Mock(return_value=iter([]))
29+
mock_queryset.__getitem__ = Mock(return_value=mock_sliced)
30+
mock_tests_model.objects.filter.return_value = mock_queryset
31+
return mock_queryset
32+
33+
34+
TEST_TREE = Tree(
35+
index="0",
36+
tree_name="mainline",
37+
origin="maestro",
38+
git_repository_branch="master",
39+
git_repository_url="https://my_url.com",
40+
head_git_commit_name="v6.1",
41+
head_git_commit_hash="abc123",
42+
head_git_commit_tag=None,
43+
selected_commit_status=None,
44+
is_selected=None,
45+
)
46+
47+
48+
def setup_mock_query_builder(mock_query_class, return_value):
49+
mock_query = Mock()
50+
mock_query.from_table.return_value = mock_query
51+
mock_query.join.return_value = mock_query
52+
mock_query.where.return_value = mock_query
53+
mock_query.select.return_value = return_value
54+
mock_query_class.return_value = mock_query
55+
return mock_query
56+
57+
58+
def setup_mock_filter_values_queryset(mock_model, return_value):
59+
mock_filter_queryset = Mock()
60+
mock_filter_queryset.annotate.return_value = mock_filter_queryset
61+
mock_filter_queryset.values.return_value = return_value
62+
mock_model.objects.filter.return_value = mock_filter_queryset
63+
return mock_filter_queryset
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
from datetime import datetime
2+
from unittest.mock import patch
3+
4+
from kernelCI_app.queries.hardware import (
5+
get_hardware_listing_data,
6+
get_hardware_details_data,
7+
get_hardware_trees_data,
8+
get_hardware_commit_history,
9+
_generate_query_params,
10+
query_records,
11+
)
12+
from kernelCI_app.typeModels.hardwareDetails import CommitHead
13+
14+
from kernelCI_app.tests.unitTests.queries.conftest import (
15+
TEST_TREE,
16+
setup_mock_cursor,
17+
)
18+
19+
START_DATE = datetime(2025, 11, 11)
20+
END_DATE = datetime(2025, 11, 12)
21+
22+
23+
class TestGetHardwareListingData:
24+
@patch("kernelCI_app.queries.hardware.connection")
25+
def test_get_hardware_listing_data_success(self, mock_connection):
26+
expected_result = [
27+
("platform", ["compatible"], 10, 5, 0, 0, 0, 0, 0, 20, 10, 0, 0, 0, 0, 0)
28+
]
29+
mock_cursor = setup_mock_cursor(mock_connection)
30+
mock_cursor.fetchall.return_value = expected_result
31+
32+
result = get_hardware_listing_data(
33+
start_date=datetime(2025, 11, 10),
34+
end_date=datetime(2025, 11, 12),
35+
origin="maestro",
36+
)
37+
38+
assert result == expected_result
39+
mock_cursor.execute.assert_called_once()
40+
41+
42+
class TestGetHardwareDetailsData:
43+
@patch("kernelCI_app.queries.hardware.get_query_cache")
44+
def test_get_hardware_details_data_from_cache(self, mock_get_cache):
45+
cached_data = [{"id": "test", "status": "PASS"}]
46+
mock_get_cache.return_value = cached_data
47+
48+
result = get_hardware_details_data(
49+
hardware_id="hardware",
50+
origin="maestro",
51+
trees_with_selected_commits=[TEST_TREE],
52+
start_datetime=START_DATE,
53+
end_datetime=END_DATE,
54+
)
55+
56+
assert result == cached_data
57+
58+
@patch("kernelCI_app.queries.hardware.get_query_cache")
59+
@patch("kernelCI_app.queries.hardware.set_query_cache")
60+
@patch("kernelCI_app.queries.hardware.query_records")
61+
def test_get_hardware_details_data_from_database(
62+
self, mock_query_records, mock_set_cache, mock_get_cache
63+
):
64+
expected_data = [{"id": "test", "status": "PASS"}]
65+
mock_get_cache.return_value = None
66+
mock_query_records.return_value = expected_data
67+
68+
result = get_hardware_details_data(
69+
hardware_id="hardware",
70+
origin="maestro",
71+
trees_with_selected_commits=[TEST_TREE],
72+
start_datetime=START_DATE,
73+
end_datetime=END_DATE,
74+
)
75+
76+
assert result == expected_data
77+
mock_query_records.assert_called_once()
78+
mock_set_cache.assert_called_once()
79+
80+
81+
class TestGetHardwareTreesData:
82+
@patch("kernelCI_app.queries.hardware.get_query_cache")
83+
def test_get_hardware_trees_data_from_cache(self, mock_get_cache):
84+
cached_trees = [TEST_TREE]
85+
mock_get_cache.return_value = cached_trees
86+
87+
result = get_hardware_trees_data(
88+
hardware_id="hardware",
89+
origin="maestro",
90+
start_datetime=START_DATE,
91+
end_datetime=END_DATE,
92+
)
93+
94+
assert result == cached_trees
95+
96+
@patch("kernelCI_app.queries.hardware.get_query_cache")
97+
@patch("kernelCI_app.queries.hardware.set_query_cache")
98+
@patch("kernelCI_app.queries.hardware.dict_fetchall")
99+
@patch("kernelCI_app.queries.hardware.connection")
100+
def test_get_hardware_trees_data_from_database(
101+
self, mock_connection, mock_dict_fetchall, mock_set_cache, mock_get_cache
102+
):
103+
tree_records = [
104+
{
105+
"tree_name": "mainline",
106+
"origin": "maestro",
107+
"git_repository_branch": "master",
108+
"git_repository_url": "https://my_url.com",
109+
"git_commit_name": "v6.1",
110+
"git_commit_hash": "abc123",
111+
"git_commit_tags": None,
112+
}
113+
]
114+
mock_get_cache.return_value = None
115+
mock_dict_fetchall.return_value = tree_records
116+
setup_mock_cursor(mock_connection)
117+
118+
result = get_hardware_trees_data(
119+
hardware_id="hardware",
120+
origin="maestro",
121+
start_datetime=START_DATE,
122+
end_datetime=END_DATE,
123+
)
124+
125+
assert len(result) == 1
126+
assert result[0].tree_name == "mainline"
127+
mock_set_cache.assert_called_once()
128+
129+
130+
class TestGenerateQueryParams:
131+
def test_generate_query_params_single_commit(self):
132+
commit_heads = [
133+
CommitHead(
134+
treeName="mainline",
135+
repositoryUrl="https://my_url.com",
136+
branch="master",
137+
commitHash="abc123",
138+
)
139+
]
140+
141+
result = _generate_query_params(commit_heads)
142+
143+
assert "tuple_str" in result
144+
assert "query_params" in result
145+
assert result["query_params"]["tree_name0"] == "mainline"
146+
assert result["query_params"]["git_commit_hash0"] == "abc123"
147+
148+
def test_generate_query_params_multiple_commits(self):
149+
commit_heads = [
150+
CommitHead(
151+
treeName="mainline",
152+
repositoryUrl="https://my_url.com",
153+
branch="master",
154+
commitHash="abc123",
155+
),
156+
CommitHead(
157+
treeName="next",
158+
repositoryUrl="https://my_url.com",
159+
branch="master",
160+
commitHash="def456",
161+
),
162+
]
163+
164+
result = _generate_query_params(commit_heads)
165+
166+
assert len(result["query_params"]) == 8
167+
assert "tree_name0" in result["query_params"]
168+
assert "tree_name1" in result["query_params"]
169+
170+
171+
class TestGetHardwareCommitHistory:
172+
@patch("kernelCI_app.queries.hardware.connection")
173+
def test_get_hardware_commit_history_success(self, mock_connection):
174+
expected_result = [("abc123", "v6.1", None, datetime(2025, 11, 12))]
175+
mock_cursor = setup_mock_cursor(mock_connection)
176+
mock_cursor.fetchall.return_value = expected_result
177+
178+
result = get_hardware_commit_history(
179+
origin="maestro",
180+
start_date=datetime(2025, 11, 11),
181+
end_date=datetime(2025, 11, 12),
182+
commit_heads=[
183+
CommitHead(
184+
treeName="mainline",
185+
repositoryUrl="https://my_url.com",
186+
branch="master",
187+
commitHash="abc123",
188+
)
189+
],
190+
)
191+
192+
assert result == expected_result
193+
194+
@patch("kernelCI_app.queries.hardware.connection")
195+
def test_get_hardware_commit_history_empty_commits(self, mock_connection):
196+
result = get_hardware_commit_history(
197+
origin="maestro",
198+
start_date=datetime(2025, 11, 11),
199+
end_date=datetime(2025, 11, 12),
200+
commit_heads=[],
201+
)
202+
203+
assert result is None
204+
mock_connection.cursor.assert_not_called()
205+
206+
207+
class TestQueryRecords:
208+
@patch("kernelCI_app.queries.hardware.dict_fetchall")
209+
@patch("kernelCI_app.queries.hardware.connection")
210+
def test_query_records_success(self, mock_connection, mock_dict_fetchall):
211+
expected_result = [{"id": "test", "status": "PASS"}]
212+
mock_dict_fetchall.return_value = expected_result
213+
mock_cursor = setup_mock_cursor(mock_connection)
214+
215+
result = query_records(
216+
hardware_id="hardware",
217+
origin="maestro",
218+
trees=[TEST_TREE],
219+
start_date=START_DATE,
220+
end_date=END_DATE,
221+
)
222+
223+
assert result == expected_result
224+
mock_cursor.execute.assert_called_once()

0 commit comments

Comments
 (0)