|
1 | 1 | import pytest |
2 | 2 | import uuid |
3 | | -from datetime import timedelta |
| 3 | +import warnings |
| 4 | +from datetime import timedelta, datetime, timezone |
4 | 5 | from unittest.mock import AsyncMock, Mock, PropertyMock |
5 | 6 |
|
6 | 7 | from cadence.api.v1.common_pb2 import WorkflowExecution |
@@ -241,6 +242,75 @@ async def test_build_request_with_cron_schedule(self, mock_client): |
241 | 242 |
|
242 | 243 | assert request.cron_schedule == "0 * * * *" |
243 | 244 |
|
| 245 | + @pytest.mark.asyncio |
| 246 | + async def test_build_request_with_first_run_at_timezone_aware(self, mock_client): |
| 247 | + """Test building request with timezone-aware first_run_at.""" |
| 248 | + client = Client(domain="test-domain", target="localhost:7933") |
| 249 | + |
| 250 | + first_run = datetime(2024, 6, 1, 12, 0, 0, tzinfo=timezone.utc) |
| 251 | + |
| 252 | + options = StartWorkflowOptions( |
| 253 | + task_list="test-task-list", |
| 254 | + execution_start_to_close_timeout=timedelta(minutes=10), |
| 255 | + task_start_to_close_timeout=timedelta(seconds=30), |
| 256 | + cron_schedule="0 * * * *", |
| 257 | + first_run_at=first_run, |
| 258 | + ) |
| 259 | + |
| 260 | + request = client._build_start_workflow_request("TestWorkflow", (), options) |
| 261 | + |
| 262 | + assert request.HasField("first_run_at") |
| 263 | + # Convert back and verify |
| 264 | + result_dt = request.first_run_at.ToDatetime() |
| 265 | + assert result_dt == first_run.replace( |
| 266 | + tzinfo=None |
| 267 | + ) # ToDatetime returns naive UTC |
| 268 | + |
| 269 | + @pytest.mark.asyncio |
| 270 | + async def test_build_request_with_first_run_at_naive(self, mock_client): |
| 271 | + """Test building request with timezone-naive first_run_at.""" |
| 272 | + client = Client(domain="test-domain", target="localhost:7933") |
| 273 | + |
| 274 | + first_run = datetime(2024, 6, 1, 12, 0, 0) # Naive datetime |
| 275 | + |
| 276 | + options = StartWorkflowOptions( |
| 277 | + task_list="test-task-list", |
| 278 | + execution_start_to_close_timeout=timedelta(minutes=10), |
| 279 | + task_start_to_close_timeout=timedelta(seconds=30), |
| 280 | + first_run_at=first_run, |
| 281 | + ) |
| 282 | + |
| 283 | + request = client._build_start_workflow_request("TestWorkflow", (), options) |
| 284 | + |
| 285 | + assert request.HasField("first_run_at") |
| 286 | + |
| 287 | + def test_first_run_at_naive_datetime_warns(self): |
| 288 | + """Test that timezone-naive first_run_at produces warning.""" |
| 289 | + options = StartWorkflowOptions( |
| 290 | + task_list="test-task-list", |
| 291 | + execution_start_to_close_timeout=timedelta(minutes=10), |
| 292 | + first_run_at=datetime(2024, 1, 1, 12, 0, 0), # Naive |
| 293 | + ) |
| 294 | + with pytest.warns(UserWarning, match="timezone-naive"): |
| 295 | + _validate_and_apply_defaults(options) |
| 296 | + |
| 297 | + def test_first_run_at_aware_datetime_no_warning(self): |
| 298 | + """Test that timezone-aware first_run_at produces no warning.""" |
| 299 | + options = StartWorkflowOptions( |
| 300 | + task_list="test-task-list", |
| 301 | + execution_start_to_close_timeout=timedelta(minutes=10), |
| 302 | + first_run_at=datetime(2024, 1, 1, 12, 0, 0, tzinfo=timezone.utc), |
| 303 | + ) |
| 304 | + # Should not warn - use warnings.catch_warnings to verify |
| 305 | + with warnings.catch_warnings(record=True) as w: |
| 306 | + warnings.simplefilter("always") |
| 307 | + _validate_and_apply_defaults(options) |
| 308 | + # Filter for our specific warning |
| 309 | + relevant_warnings = [ |
| 310 | + warning for warning in w if "timezone-naive" in str(warning.message) |
| 311 | + ] |
| 312 | + assert len(relevant_warnings) == 0 |
| 313 | + |
244 | 314 |
|
245 | 315 | class TestClientStartWorkflow: |
246 | 316 | """Test Client.start_workflow method.""" |
|
0 commit comments