def test_clear(self): annotations = [Mock(spec=Annotation), Mock(spec=Annotation)] binary_annotations = [ Mock(spec=BinaryAnnotation), Mock(spec=BinaryAnnotation) ] store = ThreadLocalDataStore() store.set(ZipkinData(sampled=True, trace_id=Mock())) store.set_rpc_name(Mock()) for annotation in annotations + binary_annotations: store.record(annotation) store.clear() self.assertListEqual([], store.get_annotations()) self.assertListEqual([], store.get_binary_annotations()) self.assertZipkinDataEquals(ZipkinData(), store.get()) self.assertIsNone(store.get_rpc_name())
def test_record_noop_if_not_sampled(self): self.store.get = lambda: ZipkinData(sampled=False) self.store._record_annotation = Mock() self.store._record_binary_annotation = Mock() self.store.record(Mock()) self.assertFalse(self.store._record_annotation.called) self.assertFalse(self.store._record_binary_annotation.called)
def test_annotates_responsecode(self): self.store.get.return_value = ZipkinData() self.middleware.process_response( self.request_factory.get('/', HTTP_X_B3_SAMPLED='true'), HttpResponse(status=420)) self.api.record_key_value.assert_has_calls( [call('http.statuscode', 420)])
def test_record_delegates_if_sampled(self): self.store.get = lambda: ZipkinData(sampled=True) annotation = Mock(spec=Annotation) binary_annotation = Mock(spec=BinaryAnnotation) self.store.record(annotation) self.store.record(binary_annotation) self.store._record_annotation.assert_called_once_with(annotation) self.store._record_binary_annotation.assert_called_once_with( binary_annotation)
def test_process_response_without_process_request(self): # This happens when a middleware before us returns a response in process_request self.store.get.return_value = ZipkinData() request = Mock() self.middleware.process_request = Mock() self.middleware.process_response(request, HttpResponse()) self.middleware.process_request.assert_called_once_with(request) self.middleware.api.record_event( constants.ANNOTATION_NO_DATA_IN_LOCAL_STORE)
def test_generates_ids_if_no_incoming(self): self.request_processor.get_zipkin_data.return_value = ZipkinData() self.middleware.process_request(Mock()) self.generator.generate_trace_id.assert_called_once_with() self.generator.generate_span_id.assert_called_once_with() data = self.store.set.call_args[0][0] self.assertEqual(data.span_id, self.generator.generate_span_id.return_value) self.assertEqual(data.trace_id, self.generator.generate_trace_id.return_value)
def test_logs_iff_sampled_or_flagged(self): for sampled in [True, False]: for flags in [True, False]: self.middleware.logger = Mock(spec=logging.Logger) self.middleware.store.get.return_value = ZipkinData( sampled=sampled, flags=flags) self.middleware.process_response(Mock(), HttpResponse()) if sampled or flags: self.middleware.logger.info.assert_called_once_with( self.api.build_log_message.return_value) else: self.assertListEqual( self.middleware.logger.info.mock_calls, [])
def test_annotations(self): annotations = [Mock(spec=Annotation), Mock(spec=Annotation)] binary_annotations = [ Mock(spec=BinaryAnnotation), Mock(spec=BinaryAnnotation) ] store = ThreadLocalDataStore() store.clear() store.set(ZipkinData(sampled=True)) for annotation in annotations + binary_annotations: store.record(annotation) self.assertListEqual(annotations, store.get_annotations()) self.assertListEqual(binary_annotations, store.get_binary_annotations())
def test_downstream_request_headers_without_parent_span_id(self): generator = SimpleIdGenerator() self.store.get.return_value = data = ZipkinData( trace_id=generator.generate_trace_id(), span_id=generator.generate_span_id(), sampled=True, flags=0) self.assertDictEqual( self.api.get_headers_for_downstream_request(), { 'X-B3-TraceId': data.trace_id.get_hex(), 'X-B3-SpanId': data.span_id.get_hex(), 'X-B3-Sampled': 'true', 'X-B3-Flags': '0' })
def test_nonascii_input(self): uri_in = u'\ufffd\ufffd/\x01' uri_out = uri_in.encode('utf-8') self.store.get.return_value = ZipkinData(trace_id=ZipkinId(42), span_id=ZipkinId(4242), parent_span_id=ZipkinId(1773), sampled=True) self.store.get_binary_annotations.return_value = [ self.api._build_binary_annotation('http.uri', uri_in) ] self.store.get_annotations.return_value = [ self.api._build_annotation(uri_in) ] self.store.get_rpc_name.return_value = 'test-rpc-name' self.api.build_log_message() # Assert no exception is raised self.assertEqual(self.api._build_span().annotations[0].value, uri_out) self.assertEqual(self.api._build_span().binary_annotations[0].value, uri_out)
def test_integration(self): self.api.endpoint.ipv4 = 2130706433 binary_annotations = [ self.api._build_binary_annotation('awesome', True) ] annotations = [ self.api._build_annotation('sr'), self.api._build_annotation('ss'), ] self.store.get_annotations.return_value = annotations self.store.get_binary_annotations.return_value = binary_annotations self.store.get.return_value = ZipkinData(trace_id=ZipkinId(42), span_id=ZipkinId(4242), parent_span_id=ZipkinId(1773), sampled=True) self.store.get_rpc_name.return_value = 'test-name' self.mock_time.time.return_value = 1024 self.assertEqual(self.api.build_log_message(), self.api.build_log_message()) self.assertEqual( self.api.build_log_message(), 'CgABAAAAAAAAACoLAAMAAAAJdGVzdC1uYW1lCgAEAAAAAAAAEJIKAAUAAAAAAAAG7Q8ABgwAAAACCgABAAAAAAAAAAELAAIAAAACc3IMAAMIAAF/AAABAAAKAAEAAAAAAAAAAQsAAgAAAAJzcwwAAwgAAX8AAAEAAA8ACAwAAAABCwABAAAAB2F3ZXNvbWULAAIAAAABMQgAAwAAAAAMAAQIAAF/AAABAAACAAkAAA==' )
def test_all_fields_filled(self): trace_id = ZipkinId.from_binary(42) span_id = ZipkinId.from_binary(-42) parent_span_id = ZipkinId.from_binary(53) request = self.request_factory.get( '/', **{ ZipkinDjangoRequestParser.trace_id_hdr_name: trace_id.get_hex(), ZipkinDjangoRequestParser.span_id_hdr_name: span_id.get_hex(), ZipkinDjangoRequestParser.parent_span_id_hdr_name: parent_span_id.get_hex(), ZipkinDjangoRequestParser.sampled_hdr_name: 'true', ZipkinDjangoRequestParser.flags_hdr_name: '0' }) self.assertZipkinDataEquals( self.processor.get_zipkin_data(request), ZipkinData(trace_id=trace_id, span_id=span_id, parent_span_id=parent_span_id, sampled=True, flags=False))
def test_get_without_set_returns_empty_zipkin_data(self): store = ThreadLocalDataStore() store.clear() self.assertZipkinDataEquals(ZipkinData(), store.get())
def test_dont_freak_out_if_thread_local_store_is_gone(self): store = ThreadLocalDataStore() ThreadLocalDataStore.thread_local_data = object() self.assertIsNone(store.get_rpc_name()) self.assertZipkinDataEquals(ZipkinData(), store.get())
def test_no_fields_filled(self): self.assertZipkinDataEquals( self.processor.get_zipkin_data(self.request_factory.get('/')), ZipkinData())
def test_downstream_request_headers_with_empty_data(self): self.store.get.return_value = ZipkinData() self.assertDictEqual(self.api.get_headers_for_downstream_request(), { 'X-B3-Sampled': 'false', 'X-B3-Flags': '0' })