Repository: getmoto/moto
Pull request #6000 (2023-02-28 07:24:10)

Store client_request_token in FakePipelineExecution object


Patch:
diff --git a/moto/resourcegroupstaggingapi/models.py b/moto/resourcegroupstaggingapi/models.py
index 1fa101047..0514901c6 100644
--- a/moto/resourcegroupstaggingapi/models.py
+++ b/moto/resourcegroupstaggingapi/models.py
@@ -326,6 +326,21 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
 
                 yield {"ResourceARN": f"{kms_key.arn}", "Tags": tags}
 
+        # RDS Cluster
+        if (
+            not resource_type_filters
+            or "rds" in resource_type_filters
+            or "rds:cluster" in resource_type_filters
+        ):
+            for cluster in self.rds_backend.clusters.values():
+                tags = cluster.get_tags()
+                if not tags or not tag_filter(tags):
+                    continue
+                yield {
+                    "ResourceARN": cluster.db_cluster_arn,
+                    "Tags": tags,
+                }
+
         # RDS Instance
         if (
             not resource_type_filters
diff --git a/moto/sagemaker/models.py b/moto/sagemaker/models.py
index 2d5a2103b..d1ea299a4 100644
--- a/moto/sagemaker/models.py
+++ b/moto/sagemaker/models.py
@@ -88,6 +88,7 @@ class FakePipelineExecution(BaseObject):
         pipeline_execution_description,
         parallelism_configuration,
         pipeline_definition,
+        client_request_token,
     ):
         self.pipeline_execution_arn = pipeline_execution_arn
         self.pipeline_execution_display_name = pipeline_execution_display_name
@@ -97,6 +98,7 @@ class FakePipelineExecution(BaseObject):
         self.pipeline_execution_failure_reason = None
         self.parallelism_configuration = parallelism_configuration
         self.pipeline_definition_for_execution = pipeline_definition
+        self.client_request_token = client_request_token
 
         now_string = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
         self.creation_time = now_string
@@ -1909,6 +1911,7 @@ class SageMakerModelBackend(BaseBackend):
         pipeline_parameters,
         pipeline_execution_description,
         parallelism_configuration,
+        client_request_token,
     ):
         pipeline = get_pipeline_from_name(self.pipelines, pipeline_name)
         execution_id = "".join(
@@ -1929,6 +1932,7 @@ class SageMakerModelBackend(BaseBackend):
             pipeline_definition=pipeline.pipeline_definition,
             parallelism_configuration=parallelism_configuration
             or pipeline.parallelism_configuration,
+            client_request_token=client_request_token,
         )
 
         self.pipelines[pipeline_name].pipeline_executions[
diff --git a/moto/sagemaker/responses.py b/moto/sagemaker/responses.py
index 2a6cc4bfc..c679cb5dd 100644
--- a/moto/sagemaker/responses.py
+++ b/moto/sagemaker/responses.py
@@ -480,6 +480,7 @@ class SageMakerResponse(BaseResponse):
             self._get_param("PipelineParameters"),
             self._get_param("PipelineExecutionDescription"),
             self._get_param("ParallelismConfiguration"),
+            self._get_param("ClientRequestToken"),
         )
         return 200, {}, json.dumps(response)
 


Test patch:
diff --git a/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py b/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py
index f0ccce2da..072092ad3 100644
--- a/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py
+++ b/tests/test_resourcegroupstaggingapi/test_resourcegroupstaggingapi.py
@@ -422,6 +422,50 @@ def test_get_resources_rds():
     assert_response(resp, 2)
 
 
