Databrew: Allow spaces in names (#6923)
This commit is contained in:
		
							parent
							
								
									069218e1f3
								
							
						
					
					
						commit
						a0434335d2
					
				| @ -1,5 +1,6 @@ | ||||
| import json | ||||
| from typing import Any, Dict, Union | ||||
| from urllib.parse import unquote | ||||
| 
 | ||||
| from moto.core.common_types import TYPE_RESPONSE | ||||
| from moto.core.responses import BaseResponse | ||||
| @ -39,7 +40,7 @@ class DataBrewResponse(BaseResponse): | ||||
|         self.setup_class(request, full_url, headers) | ||||
|         # https://docs.aws.amazon.com/databrew/latest/dg/API_DeleteRecipeVersion.html | ||||
|         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_version = split_path[3] | ||||
|             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}), | ||||
|             ) | ||||
| 
 | ||||
|     def _get_path(self) -> str: | ||||
|         return unquote(self.parsed_url.path) | ||||
| 
 | ||||
|     @amzn_request_id | ||||
|     def list_recipes(self) -> str: | ||||
|         # 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] | ||||
|         self.setup_class(request, full_url, headers) | ||||
|         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") | ||||
|             self.databrew_backend.publish_recipe(recipe_name, recipe_description) | ||||
|             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] | ||||
|         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": | ||||
|             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] | ||||
|         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": | ||||
|             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] | ||||
|         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": | ||||
|             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] | ||||
|         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": | ||||
|             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] | ||||
|         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": | ||||
|             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] | ||||
|         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": | ||||
|             return self.update_recipe_job_response(job_name) | ||||
|  | ||||
| @ -177,20 +177,22 @@ def test_create_dataset_that_already_exists(): | ||||
| 
 | ||||
| 
 | ||||
| @mock_databrew | ||||
| def test_delete_dataset(): | ||||
| @pytest.mark.parametrize("name", ["name", "name with space"]) | ||||
| def test_delete_dataset(name): | ||||
|     client = _create_databrew_client() | ||||
|     response = _create_test_dataset(client) | ||||
|     response = _create_test_dataset(client, dataset_name=name) | ||||
|     assert response["Name"] == name | ||||
| 
 | ||||
|     # Check dataset exists | ||||
|     dataset = client.describe_dataset(Name=response["Name"]) | ||||
|     assert dataset["Name"] == response["Name"] | ||||
|     dataset = client.describe_dataset(Name=name) | ||||
|     assert dataset["Name"] == name | ||||
| 
 | ||||
|     # Delete the dataset | ||||
|     client.delete_dataset(Name=response["Name"]) | ||||
|     client.delete_dataset(Name=name) | ||||
| 
 | ||||
|     # Check it does not exist anymore | ||||
|     with pytest.raises(ClientError) as exc: | ||||
|         client.describe_dataset(Name=response["Name"]) | ||||
|         client.describe_dataset(Name=name) | ||||
| 
 | ||||
|     err = exc.value.response["Error"] | ||||
|     assert err["Code"] == "ResourceNotFoundException" | ||||
| @ -198,20 +200,21 @@ def test_delete_dataset(): | ||||
| 
 | ||||
|     # Check that a dataset that does not exist errors | ||||
|     with pytest.raises(ClientError) as exc: | ||||
|         client.delete_dataset(Name=response["Name"]) | ||||
|         client.delete_dataset(Name=name) | ||||
|     err = exc.value.response["Error"] | ||||
|     assert err["Code"] == "ResourceNotFoundException" | ||||
|     assert err["Message"] == "One or more resources can't be found." | ||||
| 
 | ||||
| 
 | ||||
| @mock_databrew | ||||
| def test_update_dataset(): | ||||
| @pytest.mark.parametrize("name", ["name", "name with space"]) | ||||
| def test_update_dataset(name): | ||||
|     client = _create_databrew_client() | ||||
|     response = _create_test_dataset(client) | ||||
|     _create_test_dataset(client, dataset_name=name) | ||||
| 
 | ||||
