Databrew: Allow spaces in names (#6923)
This commit is contained in:
parent
069218e1f3
commit
a0434335d2
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
from typing import Any, Dict, Union
|
from typing import Any, Dict, Union
|
||||||
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from moto.core.common_types import TYPE_RESPONSE
|
from moto.core.common_types import TYPE_RESPONSE
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
@ -39,7 +40,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
# https://docs.aws.amazon.com/databrew/latest/dg/API_DeleteRecipeVersion.html
|
# https://docs.aws.amazon.com/databrew/latest/dg/API_DeleteRecipeVersion.html
|
||||||
if request.method == "DELETE":
|
if request.method == "DELETE":
|
||||||
split_path = self.parsed_url.path.strip("/").split("/")
|
split_path = self._get_path().strip("/").split("/")
|
||||||
recipe_name = split_path[1]
|
recipe_name = split_path[1]
|
||||||
recipe_version = split_path[3]
|
recipe_version = split_path[3]
|
||||||
self.databrew_backend.delete_recipe_version(recipe_name, recipe_version)
|
self.databrew_backend.delete_recipe_version(recipe_name, recipe_version)
|
||||||
@ -49,6 +50,9 @@ class DataBrewResponse(BaseResponse):
|
|||||||
json.dumps({"Name": recipe_name, "RecipeVersion": recipe_version}),
|
json.dumps({"Name": recipe_name, "RecipeVersion": recipe_version}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _get_path(self) -> str:
|
||||||
|
return unquote(self.parsed_url.path)
|
||||||
|
|
||||||
@amzn_request_id
|
@amzn_request_id
|
||||||
def list_recipes(self) -> str:
|
def list_recipes(self) -> str:
|
||||||
# https://docs.aws.amazon.com/databrew/latest/dg/API_ListRecipes.html
|
# https://docs.aws.amazon.com/databrew/latest/dg/API_ListRecipes.html
|
||||||
@ -98,7 +102,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def publish_recipe(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
def publish_recipe(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
recipe_name = self.parsed_url.path.strip("/").split("/", 2)[1]
|
recipe_name = self._get_path().strip("/").split("/", 2)[1]
|
||||||
recipe_description = self.parameters.get("Description")
|
recipe_description = self.parameters.get("Description")
|
||||||
self.databrew_backend.publish_recipe(recipe_name, recipe_description)
|
self.databrew_backend.publish_recipe(recipe_name, recipe_description)
|
||||||
return 200, {}, json.dumps({"Name": recipe_name})
|
return 200, {}, json.dumps({"Name": recipe_name})
|
||||||
@ -126,7 +130,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def recipe_response(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
def recipe_response(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
recipe_name = self.parsed_url.path.rstrip("/").rsplit("/", 1)[1]
|
recipe_name = self._get_path().rstrip("/").rsplit("/", 1)[1]
|
||||||
|
|
||||||
if request.method == "PUT":
|
if request.method == "PUT":
|
||||||
return self.put_recipe_response(recipe_name)
|
return self.put_recipe_response(recipe_name)
|
||||||
@ -177,7 +181,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def ruleset_response(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
def ruleset_response(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
ruleset_name = self.parsed_url.path.split("/")[-1]
|
ruleset_name = self._get_path().split("/")[-1]
|
||||||
|
|
||||||
if request.method == "PUT":
|
if request.method == "PUT":
|
||||||
response = self.put_ruleset_response(ruleset_name)
|
response = self.put_ruleset_response(ruleset_name)
|
||||||
@ -281,7 +285,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def dataset_response(self, request: Any, full_url: str, headers: Any) -> Union[str, TYPE_RESPONSE]: # type: ignore[return]
|
def dataset_response(self, request: Any, full_url: str, headers: Any) -> Union[str, TYPE_RESPONSE]: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
dataset_name = self.parsed_url.path.split("/")[-1]
|
dataset_name = self._get_path().split("/")[-1]
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
return self.create_dataset()
|
return self.create_dataset()
|
||||||
@ -334,7 +338,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def job_response(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
def job_response(self, request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
job_name = self.parsed_url.path.rstrip("/").rsplit("/", 1)[1]
|
job_name = self._get_path().rstrip("/").rsplit("/", 1)[1]
|
||||||
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
return self.get_job_response(job_name)
|
return self.get_job_response(job_name)
|
||||||
@ -424,7 +428,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def profile_job_response(self, request: Any, full_url: str, headers: Any) -> str: # type: ignore[return]
|
def profile_job_response(self, request: Any, full_url: str, headers: Any) -> str: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
job_name = self.parsed_url.path.rstrip("/").rsplit("/", 1)[1]
|
job_name = self._get_path().rstrip("/").rsplit("/", 1)[1]
|
||||||
|
|
||||||
if request.method == "PUT":
|
if request.method == "PUT":
|
||||||
return self.update_profile_job_response(job_name)
|
return self.update_profile_job_response(job_name)
|
||||||
@ -433,7 +437,7 @@ class DataBrewResponse(BaseResponse):
|
|||||||
def recipe_job_response(self, request: Any, full_url: str, headers: Any) -> str: # type: ignore[return]
|
def recipe_job_response(self, request: Any, full_url: str, headers: Any) -> str: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
job_name = self.parsed_url.path.rstrip("/").rsplit("/", 1)[1]
|
job_name = self._get_path().rstrip("/").rsplit("/", 1)[1]
|
||||||
|
|
||||||
if request.method == "PUT":
|
if request.method == "PUT":
|
||||||
return self.update_recipe_job_response(job_name)
|
return self.update_recipe_job_response(job_name)
|
||||||
|
@ -177,20 +177,22 @@ def test_create_dataset_that_already_exists():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_delete_dataset():
|
@pytest.mark.parametrize("name", ["name", "name with space"])
|
||||||
|
def test_delete_dataset(name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
response = _create_test_dataset(client)
|
response = _create_test_dataset(client, dataset_name=name)
|
||||||
|
assert response["Name"] == name
|
||||||
|
|
||||||
# Check dataset exists
|
# Check dataset exists
|
||||||
dataset = client.describe_dataset(Name=response["Name"])
|
dataset = client.describe_dataset(Name=name)
|
||||||
assert dataset["Name"] == response["Name"]
|
assert dataset["Name"] == name
|
||||||
|
|
||||||
# Delete the dataset
|
# Delete the dataset
|
||||||
client.delete_dataset(Name=response["Name"])
|
client.delete_dataset(Name=name)
|
||||||
|
|
||||||
# Check it does not exist anymore
|
# Check it does not exist anymore
|
||||||
with pytest.raises(ClientError) as exc:
|
with pytest.raises(ClientError) as exc:
|
||||||
client.describe_dataset(Name=response["Name"])
|
client.describe_dataset(Name=name)
|
||||||
|
|
||||||
err = exc.value.response["Error"]
|
err = exc.value.response["Error"]
|
||||||
assert err["Code"] == "ResourceNotFoundException"
|
assert err["Code"] == "ResourceNotFoundException"
|
||||||
@ -198,20 +200,21 @@ def test_delete_dataset():
|
|||||||
|
|
||||||
# Check that a dataset that does not exist errors
|
# Check that a dataset that does not exist errors
|
||||||
with pytest.raises(ClientError) as exc:
|
with pytest.raises(ClientError) as exc:
|
||||||
client.delete_dataset(Name=response["Name"])
|
client.delete_dataset(Name=name)
|
||||||
err = exc.value.response["Error"]
|
err = exc.value.response["Error"]
|
||||||
assert err["Code"] == "ResourceNotFoundException"
|
assert err["Code"] == "ResourceNotFoundException"
|
||||||
assert err["Message"] == "One or more resources can't be found."
|
assert err["Message"] == "One or more resources can't be found."
|
||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_update_dataset():
|
@pytest.mark.parametrize("name", ["name", "name with space"])
|
||||||
|
def test_update_dataset(name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
response = _create_test_dataset(client)
|
_create_test_dataset(client, dataset_name=name)
|
||||||
|
|
||||||
# Update the dataset and check response
|
# Update the dataset and check response
|
||||||
dataset = client.update_dataset(
|
dataset = client.update_dataset(
|
||||||
Name=response["Name"],
|
Name=name,
|
||||||
Format="TEST",
|
Format="TEST",
|
||||||
Input={
|
Input={
|
||||||
"S3InputDefinition": {
|
"S3InputDefinition": {
|
||||||
@ -232,15 +235,15 @@ def test_update_dataset():
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert dataset["Name"] == response["Name"]
|
assert dataset["Name"] == name
|
||||||
|
|
||||||
# Describe the dataset and check the changes
|
# Describe the dataset and check the changes
|
||||||
dataset = client.describe_dataset(Name=response["Name"])
|
dataset = client.describe_dataset(Name=name)
|
||||||
assert dataset["Name"] == response["Name"]
|
assert dataset["Name"] == name
|
||||||
assert dataset["Format"] == "TEST"
|
assert dataset["Format"] == "TEST"
|
||||||
assert (
|
assert (
|
||||||
dataset["ResourceArn"]
|
dataset["ResourceArn"]
|
||||||
== f"arn:aws:databrew:us-west-1:{ACCOUNT_ID}:dataset/{response['Name']}"
|
== f"arn:aws:databrew:us-west-1:{ACCOUNT_ID}:dataset/{name}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,12 +184,12 @@ def test_describe_job_with_long_name():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_update_profile_job():
|
@pytest.mark.parametrize("job_name", ["name", "name with space"])
|
||||||
|
def test_update_profile_job(job_name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
|
|
||||||
# Create the job
|
# Create the job
|
||||||
response = _create_test_profile_job(client)
|
response = _create_test_profile_job(client, job_name=job_name)
|
||||||
job_name = response["Name"]
|
|
||||||
|
|
||||||
# Update the job by changing RoleArn
|
# Update the job by changing RoleArn
|
||||||
update_response = client.update_profile_job(
|
update_response = client.update_profile_job(
|
||||||
@ -205,12 +205,12 @@ def test_update_profile_job():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_update_recipe_job():
|
@pytest.mark.parametrize("job_name", ["name", "name with space"])
|
||||||
|
def test_update_recipe_job(job_name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
|
|
||||||
# Create the job
|
# Create the job
|
||||||
response = _create_test_recipe_job(client)
|
response = _create_test_recipe_job(client, job_name=job_name)
|
||||||
job_name = response["Name"]
|
|
||||||
|
|
||||||
# Update the job by changing RoleArn
|
# Update the job by changing RoleArn
|
||||||
update_response = client.update_recipe_job(Name=job_name, RoleArn="a" * 20)
|
update_response = client.update_recipe_job(Name=job_name, RoleArn="a" * 20)
|
||||||
@ -250,12 +250,12 @@ def test_update_recipe_job_does_not_exist():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_delete_job():
|
@pytest.mark.parametrize("job_name", ["name", "name with space"])
|
||||||
|
def test_delete_job(job_name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
|
|
||||||
# Create the job
|
# Create the job
|
||||||
response = _create_test_recipe_job(client)
|
_create_test_recipe_job(client, job_name=job_name)
|
||||||
job_name = response["Name"]
|
|
||||||
|
|
||||||
# Delete the job
|
# Delete the job
|
||||||
response = client.delete_job(Name=job_name)
|
response = client.delete_job(Name=job_name)
|
||||||
|
@ -162,13 +162,14 @@ def test_describe_recipe_latest_working():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_describe_recipe_with_version():
|
@pytest.mark.parametrize("name", ["name", "name with space"])
|
||||||
|
def test_describe_recipe_with_version(name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
response = _create_test_recipe(client)
|
_create_test_recipe(client, recipe_name=name)
|
||||||
|
|
||||||
recipe = client.describe_recipe(Name=response["Name"], RecipeVersion="0.1")
|
recipe = client.describe_recipe(Name=name, RecipeVersion="0.1")
|
||||||
|
|
||||||
assert recipe["Name"] == response["Name"]
|
assert recipe["Name"] == name
|
||||||
assert len(recipe["Steps"]) == 1
|
assert len(recipe["Steps"]) == 1
|
||||||
assert recipe["RecipeVersion"] == "0.1"
|
assert recipe["RecipeVersion"] == "0.1"
|
||||||
|
|
||||||
@ -260,12 +261,13 @@ def test_describe_recipe_with_invalid_version():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_update_recipe():
|
@pytest.mark.parametrize("name", ["name", "name with space"])
|
||||||
|
def test_update_recipe(name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
response = _create_test_recipe(client)
|
_create_test_recipe(client, recipe_name=name)
|
||||||
|
|
||||||
recipe = client.update_recipe(
|
recipe = client.update_recipe(
|
||||||
Name=response["Name"],
|
Name=name,
|
||||||
Steps=[
|
Steps=[
|
||||||
{
|
{
|
||||||
"Action": {
|
"Action": {
|
||||||
@ -290,13 +292,11 @@ def test_update_recipe():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
assert recipe["Name"] == response["Name"]
|
assert recipe["Name"] == name
|
||||||
|
|
||||||
# Describe the recipe and check the changes
|
# Describe the recipe and check the changes
|
||||||
recipe = client.describe_recipe(
|
recipe = client.describe_recipe(Name=name, RecipeVersion="LATEST_WORKING")
|
||||||
Name=response["Name"], RecipeVersion="LATEST_WORKING"
|
assert recipe["Name"] == name
|
||||||
)
|
|
||||||
assert recipe["Name"] == response["Name"]
|
|
||||||
assert len(recipe["Steps"]) == 1
|
assert len(recipe["Steps"]) == 1
|
||||||
assert recipe["Steps"][0]["Action"]["Parameters"]["removeCustomValue"] == "true"
|
assert recipe["Steps"][0]["Action"]["Parameters"]["removeCustomValue"] == "true"
|
||||||
|
|
||||||
@ -349,11 +349,11 @@ def test_create_recipe_that_already_exists():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_publish_recipe():
|
@pytest.mark.parametrize("recipe_name", ["name", "name with space"])
|
||||||
|
def test_publish_recipe(recipe_name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
|
|
||||||
response = _create_test_recipe(client)
|
_create_test_recipe(client, recipe_name=recipe_name)
|
||||||
recipe_name = response["Name"]
|
|
||||||
|
|
||||||
# Before a recipe is published, we should not be able to retrieve a published version
|
# Before a recipe is published, we should not be able to retrieve a published version
|
||||||
with pytest.raises(ClientError) as exc:
|
with pytest.raises(ClientError) as exc:
|
||||||
@ -412,10 +412,11 @@ def test_publish_long_recipe_name():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_delete_recipe_version():
|
@pytest.mark.parametrize("recipe_name", ["name", "name with space"])
|
||||||
|
def test_delete_recipe_version(recipe_name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
response = _create_test_recipe(client)
|
_create_test_recipe(client, recipe_name=recipe_name)
|
||||||
recipe_name = response["Name"]
|
|
||||||
client.delete_recipe_version(Name=recipe_name, RecipeVersion="LATEST_WORKING")
|
client.delete_recipe_version(Name=recipe_name, RecipeVersion="LATEST_WORKING")
|
||||||
with pytest.raises(ClientError) as exc:
|
with pytest.raises(ClientError) as exc:
|
||||||
client.describe_recipe(Name=recipe_name)
|
client.describe_recipe(Name=recipe_name)
|
||||||
|
@ -144,13 +144,14 @@ def test_delete_ruleset():
|
|||||||
|
|
||||||
|
|
||||||
@mock_databrew
|
@mock_databrew
|
||||||
def test_update_ruleset():
|
@pytest.mark.parametrize("name", ["name", "name with space"])
|
||||||
|
def test_update_ruleset(name):
|
||||||
client = _create_databrew_client()
|
client = _create_databrew_client()
|
||||||
response = _create_test_ruleset(client)
|
_create_test_ruleset(client, ruleset_name=name)
|
||||||
|
|
||||||
# Update the ruleset and check response
|
# Update the ruleset and check response
|
||||||
ruleset = client.update_ruleset(
|
ruleset = client.update_ruleset(
|
||||||
Name=response["Name"],
|
Name=name,
|
||||||
Rules=[
|
Rules=[
|
||||||
{
|
{
|
||||||
"Name": "Assert values > 0",
|
"Name": "Assert values > 0",
|
||||||
@ -165,10 +166,10 @@ def test_update_ruleset():
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert ruleset["Name"] == response["Name"]
|
assert ruleset["Name"] == name
|
||||||
|
|
||||||
# Describe the ruleset and check the changes
|
# Describe the ruleset and check the changes
|
||||||
ruleset = client.describe_ruleset(Name=response["Name"])
|
ruleset = client.describe_ruleset(Name=name)
|
||||||
assert ruleset["Name"] == response["Name"]
|
assert ruleset["Name"] == name
|
||||||
assert len(ruleset["Rules"]) == 1
|
assert len(ruleset["Rules"]) == 1
|
||||||
assert ruleset["Rules"][0]["SubstitutionMap"][":val1"] == "10"
|
assert ruleset["Rules"][0]["SubstitutionMap"][":val1"] == "10"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user