1616 AWS_LOCAL_OPERATION ,
1717 AWS_LOCAL_SERVICE ,
1818 AWS_REMOTE_OPERATION ,
19+ AWS_REMOTE_RESOURCE_ACCESS_KEY ,
20+ AWS_REMOTE_RESOURCE_ACCOUNT_ID ,
1921 AWS_REMOTE_RESOURCE_IDENTIFIER ,
22+ AWS_REMOTE_RESOURCE_REGION ,
2023 AWS_REMOTE_RESOURCE_TYPE ,
2124 AWS_REMOTE_SERVICE ,
2225 AWS_SPAN_KIND ,
5053_AWS_STATE_MACHINE_ARN : str = "aws.stepfunctions.state_machine.arn"
5154_AWS_ACTIVITY_ARN : str = "aws.stepfunctions.activity.arn"
5255_AWS_SNS_TOPIC_ARN : str = "aws.sns.topic.arn"
56+ _AWS_DYNAMODB_TABLE_ARN : str = "aws.dynamodb.table.arn"
57+ _AWS_KINESIS_STREAM_ARN : str = "aws.kinesis.stream.arn"
5358
5459
5560# pylint: disable=too-many-public-methods,too-many-lines
@@ -212,6 +217,29 @@ def test_dynamodb_create_table(self):
212217 span_name = "DynamoDB.CreateTable" ,
213218 )
214219
220+ def test_dynamodb_describe_table (self ):
221+ self .do_test_requests (
222+ "ddb/describetable/some-table" ,
223+ "GET" ,
224+ 200 ,
225+ 0 ,
226+ 0 ,
227+ remote_service = "AWS::DynamoDB" ,
228+ remote_operation = "DescribeTable" ,
229+ remote_resource_type = "AWS::DynamoDB::Table" ,
230+ remote_resource_identifier = "put_test_table" ,
231+ remote_resource_account_id = "000000000000" ,
232+ remote_resource_region = "us-west-2" ,
233+ cloudformation_primary_identifier = "put_test_table" ,
234+ request_specific_attributes = {
235+ SpanAttributes .AWS_DYNAMODB_TABLE_NAMES : ["put_test_table" ],
236+ },
237+ response_specific_attributes = {
238+ _AWS_DYNAMODB_TABLE_ARN : r"arn:aws:dynamodb:us-west-2:000000000000:table/put_test_table" ,
239+ },
240+ span_name = "DynamoDB.DescribeTable" ,
241+ )
242+
215243 def test_dynamodb_put_item (self ):
216244 self .do_test_requests (
217245 "ddb/putitem/putitem-table/key" ,
@@ -379,6 +407,26 @@ def test_kinesis_put_record(self):
379407 span_name = "Kinesis.PutRecord" ,
380408 )
381409
410+ def test_kinesis_describe_stream (self ):
411+ self .do_test_requests (
412+ "kinesis/describestream/my-stream" ,
413+ "GET" ,
414+ 200 ,
415+ 0 ,
416+ 0 ,
417+ remote_service = "AWS::Kinesis" ,
418+ remote_operation = "DescribeStream" ,
419+ remote_resource_type = "AWS::Kinesis::Stream" ,
420+ remote_resource_identifier = "test_stream" ,
421+ cloudformation_primary_identifier = "test_stream" ,
422+ remote_resource_account_id = "000000000000" ,
423+ remote_resource_region = "us-west-2" ,
424+ request_specific_attributes = {
425+ _AWS_KINESIS_STREAM_NAME : "test_stream" ,
426+ },
427+ span_name = "Kinesis.DescribeStream" ,
428+ )
429+
382430 def test_kinesis_error (self ):
383431 self .do_test_requests (
384432 "kinesis/error" ,
@@ -905,6 +953,26 @@ def test_stepfunctions_fault(self):
905953 span_name = "SFN.ListStateMachineVersions" ,
906954 )
907955
956+ def test_cross_account (self ):
957+ self .do_test_requests (
958+ "cross-account/createbucket/account_b" ,
959+ "GET" ,
960+ 200 ,
961+ 0 ,
962+ 0 ,
963+ remote_service = "AWS::S3" ,
964+ remote_operation = "CreateBucket" ,
965+ remote_resource_type = "AWS::S3::Bucket" ,
966+ remote_resource_identifier = "cross-account-bucket" ,
967+ cloudformation_primary_identifier = "cross-account-bucket" ,
968+ request_specific_attributes = {
969+ SpanAttributes .AWS_S3_BUCKET : "cross-account-bucket" ,
970+ },
971+ remote_resource_access_key = "account_b_access_key_id" ,
972+ remote_resource_region = "eu-central-1" ,
973+ span_name = "S3.CreateBucket" ,
974+ )
975+
908976 # TODO: Add contract test for lambda event source mapping resource
909977
910978 @override
@@ -924,6 +992,9 @@ def _assert_aws_span_attributes(self, resource_scope_spans: List[ResourceScopeSp
924992 kwargs .get ("remote_resource_type" , "None" ),
925993 kwargs .get ("remote_resource_identifier" , "None" ),
926994 kwargs .get ("cloudformation_primary_identifier" , "None" ),
995+ kwargs .get ("remote_resource_account_id" , "None" ),
996+ kwargs .get ("remote_resource_access_key" , "None" ),
997+ kwargs .get ("remote_resource_region" , "None" ),
927998 )
928999
9291000 def _assert_aws_attributes (
@@ -935,6 +1006,9 @@ def _assert_aws_attributes(
9351006 remote_resource_type : str ,
9361007 remote_resource_identifier : str ,
9371008 cloudformation_primary_identifier : str ,
1009+ remote_resource_account_id : str ,
1010+ remote_resource_access_key : str ,
1011+ remote_resource_region : str ,
9381012 ) -> None :
9391013 attributes_dict : Dict [str , AnyValue ] = self ._get_attributes_dict (attributes_list )
9401014 self ._assert_str_attribute (attributes_dict , AWS_LOCAL_SERVICE , self .get_application_otel_service_name ())
@@ -961,8 +1035,16 @@ def _assert_aws_attributes(
9611035 self ._assert_str_attribute (
9621036 attributes_dict , AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER , cloudformation_primary_identifier
9631037 )
964- # See comment above AWS_LOCAL_OPERATION
965- self ._assert_str_attribute (attributes_dict , AWS_SPAN_KIND , span_kind )
1038+ if remote_resource_account_id != "None" :
1039+ assert remote_resource_identifier != "None"
1040+ self ._assert_str_attribute (attributes_dict , AWS_REMOTE_RESOURCE_ACCOUNT_ID , remote_resource_account_id )
1041+ self .assertIsNone (attributes_dict .get (AWS_REMOTE_RESOURCE_ACCESS_KEY ))
1042+ if remote_resource_access_key != "None" :
1043+ assert remote_resource_identifier != "None"
1044+ self ._assert_str_attribute (attributes_dict , AWS_REMOTE_RESOURCE_ACCESS_KEY , remote_resource_access_key )
1045+ self .assertIsNone (attributes_dict .get (AWS_REMOTE_RESOURCE_ACCOUNT_ID ))
1046+ if remote_resource_region != "None" :
1047+ self ._assert_str_attribute (attributes_dict , AWS_REMOTE_RESOURCE_REGION , remote_resource_region )
9661048
9671049 @override
9681050 def _assert_semantic_conventions_span_attributes (
@@ -1050,13 +1132,26 @@ def _assert_metric_attributes(
10501132 self ._assert_str_attribute (attribute_dict , AWS_SPAN_KIND , "CLIENT" )
10511133 remote_resource_type = kwargs .get ("remote_resource_type" , "None" )
10521134 remote_resource_identifier = kwargs .get ("remote_resource_identifier" , "None" )
1135+ remote_resource_account_id = kwargs .get ("remote_resource_account_id" , "None" )
1136+ remote_resource_access_key = kwargs .get ("remote_resource_access_key" , "None" )
1137+ remote_resource_region = kwargs .get ("remote_resource_region" , "None" )
10531138 if remote_resource_type != "None" :
10541139 self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_TYPE , remote_resource_type )
10551140 if remote_resource_identifier != "None" :
10561141 if self ._is_valid_regex (remote_resource_identifier ):
10571142 self ._assert_match_attribute (attribute_dict , AWS_REMOTE_RESOURCE_IDENTIFIER , remote_resource_identifier )
10581143 else :
10591144 self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_IDENTIFIER , remote_resource_identifier )
1145+ if remote_resource_account_id != "None" :
1146+ assert remote_resource_identifier != "None"
1147+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_ACCOUNT_ID , remote_resource_account_id )
1148+ self .assertIsNone (attribute_dict .get (AWS_REMOTE_RESOURCE_ACCESS_KEY ))
1149+ if remote_resource_access_key != "None" :
1150+ assert remote_resource_identifier != "None"
1151+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_ACCESS_KEY , remote_resource_access_key )
1152+ self .assertIsNone (attribute_dict .get (AWS_REMOTE_RESOURCE_ACCOUNT_ID ))
1153+ if remote_resource_region != "None" :
1154+ self ._assert_str_attribute (attribute_dict , AWS_REMOTE_RESOURCE_REGION , remote_resource_region )
10601155 self .check_sum (metric_name , dependency_dp .sum , expected_sum )
10611156
10621157 attribute_dict : Dict [str , AnyValue ] = self ._get_attributes_dict (service_dp .attributes )
0 commit comments