Skip to content

Commit 77d05b9

Browse files
committed
[CI] Add unit tests for amend_pull_request_data.py
1 parent a6c40d8 commit 77d05b9

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import datetime
2+
from typing import Any
3+
import unittest
4+
import unittest.mock
5+
6+
import amend_pull_request_data
7+
import operational_metrics_lib
8+
9+
10+
class TestAmendPullRequestData(unittest.TestCase):
11+
12+
def _create_mock_bq_row(
13+
self, pull_request_number: int
14+
) -> unittest.mock.MagicMock:
15+
"""Creates a mock row for BigQuery."""
16+
mock_row = unittest.mock.MagicMock()
17+
mock_row.pull_request_number = pull_request_number
18+
return mock_row
19+
20+
def _create_mock_graphql_response(
21+
self,
22+
nodes: list[dict[str, Any]],
23+
has_next_page: bool = False,
24+
end_cursor: str | None = None,
25+
) -> unittest.mock.MagicMock:
26+
"""Creates a mock response for the GitHub GraphQL API."""
27+
mock_response = unittest.mock.MagicMock()
28+
mock_response.json.return_value = {
29+
"data": {
30+
"search": {
31+
"nodes": nodes,
32+
"pageInfo": {
33+
"hasNextPage": has_next_page,
34+
"endCursor": end_cursor,
35+
},
36+
}
37+
}
38+
}
39+
return mock_response
40+
41+
@unittest.mock.patch.object(
42+
operational_metrics_lib, "query_github_graphql_api"
43+
)
44+
def test_fetch_open_pull_requests_from_github(
45+
self, mock_query_github_graphql_api
46+
):
47+
"""Test fetching open pull requests from GitHub, with pagination."""
48+
mock_response_1 = self._create_mock_graphql_response(
49+
nodes=[{"number": 1234}], has_next_page=True, end_cursor="cursor1"
50+
)
51+
mock_response_2 = self._create_mock_graphql_response(
52+
nodes=[{"number": 5678}], has_next_page=False, end_cursor=None
53+
)
54+
mock_query_github_graphql_api.side_effect = [
55+
mock_response_1,
56+
mock_response_2,
57+
]
58+
59+
cutoff_timestamp = datetime.datetime.now() - datetime.timedelta(hours=2)
60+
pull_requests = (
61+
amend_pull_request_data.fetch_open_pull_requests_from_github(
62+
github_token="dummy_token",
63+
cutoff_timestamp=cutoff_timestamp,
64+
)
65+
)
66+
self.assertEqual(pull_requests, [{"number": 1234}, {"number": 5678}])
67+
self.assertEqual(mock_query_github_graphql_api.call_count, 2)
68+
69+
def test_mark_stale_pull_request_data_in_bigquery(self):
70+
"""Test marking stale pull request data in BigQuery."""
71+
mock_bq_client = unittest.mock.MagicMock()
72+
mock_bq_query_job = unittest.mock.MagicMock()
73+
mock_bq_client.query.return_value = mock_bq_query_job
74+
75+
amend_pull_request_data.mark_stale_pull_request_data_in_bigquery(
76+
mock_bq_client,
77+
cutoff_age_days=14,
78+
)
79+
job_config = mock_bq_client.query.call_args.kwargs["job_config"]
80+
query_parameters = job_config.query_parameters[0]
81+
82+
mock_bq_client.query.assert_called_once()
83+
executed_query = mock_bq_client.query.call_args.args[0]
84+
self.assertIn("SET is_stale_data = true", executed_query)
85+
self.assertRegex(executed_query, r"WHERE\s+pull_request_state = 'OPEN'")
86+
self.assertEqual(query_parameters.name, "cutoff_age_days")
87+
self.assertEqual(query_parameters.value, 14)
88+
89+
def test_get_open_pull_requests_from_bigquery(self):
90+
"""Test getting open pull requests from BigQuery."""
91+
mock_bq_client = unittest.mock.MagicMock()
92+
mock_bq_query_job = unittest.mock.MagicMock()
93+
mock_bq_query_job.result.return_value = [
94+
self._create_mock_bq_row(1234),
95+
self._create_mock_bq_row(5678),
96+
]
97+
mock_bq_client.query.return_value = mock_bq_query_job
98+
99+
result = amend_pull_request_data.get_open_pull_requests_from_bigquery(
100+
mock_bq_client
101+
)
102+
mock_bq_client.query.assert_called_once()
103+
executed_query = mock_bq_client.query.call_args.args[0]
104+
self.assertIn("SELECT pull_request_number", executed_query)
105+
self.assertRegex(executed_query, r"WHERE\s+pull_request_state = 'OPEN'")
106+
self.assertEqual(result, [1234, 5678])
107+
108+
@unittest.mock.patch.object(
109+
operational_metrics_lib, "fetch_repository_data_from_github"
110+
)
111+
def test_query_pull_request_data_from_github(
112+
self, mock_fetch_repository_data_from_github
113+
):
114+
"""Test querying pull request data from GitHub."""
115+
mock_fetch_repository_data_from_github.return_value = {
116+
"pr_1234": {"number": 1234},
117+
"pr_5678": {"number": 5678},
118+
}
119+
120+
result = amend_pull_request_data.query_pull_request_data_from_github(
121+
pull_request_numbers=[1234, 5678],
122+
github_token="dummy_token",
123+
)
124+
call_kwargs = mock_fetch_repository_data_from_github.call_args.kwargs
125+
126+
self.assertEqual(mock_fetch_repository_data_from_github.call_count, 1)
127+
self.assertEqual(len(call_kwargs["subqueries"]), 2)
128+
self.assertEqual(result, [{"number": 1234}, {"number": 5678}])
129+
130+
def test_get_unapproved_pull_requests_from_bigquery(self):
131+
"""Test getting unapproved pull requests from BigQuery."""
132+
mock_bq_client = unittest.mock.MagicMock()
133+
mock_bq_query_job = unittest.mock.MagicMock()
134+
mock_bq_query_job.result.return_value = [
135+
self._create_mock_bq_row(1234),
136+
self._create_mock_bq_row(5678),
137+
]
138+
mock_bq_client.query.return_value = mock_bq_query_job
139+
140+
result = amend_pull_request_data.get_unapproved_pull_requests_from_bigquery(
141+
mock_bq_client,
142+
cutoff_age_days=14,
143+
)
144+
job_config = mock_bq_client.query.call_args.kwargs["job_config"]
145+
query_parameters = job_config.query_parameters[0]
146+
147+
mock_bq_client.query.assert_called_once()
148+
executed_query = mock_bq_client.query.call_args.args[0]
149+
self.assertRegex(executed_query, r"SELECT\s+(.+.)?pull_request_number")
150+
self.assertRegex(
151+
executed_query, r"WHERE\s+(.+.)?pull_request_state = 'MERGED'"
152+
)
153+
self.assertEqual(query_parameters.name, "cutoff_age_days")
154+
self.assertEqual(query_parameters.value, 14)
155+
self.assertEqual(result, [1234, 5678])
156+
157+
@unittest.mock.patch.object(
158+
operational_metrics_lib, "parse_pull_request_data"
159+
)
160+
@unittest.mock.patch.object(operational_metrics_lib, "parse_review_data")
161+
@unittest.mock.patch.object(operational_metrics_lib, "upload_to_bigquery")
162+
def test_upload_github_data_to_bigquery(
163+
self,
164+
mock_upload_to_bigquery,
165+
mock_parse_review_data,
166+
mock_parse_pull_request_data,
167+
):
168+
"""Test uploading GitHub data to BigQuery."""
169+
mock_bq_client = unittest.mock.MagicMock()
170+
mock_parse_pull_request_data.return_value = "parsed_pull_request_data"
171+
mock_parse_review_data.return_value = ["parsed_review_data"]
172+
173+
amend_pull_request_data.upload_github_data_to_bigquery(
174+
mock_bq_client,
175+
pull_request_data=[{"number": 1234}],
176+
)
177+
178+
mock_parse_pull_request_data.assert_called_once_with({"number": 1234})
179+
mock_parse_review_data.assert_called_once_with({"number": 1234})
180+
mock_upload_to_bigquery.assert_any_call(
181+
mock_bq_client,
182+
amend_pull_request_data.OPERATIONAL_METRICS_DATASET,
183+
amend_pull_request_data.LLVM_PULL_REQUESTS_TABLE,
184+
["parsed_pull_request_data"],
185+
"pull_request_number",
186+
)
187+
mock_upload_to_bigquery.assert_any_call(
188+
mock_bq_client,
189+
amend_pull_request_data.OPERATIONAL_METRICS_DATASET,
190+
amend_pull_request_data.LLVM_REVIEWS_TABLE,
191+
["parsed_review_data"],
192+
"review_id",
193+
)
194+
195+
196+
if __name__ == "__main__":
197+
unittest.main()

0 commit comments

Comments
 (0)