def test_too_many_event_attributes(self): event_attrs = {} for attr_key in range(MAX_EVENT_ATTRS + 5): event_attrs[str(attr_key)] = 0 proto_events = _extract_events( [ Event( name="a", attributes=event_attrs, timestamp=self.example_time_in_ns, ) ] ) self.assertEqual( len( proto_events.time_event[0].annotation.attributes.attribute_map ), MAX_EVENT_ATTRS, ) self.assertEqual( proto_events.time_event[ 0 ].annotation.attributes.dropped_attributes_count, len(event_attrs) - MAX_EVENT_ATTRS, )
def test_extract_events(self): self.assertIsNone(_extract_events([])) time_in_ns1 = 1589919268850900051 time_in_ms_and_ns1 = {"seconds": 1589919268, "nanos": 850899968} time_in_ns2 = 1589919438550020326 time_in_ms_and_ns2 = {"seconds": 1589919438, "nanos": 550020352} event1 = Event( name="event1", attributes=self.attributes_variety_pack, timestamp=time_in_ns1, ) event2 = Event( name="event2", attributes={"illegal_attr_value": dict()}, timestamp=time_in_ns2, ) self.assertEqual( _extract_events([event1, event2]), ProtoSpan.TimeEvents( time_event=[ { "time": time_in_ms_and_ns1, "annotation": { "description": TruncatableString( value="event1", truncated_byte_count=0 ), "attributes": self.extracted_attributes_variety_pack, }, }, { "time": time_in_ms_and_ns2, "annotation": { "description": TruncatableString( value="event2", truncated_byte_count=0 ), "attributes": ProtoSpan.Attributes( attribute_map={}, dropped_attributes_count=1 ), }, }, ] ), )
def test_extract_multiple_events(self): event1 = Event( name="event1", attributes=self.attributes_variety_pack, timestamp=self.example_time_in_ns, ) event2_nanos = 1589919438550020326 event2 = Event( name="event2", attributes={"illegal_attr_value": dict()}, timestamp=event2_nanos, ) self.assertEqual( _extract_events([event1, event2]), ProtoSpan.TimeEvents( time_event=[ { "time": self.example_time_stamp, "annotation": { "description": TruncatableString( value="event1", truncated_byte_count=0 ), "attributes": self.extracted_attributes_variety_pack, }, }, { "time": _get_time_from_ns(event2_nanos), "annotation": { "description": TruncatableString( value="event2", truncated_byte_count=0 ), "attributes": ProtoSpan.Attributes( attribute_map={}, dropped_attributes_count=1 ), }, }, ] ), )
def test_event_name_truncation(self): event1 = Event(name=self.str_300, attributes={}, timestamp=self.example_time_in_ns) self.assertEqual( _extract_events([event1]), ProtoSpan.TimeEvents(time_event=[ { "time": self.example_time_stamp, "annotation": { "description": TruncatableString( value=self.str_256, truncated_byte_count=300 - 256, ), "attributes": {}, }, }, ]), )
def test_too_many_events(self): event = Event(name="event", timestamp=self.example_time_in_ns, attributes={}) too_many_events = [event] * (MAX_NUM_EVENTS + 5) self.assertEqual( _extract_events(too_many_events), ProtoSpan.TimeEvents( time_event=[ { "time": self.example_time_stamp, "annotation": { "description": TruncatableString(value="event", ), "attributes": {}, }, }, ] * MAX_NUM_EVENTS, dropped_annotations_count=len(too_many_events) - MAX_NUM_EVENTS, ), )
def test_truncate(self): """Cloud Trace API imposes limits on the length of many things, e.g. strings, number of events, number of attributes. We truncate these things before sending it to the API as an optimization. """ str_300 = "a" * 300 str_256 = "a" * 256 str_128 = "a" * 128 self.assertEqual(_truncate_str("aaaa", 1), ("a", 3)) self.assertEqual(_truncate_str("aaaa", 5), ("aaaa", 0)) self.assertEqual(_truncate_str("aaaa", 4), ("aaaa", 0)) self.assertEqual(_truncate_str("中文翻译", 4), ("中", 9)) self.assertEqual( _format_attribute_value(str_300), AttributeValue( string_value=TruncatableString( value=str_256, truncated_byte_count=300 - 256 ) ), ) self.assertEqual( _extract_attributes({str_300: str_300}, 4), ProtoSpan.Attributes( attribute_map={ str_128: AttributeValue( string_value=TruncatableString( value=str_256, truncated_byte_count=300 - 256 ) ) } ), ) time_in_ns1 = 1589919268850900051 time_in_ms_and_ns1 = {"seconds": 1589919268, "nanos": 850899968} event1 = Event(name=str_300, attributes={}, timestamp=time_in_ns1) self.assertEqual( _extract_events([event1]), ProtoSpan.TimeEvents( time_event=[ { "time": time_in_ms_and_ns1, "annotation": { "description": TruncatableString( value=str_256, truncated_byte_count=300 - 256 ), "attributes": {}, }, }, ] ), ) trace_id = "6e0c63257de34c92bf9efcd03927272e" span_id = "95bb5edabd45950f" link = Link( context=SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id, 16), is_remote=False, ), attributes={}, ) too_many_links = [link] * (MAX_NUM_LINKS + 1) self.assertEqual( _extract_links(too_many_links), ProtoSpan.Links( link=[ { "trace_id": trace_id, "span_id": span_id, "type": "TYPE_UNSPECIFIED", "attributes": {}, } ] * MAX_NUM_LINKS, dropped_links_count=len(too_many_links) - MAX_NUM_LINKS, ), ) link_attrs = {} for attr_key in range(MAX_LINK_ATTRS + 1): link_attrs[str(attr_key)] = 0 attr_link = Link( context=SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id, 16), is_remote=False, ), attributes=link_attrs, ) proto_link = _extract_links([attr_link]) self.assertEqual( len(proto_link.link[0].attributes.attribute_map), MAX_LINK_ATTRS ) too_many_events = [event1] * (MAX_NUM_EVENTS + 1) self.assertEqual( _extract_events(too_many_events), ProtoSpan.TimeEvents( time_event=[ { "time": time_in_ms_and_ns1, "annotation": { "description": TruncatableString( value=str_256, truncated_byte_count=300 - 256 ), "attributes": {}, }, }, ] * MAX_NUM_EVENTS, dropped_annotations_count=len(too_many_events) - MAX_NUM_EVENTS, ), ) time_in_ns1 = 1589919268850900051 event_attrs = {} for attr_key in range(MAX_EVENT_ATTRS + 1): event_attrs[str(attr_key)] = 0 proto_events = _extract_events( [Event(name="a", attributes=event_attrs, timestamp=time_in_ns1)] ) self.assertEqual( len( proto_events.time_event[0].annotation.attributes.attribute_map ), MAX_EVENT_ATTRS, )