def test_it_handles_query_planning_complete(table):
    update_status(
        "job123",
        [{
            "Id": "job123",
            "Sk": "123456",
            "Type": "JobEvent",
            "CreatedAt": 123.0,
            "EventName": "QueryPlanningComplete",
            "EventData": {
                "GeneratedQueries":
                123,
                "DeletionQueueSize":
                3456,
                "Manifests":
                ["s3://temp-bucket/manifests/job123/dm-123/manifest.json"],
            },
        }],
    )
    table.update_item.assert_called_with(
        Key={
            "Id": "job123",
            "Sk": "job123",
        },
        UpdateExpression=
        "set #GeneratedQueries = :GeneratedQueries, #DeletionQueueSize = :DeletionQueueSize, #Manifests = :Manifests",
        ConditionExpression=
        "#Id = :Id AND #Sk = :Sk AND (#JobStatus = :RUNNING OR #JobStatus = :QUEUED OR #JobStatus = :FORGET_COMPLETED_CLEANUP_IN_PROGRESS)",
        ExpressionAttributeNames={
            "#Id": "Id",
            "#Sk": "Sk",
            "#JobStatus": "JobStatus",
            "#GeneratedQueries": "GeneratedQueries",
            "#DeletionQueueSize": "DeletionQueueSize",
            "#Manifests": "Manifests",
        },
        ExpressionAttributeValues={
            ":Id":
            "job123",
            ":Sk":
            "job123",
            ":GeneratedQueries":
            123,
            ":DeletionQueueSize":
            3456,
            ":Manifests":
            ["s3://temp-bucket/manifests/job123/dm-123/manifest.json"],
            ":RUNNING":
            "RUNNING",
            ":QUEUED":
            "QUEUED",
            ":FORGET_COMPLETED_CLEANUP_IN_PROGRESS":
            "FORGET_COMPLETED_CLEANUP_IN_PROGRESS",
        },
        ReturnValues="ALL_NEW",
    )
    assert 1 == table.update_item.call_count
def test_it_ignores_none_status_events(table):
    update_status(
        "job123",
        [{
            "Id": "job123",
            "Sk": "123456",
            "Type": "JobEvent",
            "CreatedAt": 123.0,
            "EventName": "SomeEvent",
            "EventData": {},
        }],
    )
    table.update_item.assert_not_called()
def test_it_throws_for_non_condition_errors(table):
    table.update_item.side_effect = ClientError({"Error": {
        "Code": "AnError"
    }}, "update_item")
    with pytest.raises(ClientError):
        update_status(
            "job123",
            [{
                "Id": "job123",
                "Sk": "123456",
                "Type": "JobEvent",
                "CreatedAt": 123.0,
                "EventName": "Exception",
                "EventData": {},
            }],
        )
def test_it_handles_already_failed_jobs(table, ddb):
    e = boto3.client("dynamodb").exceptions.ConditionalCheckFailedException
    ddb.meta.client.exceptions.ConditionalCheckFailedException = e
    table.update_item.side_effect = e({}, "ConditionalCheckFailedException")
    update_status(
        "job123",
        [{
            "Id": "job123",
            "Sk": "123456",
            "Type": "JobEvent",
            "CreatedAt": 123.0,
            "EventName": "Exception",
            "EventData": {},
        }],
    )
    table.update_item.assert_called()
def test_it_handles_job_started(table):
    update_status(
        "job123",
        [{
            "Id": "job123",
            "Sk": "123456",
            "Type": "JobEvent",
            "CreatedAt": 123.0,
            "EventName": "JobStarted",
            "EventData": {},
        }],
    )
    table.update_item.assert_called_with(
        Key={
            "Id": "job123",
            "Sk": "job123",
        },
        UpdateExpression=
        "set #JobStatus = :JobStatus, #JobStartTime = :JobStartTime",
        ConditionExpression=
        "#Id = :Id AND #Sk = :Sk AND (#JobStatus = :RUNNING OR #JobStatus = :QUEUED OR #JobStatus = :FORGET_COMPLETED_CLEANUP_IN_PROGRESS)",
        ExpressionAttributeNames={
            "#Id": "Id",
            "#Sk": "Sk",
            "#JobStatus": "JobStatus",
            "#JobStartTime": "JobStartTime",
        },
        ExpressionAttributeValues={
            ":Id": "job123",
            ":Sk": "job123",
            ":RUNNING": "RUNNING",
            ":QUEUED": "QUEUED",
            ":FORGET_COMPLETED_CLEANUP_IN_PROGRESS":
            "FORGET_COMPLETED_CLEANUP_IN_PROGRESS",
            ":JobStatus": "RUNNING",
            ":JobStartTime": 123.0,
        },
        ReturnValues="ALL_NEW",
    )
    assert 1 == table.update_item.call_count