Skip to content

Commit 2479aca

Browse files
committed
Fix test and SDK compatibility issues
- Fix StepConfig import from aws_durable_execution_sdk_python.config - Use RetryPresets.none() instead of non-existent max_attempts parameter - Set EVENTS_TABLE_NAME env var before module imports in tests
1 parent fa4157d commit 2479aca

3 files changed

Lines changed: 154 additions & 146 deletions

File tree

lambda-durable-webhook-sam-python/src/webhook_processor.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import logging
99
from datetime import datetime
1010
from typing import Dict, Any
11-
from aws_durable_execution_sdk_python import DurableContext, StepConfig, durable_execution
11+
from aws_durable_execution_sdk_python import DurableContext, durable_execution
12+
from aws_durable_execution_sdk_python.config import StepConfig
13+
from aws_durable_execution_sdk_python.retries import RetryPresets
1214
import boto3
1315

1416
logger = logging.getLogger()
@@ -71,7 +73,7 @@ def validate_webhook(_) -> Dict[str, Any]:
7173
validation_result = context.step(
7274
validate_webhook,
7375
name='validate-webhook',
74-
config=StepConfig(max_attempts=1)
76+
config=StepConfig(retry_strategy=RetryPresets.none())
7577
)
7678

7779
# Step 2: Process
Lines changed: 147 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,147 @@
1-
"""
2-
Unit tests for status query function
3-
"""
4-
import json
5-
import os
6-
import sys
7-
import unittest
8-
from unittest.mock import Mock, patch
9-
10-
# Add src to path
11-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
12-
13-
from status_query import lambda_handler
14-
15-
16-
class TestStatusQuery(unittest.TestCase):
17-
"""Test cases for status query function"""
18-
19-
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
20-
@patch('status_query.table')
21-
def test_query_existing_token(self, mock_table):
22-
"""Test querying status for existing execution token"""
23-
execution_token = 'test-token-123'
24-
25-
# Mock DynamoDB response
26-
mock_table.get_item.return_value = {
27-
'Item': {
28-
'executionToken': execution_token,
29-
'status': 'completed',
30-
'currentStep': 'finalize',
31-
'createdAt': '2025-02-01T10:00:00.000Z',
32-
'lastUpdated': '2025-02-01T10:00:05.000Z',
33-
'webhookPayload': {
34-
'type': 'order.created',
35-
'source': 'test-system',
36-
'orderId': 'ORD-123'
37-
}
38-
}
39-
}
40-
41-
event = {
42-
'pathParameters': {'executionToken': execution_token}
43-
}
44-
45-
response = lambda_handler(event, None)
46-
47-
self.assertEqual(response['statusCode'], 200)
48-
body = json.loads(response['body'])
49-
self.assertEqual(body['executionToken'], execution_token)
50-
self.assertEqual(body['status'], 'completed')
51-
self.assertEqual(body['currentStep'], 'finalize')
52-
self.assertIn('webhookSummary', body)
53-
54-
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
55-
@patch('status_query.table')
56-
def test_query_nonexistent_token(self, mock_table):
57-
"""Test querying status for non-existent execution token"""
58-
execution_token = 'nonexistent-token'
59-
60-
# Mock DynamoDB response with no item
61-
mock_table.get_item.return_value = {}
62-
63-
event = {
64-
'pathParameters': {'executionToken': execution_token}
65-
}
66-
67-
response = lambda_handler(event, None)
68-
69-
self.assertEqual(response['statusCode'], 404)
70-
body = json.loads(response['body'])
71-
self.assertIn('error', body)
72-
self.assertEqual(body['executionToken'], execution_token)
73-
74-
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
75-
def test_query_missing_token(self):
76-
"""Test querying status without execution token"""
77-
event = {
78-
'pathParameters': {}
79-
}
80-
81-
response = lambda_handler(event, None)
82-
83-
self.assertEqual(response['statusCode'], 400)
84-
body = json.loads(response['body'])
85-
self.assertIn('error', body)
86-
87-
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
88-
@patch('status_query.table')
89-
def test_query_with_error(self, mock_table):
90-
"""Test querying status for webhook with error"""
91-
execution_token = 'error-token-123'
92-
93-
# Mock DynamoDB response with error
94-
mock_table.get_item.return_value = {
95-
'Item': {
96-
'executionToken': execution_token,
97-
'status': 'failed',
98-
'currentStep': 'validate',
99-
'error': 'Invalid webhook signature',
100-
'createdAt': '2025-02-01T10:00:00.000Z',
101-
'lastUpdated': '2025-02-01T10:00:01.000Z',
102-
'webhookPayload': {'type': 'test.event'}
103-
}
104-
}
105-
106-
event = {
107-
'pathParameters': {'executionToken': execution_token}
108-
}
109-
110-
response = lambda_handler(event, None)
111-
112-
self.assertEqual(response['statusCode'], 200)
113-
body = json.loads(response['body'])
114-
self.assertEqual(body['status'], 'failed')
115-
self.assertIn('error', body)
116-
self.assertEqual(body['error'], 'Invalid webhook signature')
117-
118-
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
119-
@patch('status_query.table')
120-
def test_query_cors_headers(self, mock_table):
121-
"""Test that CORS headers are present in response"""
122-
mock_table.get_item.return_value = {
123-
'Item': {
124-
'executionToken': 'test-token',
125-
'status': 'completed',
126-
'createdAt': '2025-02-01T10:00:00.000Z',
127-
'lastUpdated': '2025-02-01T10:00:05.000Z',
128-
'webhookPayload': {}
129-
}
130-
}
131-
132-
event = {
133-
'pathParameters': {'executionToken': 'test-token'}
134-
}
135-
136-
response = lambda_handler(event, None)
137-
138-
self.assertIn('headers', response)
139-
self.assertIn('Access-Control-Allow-Origin', response['headers'])
140-
self.assertEqual(response['headers']['Access-Control-Allow-Origin'], '*')
141-
142-
143-
if __name__ == '__main__':
144-
unittest.main()
1+
"""
2+
Unit tests for status query function
3+
"""
4+
import json
5+
import os
6+
import sys
7+
import unittest
8+
from unittest.mock import Mock, patch
9+
10+
# Add src to path
11+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
12+
13+
# Set env var before importing module (module-level DynamoDB table init requires it)
14+
os.environ.setdefault('EVENTS_TABLE_NAME', 'test-table')
15+
16+
from status_query import lambda_handler
17+
18+
19+
class TestStatusQuery(unittest.TestCase):
20+
"""Test cases for status query function"""
21+
22+
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
23+
@patch('status_query.table')
24+
def test_query_existing_token(self, mock_table):
25+
"""Test querying status for existing execution token"""
26+
execution_token = 'test-token-123'
27+
28+
# Mock DynamoDB response
29+
mock_table.get_item.return_value = {
30+
'Item': {
31+
'executionToken': execution_token,
32+
'status': 'completed',
33+
'currentStep': 'finalize',
34+
'createdAt': '2025-02-01T10:00:00.000Z',
35+
'lastUpdated': '2025-02-01T10:00:05.000Z',
36+
'webhookPayload': {
37+
'type': 'order.created',
38+
'source': 'test-system',
39+
'orderId': 'ORD-123'
40+
}
41+
}
42+
}
43+
44+
event = {
45+
'pathParameters': {'executionToken': execution_token}
46+
}
47+
48+
response = lambda_handler(event, None)
49+
50+
self.assertEqual(response['statusCode'], 200)
51+
body = json.loads(response['body'])
52+
self.assertEqual(body['executionToken'], execution_token)
53+
self.assertEqual(body['status'], 'completed')
54+
self.assertEqual(body['currentStep'], 'finalize')
55+
self.assertIn('webhookSummary', body)
56+
57+
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
58+
@patch('status_query.table')
59+
def test_query_nonexistent_token(self, mock_table):
60+
"""Test querying status for non-existent execution token"""
61+
execution_token = 'nonexistent-token'
62+
63+
# Mock DynamoDB response with no item
64+
mock_table.get_item.return_value = {}
65+
66+
event = {
67+
'pathParameters': {'executionToken': execution_token}
68+
}
69+
70+
response = lambda_handler(event, None)
71+
72+
self.assertEqual(response['statusCode'], 404)
73+
body = json.loads(response['body'])
74+
self.assertIn('error', body)
75+
self.assertEqual(body['executionToken'], execution_token)
76+
77+
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
78+
def test_query_missing_token(self):
79+
"""Test querying status without execution token"""
80+
event = {
81+
'pathParameters': {}
82+
}
83+
84+
response = lambda_handler(event, None)
85+
86+
self.assertEqual(response['statusCode'], 400)
87+
body = json.loads(response['body'])
88+
self.assertIn('error', body)
89+
90+
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
91+
@patch('status_query.table')
92+
def test_query_with_error(self, mock_table):
93+
"""Test querying status for webhook with error"""
94+
execution_token = 'error-token-123'
95+
96+
# Mock DynamoDB response with error
97+
mock_table.get_item.return_value = {
98+
'Item': {
99+
'executionToken': execution_token,
100+
'status': 'failed',
101+
'currentStep': 'validate',
102+
'error': 'Invalid webhook signature',
103+
'createdAt': '2025-02-01T10:00:00.000Z',
104+
'lastUpdated': '2025-02-01T10:00:01.000Z',
105+
'webhookPayload': {'type': 'test.event'}
106+
}
107+
}
108+
109+
event = {
110+
'pathParameters': {'executionToken': execution_token}
111+
}
112+
113+
response = lambda_handler(event, None)
114+
115+
self.assertEqual(response['statusCode'], 200)
116+
body = json.loads(response['body'])
117+
self.assertEqual(body['status'], 'failed')
118+
self.assertIn('error', body)
119+
self.assertEqual(body['error'], 'Invalid webhook signature')
120+
121+
@patch.dict(os.environ, {'EVENTS_TABLE_NAME': 'test-table'})
122+
@patch('status_query.table')
123+
def test_query_cors_headers(self, mock_table):
124+
"""Test that CORS headers are present in response"""
125+
mock_table.get_item.return_value = {
126+
'Item': {
127+
'executionToken': 'test-token',
128+
'status': 'completed',
129+
'createdAt': '2025-02-01T10:00:00.000Z',
130+
'lastUpdated': '2025-02-01T10:00:05.000Z',
131+
'webhookPayload': {}
132+
}
133+
}
134+
135+
event = {
136+
'pathParameters': {'executionToken': 'test-token'}
137+
}
138+
139+
response = lambda_handler(event, None)
140+
141+
self.assertIn('headers', response)
142+
self.assertIn('Access-Control-Allow-Origin', response['headers'])
143+
self.assertEqual(response['headers']['Access-Control-Allow-Origin'], '*')
144+
145+
146+
if __name__ == '__main__':
147+
unittest.main()

lambda-durable-webhook-sam-python/tests/test_webhook_processor.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
# Add src to path
1111
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
1212

13+
# Set env var before importing module (module-level DynamoDB table init requires it)
14+
os.environ.setdefault('EVENTS_TABLE_NAME', 'test-table')
15+
1316
from webhook_processor import store_event
1417
from webhook_validator import validate_signature
1518

0 commit comments

Comments
 (0)