Skip to content

Commit 18e35f0

Browse files
committed
WIP
1 parent 4b1f50d commit 18e35f0

File tree

6 files changed

+345
-222
lines changed

6 files changed

+345
-222
lines changed

ack_backend/poetry.lock

Lines changed: 226 additions & 218 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ack_backend/src/update_ack_file.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from constants import ACK_HEADERS, SOURCE_BUCKET_NAME, ACK_BUCKET_NAME, FILE_NAME_PROC_LAMBDA_NAME
88
from audit_table import change_audit_table_status_to_processed, get_next_queued_file_details
99
from clients import s3_client, logger, lambda_client
10-
from utils_for_ack_lambda import get_row_count
10+
from utils_for_ack_lambda import get_row_count, debug_print
1111

1212

1313
def create_ack_data(
@@ -76,11 +76,16 @@ def upload_ack_file(
7676
) -> None:
7777
"""Adds the data row to the uploaded ack file"""
7878
for row in ack_data_rows:
79+
print(f"add row {row} to ack file")
7980
data_row_str = [str(item) for item in row.values()]
8081
cleaned_row = "|".join(data_row_str).replace(" |", "|").replace("| ", "|").strip()
8182
accumulated_csv_content.write(cleaned_row + "\n")
83+
84+
8285
csv_file_like_object = BytesIO(accumulated_csv_content.getvalue().encode("utf-8"))
8386
s3_client.upload_fileobj(csv_file_like_object, ACK_BUCKET_NAME, temp_ack_file_key)
87+
88+
debug_print("upload_ack_file...2")
8489

8590
row_count_source = get_row_count(SOURCE_BUCKET_NAME, f"processing/{file_key}")
8691
row_count_destination = get_row_count(ACK_BUCKET_NAME, temp_ack_file_key)
Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,34 @@
11
"""Utils for ack lambda"""
22

33
from clients import s3_client
4-
4+
from tests.utils.values_for_ack_backend_tests import MessageDetails
55

66
def get_row_count(bucket_name: str, file_key: str) -> int:
77
"""
88
Looks in the given bucket and returns the count of the number of lines in the given file.
99
NOTE: Blank lines are not included in the count.
1010
"""
11-
response = s3_client.get_object(Bucket=bucket_name, Key=file_key)
12-
return sum(1 for line in response["Body"].iter_lines() if line.strip())
11+
try:
12+
response = s3_client.get_object(Bucket=bucket_name, Key=file_key)
13+
if "Body" not in response or response["Body"] is None:
14+
print(f"Error getting row count: No Body in response for {bucket_name}/{file_key}")
15+
return 0
16+
ret=sum(1 for line in response["Body"].iter_lines() if line.strip())
17+
print(f"Row count {bucket_name}-{file_key}: {ret}")
18+
except Exception as e:
19+
print(f"Row count {bucket_name}-{file_key}: 0")
20+
return 0
21+
22+
from constants import ACK_HEADERS, SOURCE_BUCKET_NAME, ACK_BUCKET_NAME, FILE_NAME_PROC_LAMBDA_NAME
23+
24+
def debug_print(title, show_source=False):
25+
rsv_ravs = MessageDetails("RSV", "RAVS", "X26")
26+
print(f"Debug rowcount: {title}")
27+
28+
if show_source:
29+
row_count_source = get_row_count(SOURCE_BUCKET_NAME, f"processing/{rsv_ravs.file_key}")
30+
print(f"Row count in source bucket: {row_count_source}")
31+
32+
row_count_destination = get_row_count(ACK_BUCKET_NAME, "TempAck/RSV_Vaccinations_v5_X26_20210730T12000000_BusAck_20211120T12000000.csv")
33+
34+
print(f"Row count in destination bucket: {row_count_destination}")

ack_backend/tests/test_ack_processor.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,12 @@ def setUp(self) -> None:
5151
Key=f"processing/{MOCK_MESSAGE_DETAILS.file_key}",
5252
Body=mock_source_file_with_100_rows.getvalue(),
5353
)
54+
self.logger_info_patcher = patch('logging_decorators.logger.info')
55+
self.mock_logger_info = self.logger_info_patcher.start()
5456

5557
def tearDown(self) -> None:
5658
GenericTearDown(s3_client, firehose_client)
59+
self.mock_logger_info.stop()
5760