|     # Update the dataset and check response | ||||
|     dataset = client.update_dataset( | ||||
|         Name=response["Name"], | ||||
|         Name=name, | ||||
|         Format="TEST", | ||||
|         Input={ | ||||
|             "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 | ||||
|     dataset = client.describe_dataset(Name=response["Name"]) | ||||
|     assert dataset["Name"] == response["Name"] | ||||
|     dataset = client.describe_dataset(Name=name) | ||||
|     assert dataset["Name"] == name | ||||
|     assert dataset["Format"] == "TEST" | ||||
|     assert ( | ||||
|         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 | ||||
| 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() | ||||
| 
 | ||||
|     # Create the job | ||||
|     response = _create_test_profile_job(client) | ||||
|     job_name = response["Name"] | ||||
|     response = _create_test_profile_job(client, job_name=job_name) | ||||
| 
 | ||||
|     # Update the job by changing RoleArn | ||||
|     update_response = client.update_profile_job( | ||||
| @ -205,12 +205,12 @@ def test_update_profile_job(): | ||||
| 
 | ||||
| 
 | ||||
| @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() | ||||
| 
 | ||||
|     # Create the job | ||||
|     response = _create_test_recipe_job(client) | ||||
|     job_name = response["Name"] | ||||
|     response = _create_test_recipe_job(client, job_name=job_name) | ||||
| 
 | ||||
|     # Update the job by changing RoleArn | ||||
|     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 | ||||
| def test_delete_job(): | ||||
| @pytest.mark.parametrize("job_name", ["name", "name with space"]) | ||||
| def test_delete_job(job_name): | ||||
|     client = _create_databrew_client() | ||||
| 
 | ||||
|     # Create the job | ||||
|     response = _create_test_recipe_job(client) | ||||
|     job_name = response["Name"] | ||||
|     _create_test_recipe_job(client, job_name=job_name) | ||||
| 
 | ||||
|     # Delete the job | ||||
|     response = client.delete_job(Name=job_name) | ||||
|  | ||||
| @ -162,13 +162,14 @@ def test_describe_recipe_latest_working(): | ||||
| 
 | ||||
| 
 | ||||
| @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() | ||||
|     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 recipe["RecipeVersion"] == "0.1" | ||||
| 
 | ||||
| @ -260,12 +261,13 @@ def test_describe_recipe_with_invalid_version(): | ||||
| 
 | ||||
| 
 | ||||
| @mock_databrew | ||||
| def test_update_recipe(): | ||||
| @pytest.mark.parametrize("name", ["name", "name with space"]) | ||||
| def test_update_recipe(name): | ||||
|     client = _create_databrew_client() | ||||
|     response = _create_test_recipe(client) | ||||
|     _create_test_recipe(client, recipe_name=name) | ||||
| 
 | ||||
|     recipe = client.update_recipe( | ||||
|         Name=response["Name"], | ||||
|         Name=name, | ||||
|         Steps=[ | ||||
|             { | ||||
|                 "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 | ||||
|     recipe = client.describe_recipe( | ||||
|         Name=response["Name"], RecipeVersion="LATEST_WORKING" | ||||
|     ) | ||||
|     assert recipe["Name"] == response["Name"] | ||||
|     recipe = client.describe_recipe(Name=name, RecipeVersion="LATEST_WORKING") | ||||
|     assert recipe["Name"] == name | ||||
|     assert len(recipe["Steps"]) == 1 | ||||
|     assert recipe["Steps"][0]["Action"]["Parameters"]["removeCustomValue"] == "true" | ||||
| 
 | ||||
| @ -349,11 +349,11 @@ def test_create_recipe_that_already_exists(): | ||||
| 
 | ||||
| 
 | ||||
| @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() | ||||
| 
 | ||||
|     response = _create_test_recipe(client) | ||||
|     recipe_name = response["Name"] | ||||
|     _create_test_recipe(client, recipe_name=recipe_name) | ||||
| 
 | ||||
|     # Before a recipe is published, we should not be able to retrieve a published version | ||||
|     with pytest.raises(ClientError) as exc: | ||||
| @ -412,10 +412,11 @@ def test_publish_long_recipe_name(): | ||||
| 
 | ||||
| 
 | ||||
| @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() | ||||
|     response = _create_test_recipe(client) | ||||
|     recipe_name = response["Name"] | ||||
|     _create_test_recipe(client, recipe_name=recipe_name) | ||||
| 
 | ||||
|     client.delete_recipe_version(Name=recipe_name, RecipeVersion="LATEST_WORKING") | ||||
|     with pytest.raises(ClientError) as exc: | ||||
|         client.describe_recipe(Name=recipe_name) | ||||
|  | ||||
| @ -144,13 +144,14 @@ def test_delete_ruleset(): | ||||
| 
 | ||||
| 
 | ||||
| @mock_databrew | ||||
| def test_update_ruleset(): | ||||
| @pytest.mark.parametrize("name", ["name", "name with space"]) | ||||
| def test_update_ruleset(name): | ||||
|     client = _create_databrew_client() | ||||
|     response = _create_test_ruleset(client) | ||||
|     _create_test_ruleset(client, ruleset_name=name) | ||||
| 
 | ||||
|     # Update the ruleset and check response | ||||
|     ruleset = client.update_ruleset( | ||||
|         Name=response["Name"], | ||||
|         Name=name, | ||||
|         Rules=[ | ||||
|             { | ||||
|                 "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 | ||||
|     ruleset = client.describe_ruleset(Name=response["Name"]) | ||||
|     assert ruleset["Name"] == response["Name"] | ||||
|     ruleset = client.describe_ruleset(Name=name) | ||||
|     assert ruleset["Name"] == name | ||||
|     assert len(ruleset["Rules"]) == 1 | ||||
|     assert ruleset["Rules"][0]["SubstitutionMap"][":val1"] == "10" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user