def test_it_errors_when_version_to_not_found_after_retries(sleep_mock):
    s3_mock = MagicMock()
    s3_mock.list_object_versions.side_effect = get_list_object_versions_error()

    with pytest.raises(ClientError) as e:
        result = verify_object_versions_integrity(s3_mock, "bucket",
                                                  "requirements.txt", "v7",
                                                  "v8")

    assert sleep_mock.call_args_list == [
        call(2), call(4), call(8),
        call(16), call(32)
    ]
    assert (
        e.value.args[0] ==
        "An error occurred (InvalidArgument) when calling the ListObjectVersions operation: Invalid version id specified"
    )
def test_it_fails_integrity_when_no_other_version_before():
    s3_mock = MagicMock()
    s3_mock.list_object_versions.return_value = {
        "VersionIdMarker": "v7",
        "Versions": [],
    }

    with pytest.raises(IntegrityCheckFailedError) as e:
        result = verify_object_versions_integrity(s3_mock, "bucket",
                                                  "requirements.txt", "v5",
                                                  "v7")

    assert e.value.args == (
        "Previous version (v5) has been deleted.",
        s3_mock,
        "bucket",
        "requirements.txt",
        "v7",
    )
def test_it_verifies_integrity_happy_path():
    s3_mock = MagicMock()
    s3_mock.list_object_versions.return_value = {
        "VersionIdMarker": "v7",
        "Versions": [{
            "VersionId": "v6",
            "ETag": "a"
        }],
    }
    result = verify_object_versions_integrity(s3_mock, "bucket",
                                              "requirements.txt", "v6", "v7")

    assert result
    s3_mock.list_object_versions.assert_called_with(
        Bucket="bucket",
        Prefix="requirements.txt",
        VersionIdMarker="v7",
        KeyMarker="requirements.txt",
        MaxKeys=1,
    )
def test_it_fails_integrity_when_delete_marker_between():
    s3_mock = MagicMock()
    s3_mock.list_object_versions.return_value = {
        "VersionIdMarker": "v7",
        "Versions": [],
        "DeleteMarkers": [{
            "VersionId": "v6"
        }],
    }

    with pytest.raises(IntegrityCheckFailedError) as e:
        result = verify_object_versions_integrity(s3_mock, "bucket",
                                                  "requirements.txt", "v5",
                                                  "v7")
    assert e.value.args == (
        "A delete marker (v6) was detected for the given object between read and write operations (v5 and v7).",
        s3_mock,
        "bucket",
        "requirements.txt",
        "v7",
    )