5861
@staticmethod
5962
def generate_event(test_messages: list[dict]) -> dict:
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import unittest
2+
from unittest.mock import patch, MagicMock
3+
import audit_table
4+
from errors import UnhandledAuditTableError
5+
6+
class TestAuditTable(unittest.TestCase):
7+
8+
def setUp(self):
9+
self.logger_patcher = patch('audit_table.logger')
10+
self.mock_logger = self.logger_patcher.start()
11+
self.dynamodb_resource_patcher = patch('audit_table.dynamodb_resource')
12+
self.mock_dynamodb_resource = self.dynamodb_resource_patcher.start()
13+
self.dynamodb_client_patcher = patch('audit_table.dynamodb_client')
14+
self.mock_dynamodb_client = self.dynamodb_client_patcher.start()
15+
16+
def tearDown(self):
17+
self.logger_patcher.stop()
18+
self.dynamodb_resource_patcher.stop()
19+
self.dynamodb_client_patcher.stop()
20+
21+
def test_get_next_queued_file_details_returns_oldest(self):
22+
# Arrange
23+
mock_table = MagicMock()
24+
self.mock_dynamodb_resource.Table.return_value = mock_table
25+
mock_table.query.return_value = {
26+
"Items": [
27+
{"timestamp": 2, "foo": "bar"},
28+
{"timestamp": 1, "foo": "baz"},
29+
]
30+
}
31+
# Act
32+
result = audit_table.get_next_queued_file_details("queue1")
33+
# Assert
34+
self.assertEqual(result, {"timestamp": 1, "foo": "baz"})
35+
36+
def test_get_next_queued_file_details_returns_none_if_empty(self):
37+
mock_table = MagicMock()
38+
self.mock_dynamodb_resource.Table.return_value = mock_table
39+
mock_table.query.return_value = {"Items": []}
40+
result = audit_table.get_next_queued_file_details("queue1")
41+
self.assertIsNone(result)
42+
43+
def test_change_audit_table_status_to_processed_success(self):
44+
# Should not raise
45+
self.mock_dynamodb_client.update_item.return_value = {}
46+
audit_table.change_audit_table_status_to_processed("file1", "msg1")
47+
self.mock_dynamodb_client.update_item.assert_called_once()
48+
self.mock_logger.info.assert_called_once()
49+
50+
def test_change_audit_table_status_to_processed_raises(self):
51+
self.mock_dynamodb_client.update_item.side_effect = Exception("fail!")
52+
with self.assertRaises(UnhandledAuditTableError) as ctx:
53+
audit_table.change_audit_table_status_to_processed("file1", "msg1")
54+
self.assertIn("fail!", str(ctx.exception))
55+
self.mock_logger.error.assert_called_once()

ack_backend/tests/test_update_ack_file.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
generate_expected_ack_content,
1919
MOCK_MESSAGE_DETAILS,
2020
)
21+
from constants import ACK_HEADERS, SOURCE_BUCKET_NAME, ACK_BUCKET_NAME, FILE_NAME_PROC_LAMBDA_NAME
22+
from utils_for_ack_lambda import get_row_count, debug_print
2123

2224
with patch.dict("os.environ", MOCK_ENVIRONMENT_DICT):
2325
from update_ack_file import obtain_current_ack_content, create_ack_data, update_ack_file
@@ -42,6 +44,8 @@ def setUp(self) -> None:
4244
Key=f"processing/{MOCK_MESSAGE_DETAILS.file_key}",
4345
Body=mock_source_file_with_100_rows.getvalue(),
4446
)
47+
self.logger_patcher = patch('update_ack_file.logger')
48+
self.mock_logger = self.logger_patcher.start()
4549

4650
def tearDown(self) -> None:
4751
GenericTearDown(s3_client)
@@ -204,5 +208,31 @@ def test_obtain_current_ack_content_file_exists(self):
204208
self.assertEqual(result.getvalue(), existing_content)
205209

206210

211+
def test_update_ack_file_moves_file_to_destination(self):
212+
"""Test that update_ack_file moves the ack file to the correct destination location."""
213+
with patch('update_ack_file.move_file') as mock_move_file:
214+
215+
216+
row_count_source = get_row_count(SOURCE_BUCKET_NAME, f"processing/{MOCK_MESSAGE_DETAILS.file_key}")
217+
row_count_destination = get_row_count(ACK_BUCKET_NAME, "TempAck/RSV_Vaccinations_v5_X26_20210730T12000000_BusAck_20211120T12000000.csv")
218+
219+
debug_print("test...1")
220+
221+
update_ack_file(
222+
file_key=MOCK_MESSAGE_DETAILS.file_key,
223+
message_id=MOCK_MESSAGE_DETAILS.message_id,
224+
supplier_queue=MOCK_MESSAGE_DETAILS.queue_name,
225+
created_at_formatted_string=MOCK_MESSAGE_DETAILS.created_at_formatted_string,
226+
ack_data_rows=[ValidValues.ack_data_success_dict],
227+
)
228+
# Assert that move_file was called with the expected arguments
229+
mock_move_file.assert_called()
230+
called_args_list = [call.args for call in mock_move_file.call_args_list]
231+
# Check that at least one call moved the file to the DESTINATION bucket
232+
self.assertTrue(
233+
any(BucketNames.DESTINATION in args for args in called_args_list[0]),
234+
f"File was not moved to the {BucketNames.DESTINATION} bucket"
235+
)
236+
207237
if __name__ == "__main__":
208238
unittest.main()

0 commit comments

Comments
 (0)