def test_uninstrument(self): URLLibInstrumentor().uninstrument() result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") self.assert_span(num_spans=0) # instrument again to avoid annoying warning message URLLibInstrumentor().instrument()
def test_requests_exception_with_response(self, *_, **__): with self.assertRaises(HTTPError): self.perform_request("http://httpbin.org/status/500") span = self.assert_span() self.assertEqual( dict(span.attributes), { "http.method": "GET", "http.url": "http://httpbin.org/status/500", "http.status_code": 500, "http.status_text": "Internal Server Error", }, ) self.assertEqual(span.status.status_code, StatusCode.ERROR) self.assertIsNotNone(URLLibInstrumentor().meter) self.assertEqual(len(URLLibInstrumentor().meter.instruments), 1) recorder = list(URLLibInstrumentor().meter.instruments.values())[0] match_key = get_dict_as_key({ "http.method": "GET", "http.status_code": "500", "http.url": "http://httpbin.org/status/500", "http.flavor": "1.1", }) for key in recorder.bound_instruments.keys(): self.assertEqual(key, match_key) # pylint: disable=protected-access bound = recorder.bound_instruments.get(key) for view_data in bound.view_datas: self.assertEqual(view_data.labels, key) self.assertEqual(view_data.aggregator.current.count, 1)
def test_span_callback(self): URLLibInstrumentor().uninstrument() def span_callback(span, result: HTTPResponse): span.set_attribute("http.response.body", result.read()) URLLibInstrumentor().instrument( tracer_provider=self.tracer_provider, span_callback=span_callback, ) result = self.perform_request(self.URL) self.assertEqual(result.read(), b"") span = self.assert_span() self.assertEqual( span.attributes, { "http.method": "GET", "http.url": self.URL, "http.status_code": 200, "http.status_text": "OK", "http.response.body": "Hello!", }, )
def test_span_callback(self): URLLibInstrumentor().uninstrument() def span_callback(span, result: HTTPResponse): span.set_attribute("http.response.body", result.read()) URLLibInstrumentor().instrument( tracer_provider=self.tracer_provider, span_callback=span_callback, ) result = self.perform_request(self.URL) self.assertEqual(result.read(), b"") span = self.assert_span() self.assertEqual( span.attributes, { SpanAttributes.HTTP_METHOD: "GET", SpanAttributes.HTTP_URL: self.URL, SpanAttributes.HTTP_STATUS_CODE: 200, "http.response.body": "Hello!", }, )
def test_name_callback_default(self): def name_callback(method, url): return 123 URLLibInstrumentor().uninstrument() URLLibInstrumentor().instrument(name_callback=name_callback) result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") span = self.assert_span() self.assertEqual(span.name, "HTTP GET")
def test_custom_tracer_provider(self): resource = resources.Resource.create({}) result = self.create_tracer_provider(resource=resource) tracer_provider, exporter = result URLLibInstrumentor().uninstrument() URLLibInstrumentor().instrument(tracer_provider=tracer_provider) result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") span = self.assert_span(exporter=exporter) self.assertIs(span.resource, resource)
def test_not_recording(self): with mock.patch("opentelemetry.trace.INVALID_SPAN") as mock_span: URLLibInstrumentor().uninstrument() URLLibInstrumentor().instrument( tracer_provider=trace._DefaultTracerProvider()) mock_span.is_recording.return_value = False result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") self.assert_span(None, 0) self.assertFalse(mock_span.is_recording()) self.assertTrue(mock_span.is_recording.called) self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called)
def test_not_recording(self): with mock.patch("opentelemetry.trace.INVALID_SPAN") as mock_span: URLLibInstrumentor().uninstrument() # original_tracer_provider returns a default tracer provider, which # in turn will return an INVALID_SPAN, which is always not recording URLLibInstrumentor().instrument( tracer_provider=self.original_tracer_provider) mock_span.is_recording.return_value = False result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") self.assert_span(None, 0) self.assertFalse(mock_span.is_recording()) self.assertTrue(mock_span.is_recording.called) self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called)
def test_basic(self): result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") span = self.assert_span() self.assertIs(span.kind, trace.SpanKind.CLIENT) self.assertEqual(span.name, "HTTP GET") self.assertEqual( span.attributes, { "http.method": "GET", "http.url": self.URL, "http.status_code": 200, "http.status_text": "OK", }, ) self.assertIs(span.status.status_code, trace.status.StatusCode.UNSET) self.check_span_instrumentation_info( span, opentelemetry.instrumentation.urllib) self.assertIsNotNone(URLLibInstrumentor().meter) self.assertEqual(len(URLLibInstrumentor().meter.instruments), 1) recorder = list(URLLibInstrumentor().meter.instruments.values())[0] match_key = get_dict_as_key({ "http.flavor": "1.1", "http.method": "GET", "http.status_code": "200", "http.url": "http://httpbin.org/status/200", }) for key in recorder.bound_instruments.keys(): self.assertEqual(key, match_key) # pylint: disable=protected-access bound = recorder.bound_instruments.get(key) for view_data in bound.view_datas: self.assertEqual(view_data.labels, key) self.assertEqual(view_data.aggregator.current.count, 1) self.assertGreaterEqual(view_data.aggregator.current.sum, 0)
def test_hooks(self): def request_hook(span, request_obj): span.update_name("name set from hook") def response_hook(span, request_obj, response): span.set_attribute("response_hook_attr", "value") URLLibInstrumentor().uninstrument() URLLibInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook) result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") span = self.assert_span() self.assertEqual(span.name, "name set from hook") self.assertIn("response_hook_attr", span.attributes) self.assertEqual(span.attributes["response_hook_attr"], "value")
def setUp(self): super().setUp() URLLibInstrumentor().instrument() httpretty.enable() httpretty.register_uri(httpretty.GET, self.URL, body=b"Hello!") httpretty.register_uri( httpretty.GET, self.URL_TIMEOUT, body=self.timeout_exception_callback, ) httpretty.register_uri( httpretty.GET, self.URL_EXCEPTION, body=self.base_exception_callback, ) httpretty.register_uri( httpretty.GET, "http://httpbin.org/status/500", status=500, )
def test_uninstrument_session(self): clienr1 = urllib.request.build_opener() URLLibInstrumentor().uninstrument_opener(clienr1) result = self.perform_request(self.URL, clienr1) self.assertEqual(result.read(), b"Hello!") self.assert_span(num_spans=0) # Test that other sessions as well as global requests is still # instrumented opener2 = urllib.request.build_opener() result = self.perform_request(self.URL, opener2) self.assertEqual(result.read(), b"Hello!") self.assert_span() self.memory_exporter.clear() result = self.perform_request(self.URL) self.assertEqual(result.read(), b"Hello!") self.assert_span()
def tearDown(self): super().tearDown() URLLibInstrumentor().uninstrument() httpretty.disable()