+@mock_rds
+@mock_resourcegroupstaggingapi
+def test_get_resources_rds_clusters():
+    client = boto3.client("rds", region_name="us-west-2")
+    resources_tagged = []
+    resources_untagged = []
+    for i in range(3):
+        cluster = client.create_db_cluster(
+            DBClusterIdentifier=f"db-cluster-{i}",
+            Engine="postgres",
+            MasterUsername="admin",
+            MasterUserPassword="P@ssw0rd!",
+            CopyTagsToSnapshot=True if i else False,
+            Tags=[{"Key": "test", "Value": f"value-{i}"}] if i else [],
+        ).get("DBCluster")
+        snapshot = client.create_db_cluster_snapshot(
+            DBClusterIdentifier=cluster["DBClusterIdentifier"],
+            DBClusterSnapshotIdentifier=f"snapshot-{i}",
+        ).get("DBClusterSnapshot")
+        group = resources_tagged if i else resources_untagged
+        group.append(cluster["DBClusterArn"])
+        group.append(snapshot["DBClusterSnapshotArn"])
+
+    def assert_response(response, expected_count, resource_type=None):
+        results = response.get("ResourceTagMappingList", [])
+        results.should.have.length_of(expected_count)
+        for item in results:
+            arn = item["ResourceARN"]
+            arn.should.be.within(resources_tagged)
+            arn.should_not.be.within(resources_untagged)
+            if resource_type:
+                sure.this(f":{resource_type}:").should.be.within(arn)
+
+    rtapi = boto3.client("resourcegroupstaggingapi", region_name="us-west-2")
+    resp = rtapi.get_resources(ResourceTypeFilters=["rds"])
+    assert_response(resp, 4)
+    resp = rtapi.get_resources(ResourceTypeFilters=["rds:cluster"])
+    assert_response(resp, 2, resource_type="cluster")
+    resp = rtapi.get_resources(ResourceTypeFilters=["rds:cluster-snapshot"])
+    assert_response(resp, 2, resource_type="cluster-snapshot")
+    resp = rtapi.get_resources(TagFilters=[{"Key": "test", "Values": ["value-1"]}])
+    assert_response(resp, 2)
+
+
 @mock_lambda
 @mock_resourcegroupstaggingapi
 @mock_iam
diff --git a/tests/test_sagemaker/test_sagemaker_pipeline.py b/tests/test_sagemaker/test_sagemaker_pipeline.py
index 610c85b8c..c17af6d6b 100644
--- a/tests/test_sagemaker/test_sagemaker_pipeline.py
+++ b/tests/test_sagemaker/test_sagemaker_pipeline.py
@@ -16,7 +16,7 @@ from moto.sagemaker.utils import (
     get_pipeline_execution_from_arn,
     get_pipeline_name_from_execution_arn,
 )
-from moto.sagemaker.models import FakePipeline
+from moto.sagemaker.models import FakePipeline, sagemaker_backends
 from moto.sagemaker.utils import arn_formatter, load_pipeline_definition_from_s3
 
 
@@ -203,6 +203,35 @@ def test_start_pipeline_execution(sagemaker_client):
     assert fake_pipeline_names[0] in pipeline_execution_arn["PipelineExecutionArn"]
 
 
+def test_start_pipeline_execution_contains_client_request_token(sagemaker_client):
+    if settings.TEST_SERVER_MODE:
+        raise SkipTest(
+            "Skipping test in server mode due to lack of access to sagemaker_backends."
+        )
+
+    fake_pipeline_names = ["APipelineName"]
+    pipelines = [
+        {
+            "PipelineName": fake_pipeline_names[0],
+            "RoleArn": FAKE_ROLE_ARN,
+            "PipelineDefinition": " ",
+        },
+    ]
+    _ = create_sagemaker_pipelines(sagemaker_client, pipelines)
+    pipeline_execution_arn = sagemaker_client.start_pipeline_execution(
+        PipelineName=fake_pipeline_names[0]
+    )["PipelineExecutionArn"]
+
+    # Verify that client_request_token is stored in FakePipelineExecution object
+    assert (
+        sagemaker_backends[ACCOUNT_ID][TEST_REGION_NAME]
+        .pipelines[fake_pipeline_names[0]]
+        .pipeline_executions[pipeline_execution_arn]
+        .client_request_token
+        != ""
+    )
+
+
 def test_describe_pipeline_execution_not_exists(sagemaker_client):
     pipeline_execution_arn = arn_formatter(
         # random ID (execution ID)