def test_render(self): # render t = Template("Hello ${name}!") self.assertEqual(t.render(name="mako"), "Hello mako!") spans = self.pop_spans() self.assertEqual(len(spans), 1) assert_is_measured(spans[0]) self.assertEqual(spans[0].service, "mako") self.assertEqual(spans[0].span_type, "template") self.assertEqual(spans[0].get_tag("mako.template_name"), DEFAULT_TEMPLATE_NAME) self.assertEqual(spans[0].name, "mako.template.render") self.assertEqual(spans[0].resource, DEFAULT_TEMPLATE_NAME) # render_unicode t = Template("Hello ${name}!") self.assertEqual(t.render_unicode(name="mako"), to_unicode("Hello mako!")) spans = self.pop_spans() self.assertEqual(len(spans), 1) assert_is_measured(spans[0]) self.assertEqual(spans[0].service, "mako") self.assertEqual(spans[0].span_type, "template") self.assertEqual(spans[0].get_tag("mako.template_name"), DEFAULT_TEMPLATE_NAME) self.assertEqual(spans[0].name, "mako.template.render_unicode") self.assertEqual(spans[0].resource, DEFAULT_TEMPLATE_NAME) # render_context t = Template("Hello ${name}!") buf = StringIO() c = Context(buf, name="mako") t.render_context(c) self.assertEqual(buf.getvalue(), "Hello mako!") spans = self.pop_spans() self.assertEqual(len(spans), 1) assert_is_measured(spans[0]) self.assertEqual(spans[0].service, "mako") self.assertEqual(spans[0].span_type, "template") self.assertEqual(spans[0].get_tag("mako.template_name"), DEFAULT_TEMPLATE_NAME) self.assertEqual(spans[0].name, "mako.template.render_context") self.assertEqual(spans[0].resource, DEFAULT_TEMPLATE_NAME)
def test_sqs_send_message_trace_injection_with_message_attributes(self): sqs = self.session.create_client("sqs", region_name="us-east-1", endpoint_url="http://localhost:4566") queue = sqs.create_queue(QueueName="test") Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sqs) message_attributes = { "one": { "DataType": "String", "StringValue": "one" }, "two": { "DataType": "String", "StringValue": "two" }, "three": { "DataType": "String", "StringValue": "three" }, "four": { "DataType": "String", "StringValue": "four" }, "five": { "DataType": "String", "StringValue": "five" }, "six": { "DataType": "String", "StringValue": "six" }, "seven": { "DataType": "String", "StringValue": "seven" }, "eight": { "DataType": "String", "StringValue": "eight" }, "nine": { "DataType": "String", "StringValue": "nine" }, } sqs.send_message(QueueUrl=queue["QueueUrl"], MessageBody="world", MessageAttributes=message_attributes) spans = self.get_spans() assert spans span = spans[0] self.assertEqual(len(spans), 1) self.assertEqual(span.get_tag("aws.region"), "us-east-1") self.assertEqual(span.get_tag("aws.operation"), "SendMessage") assert_is_measured(span) assert_span_http_status_code(span, 200) self.assertEqual(span.service, "test-botocore-tracing.sqs") self.assertEqual(span.resource, "sqs.sendmessage") trace_json = span.get_tag( "params.MessageAttributes._datadog.StringValue") trace_data_injected = json.loads(trace_json) self.assertEqual(trace_data_injected[HTTP_HEADER_TRACE_ID], str(span.trace_id)) self.assertEqual(trace_data_injected[HTTP_HEADER_PARENT_ID], str(span.span_id)) response = sqs.receive_message(QueueUrl=queue["QueueUrl"], MessageAttributeNames=["_datadog"]) self.assertEqual(len(response["Messages"]), 1) trace_json_message = response["Messages"][0]["MessageAttributes"][ "_datadog"]["StringValue"] trace_data_in_message = json.loads(trace_json_message) self.assertEqual(trace_data_in_message[HTTP_HEADER_TRACE_ID], str(span.trace_id)) self.assertEqual(trace_data_in_message[HTTP_HEADER_PARENT_ID], str(span.span_id)) sqs.delete_queue(QueueUrl=queue["QueueUrl"])
def test_request_error_handler(self): """ When making a request When the requested endpoint raises an exception We create the expected spans """ @self.app.errorhandler(500) def error_handler(e): return "Whoops", 500 @self.app.route("/500") def fivehundred(): raise Exception("500 error") res = self.client.get("/500") self.assertEqual(res.status_code, 500) self.assertEqual(res.data, b"Whoops") spans = self.get_spans() if flask_version >= (0, 12): self.assertEqual(len(spans), 11) # Assert the order of the spans created self.assertListEqual( [ "flask.request", "flask.try_trigger_before_first_request_functions", "flask.preprocess_request", "flask.dispatch_request", "tests.contrib.flask.test_request.fivehundred", "flask.handle_user_exception", "flask.handle_exception", "tests.contrib.flask.test_request.error_handler", "flask.process_response", "flask.do_teardown_request", "flask.do_teardown_appcontext", ], [s.name for s in spans], ) else: self.assertEqual(len(spans), 10) # Assert the order of the spans created self.assertListEqual( [ "flask.request", "flask.try_trigger_before_first_request_functions", "flask.preprocess_request", "flask.dispatch_request", "tests.contrib.flask.test_request.fivehundred", "flask.handle_user_exception", "flask.handle_exception", "tests.contrib.flask.test_request.error_handler", "flask.do_teardown_request", "flask.do_teardown_appcontext", ], [s.name for s in spans], ) # Assert span services for span in spans: self.assertEqual(span.service, "flask") # Root request span req_span = spans[0] assert_is_measured(req_span) self.assertEqual(req_span.service, "flask") self.assertEqual(req_span.name, "flask.request") self.assertEqual(req_span.resource, "GET /500") self.assertEqual(req_span.span_type, "web") self.assertEqual(req_span.error, 1) self.assertIsNone(req_span.parent_id) # Request tags self.assertEqual(req_span.get_tag("http.method"), "GET") self.assertEqual(req_span.get_tag(http.URL), "http://localhost/500") assert_span_http_status_code(req_span, 500) self.assertEqual(req_span.get_tag("flask.endpoint"), "fivehundred") self.assertEqual(req_span.get_tag("flask.url_rule"), "/500") # Dispatch span dispatch_span = spans[3] self.assertEqual(dispatch_span.service, "flask") self.assertEqual(dispatch_span.name, "flask.dispatch_request") self.assertEqual(dispatch_span.resource, "flask.dispatch_request") self.assertEqual(dispatch_span.error, 1) self.assertTrue( dispatch_span.get_tag("error.msg").startswith("500 error")) self.assertTrue( dispatch_span.get_tag("error.stack").startswith("Traceback")) self.assertEqual(dispatch_span.get_tag("error.type"), base_exception_name) # Handler span handler_span = spans[4] self.assertEqual(handler_span.service, "flask") self.assertEqual(handler_span.name, "tests.contrib.flask.test_request.fivehundred") self.assertEqual(handler_span.resource, "/500") self.assertEqual(handler_span.error, 1) self.assertTrue( handler_span.get_tag("error.msg").startswith("500 error")) self.assertTrue( handler_span.get_tag("error.stack").startswith("Traceback")) self.assertEqual(handler_span.get_tag("error.type"), base_exception_name) # User exception span user_ex_span = spans[5] self.assertEqual(user_ex_span.service, "flask") self.assertEqual(user_ex_span.name, "flask.handle_user_exception") self.assertEqual(user_ex_span.resource, "flask.handle_user_exception") self.assertEqual(user_ex_span.error, 1) self.assertTrue( user_ex_span.get_tag("error.msg").startswith("500 error")) self.assertTrue( user_ex_span.get_tag("error.stack").startswith("Traceback")) self.assertEqual(user_ex_span.get_tag("error.type"), base_exception_name)
def test_request_501(self): """ When making a request When the requested endpoint calls `abort(501)` We create the expected spans """ @self.app.route("/501") def fivehundredone(): abort(501) res = self.client.get("/501") self.assertEqual(res.status_code, 501) spans = self.get_spans() self.assertEqual(len(spans), 10) # Assert the order of the spans created self.assertListEqual( [ "flask.request", "flask.try_trigger_before_first_request_functions", "flask.preprocess_request", "flask.dispatch_request", "tests.contrib.flask.test_request.fivehundredone", "flask.handle_user_exception", "flask.handle_http_exception", "flask.process_response", "flask.do_teardown_request", "flask.do_teardown_appcontext", ], [s.name for s in spans], ) # Assert span services for span in spans: self.assertEqual(span.service, "flask") # Root request span req_span = spans[0] assert_is_measured(req_span) self.assertEqual(req_span.service, "flask") self.assertEqual(req_span.name, "flask.request") self.assertEqual(req_span.resource, "GET /501") self.assertEqual(req_span.span_type, "web") self.assertEqual(req_span.error, 1) self.assertIsNone(req_span.parent_id) # Request tags self.assertEqual(req_span.get_tag("http.method"), "GET") self.assertEqual(req_span.get_tag(http.URL), "http://localhost/501") assert_span_http_status_code(req_span, 501) self.assertEqual(req_span.get_tag("flask.endpoint"), "fivehundredone") self.assertEqual(req_span.get_tag("flask.url_rule"), "/501") # Dispatch span dispatch_span = spans[3] self.assertEqual(dispatch_span.service, "flask") self.assertEqual(dispatch_span.name, "flask.dispatch_request") self.assertEqual(dispatch_span.resource, "flask.dispatch_request") self.assertEqual(dispatch_span.error, 1) self.assertTrue( dispatch_span.get_tag("error.msg").startswith( "501 Not Implemented")) self.assertTrue( dispatch_span.get_tag("error.stack").startswith("Traceback")) self.assertEqual(dispatch_span.get_tag("error.type"), "werkzeug.exceptions.NotImplemented") # Handler span handler_span = spans[4] self.assertEqual(handler_span.service, "flask") self.assertEqual(handler_span.name, "tests.contrib.flask.test_request.fivehundredone") self.assertEqual(handler_span.resource, "/501") self.assertEqual(handler_span.error, 1) self.assertTrue( handler_span.get_tag("error.msg").startswith( "501 Not Implemented")) self.assertTrue( handler_span.get_tag("error.stack").startswith("Traceback")) self.assertEqual(handler_span.get_tag("error.type"), "werkzeug.exceptions.NotImplemented") # User exception span user_ex_span = spans[5] self.assertEqual(user_ex_span.service, "flask") self.assertEqual(user_ex_span.name, "flask.handle_user_exception") self.assertEqual(user_ex_span.resource, "flask.handle_user_exception") self.assertEqual(user_ex_span.error, 0)
def test_request_query_string(self): """ When making a request When the request contains a query string We create the expected spans """ @self.app.route("/") def index(): return "Hello Flask", 200 res = self.client.get("/", query_string=dict(hello="flask")) self.assertEqual(res.status_code, 200) self.assertEqual(res.data, b"Hello Flask") spans = self.get_spans() self.assertEqual(len(spans), 8) # Assert the order of the spans created self.assertListEqual( [ "flask.request", "flask.try_trigger_before_first_request_functions", "flask.preprocess_request", "flask.dispatch_request", "tests.contrib.flask.test_request.index", "flask.process_response", "flask.do_teardown_request", "flask.do_teardown_appcontext", ], [s.name for s in spans], ) # Assert span services for span in spans: self.assertEqual(span.service, "flask") # Root request span req_span = spans[0] assert_is_measured(req_span) self.assertEqual(req_span.service, "flask") self.assertEqual(req_span.name, "flask.request") # Note: contains no query string self.assertEqual(req_span.resource, "GET /") self.assertEqual(req_span.span_type, "web") self.assertEqual(req_span.error, 0) self.assertIsNone(req_span.parent_id) # Request tags self.assertEqual(req_span.get_tag("flask.endpoint"), "index") # Note: contains no query string self.assertEqual(req_span.get_tag("flask.url_rule"), "/") self.assertEqual(req_span.get_tag("http.method"), "GET") # Note: contains no query string self.assertEqual(req_span.get_tag(http.URL), "http://localhost/") assert_span_http_status_code(req_span, 200) # Handler span handler_span = spans[4] self.assertEqual(handler_span.service, "flask") self.assertEqual(handler_span.name, "tests.contrib.flask.test_request.index") # Note: contains no query string self.assertEqual(handler_span.resource, "/") self.assertEqual(req_span.error, 0)
def assert_conn_is_traced(self, db, service): # ensure the trace pscyopg client doesn't add non-standard # methods try: db.execute("""select 'foobar'""") except AttributeError: pass # Ensure we can run a query and it's correctly traced q = """select 'foobarblah'""" start = time.time() cursor = db.cursor() res = cursor.execute(q) self.assertIsNone(res) rows = cursor.fetchall() end = time.time() self.assertEquals(rows, [("foobarblah", )]) self.assert_structure( dict(name="postgres.query", resource=q, service=service, error=0, span_type="sql"), ) root = self.get_root_span() self.assertIsNone(root.get_tag("sql.query")) assert start <= root.start <= end assert root.duration <= end - start # confirm analytics disabled by default self.reset() # run a query with an error and ensure all is well q = """select * from some_non_existant_table""" cur = db.cursor() try: cur.execute(q) except Exception: pass else: assert 0, "should have an error" self.assert_structure( dict( name="postgres.query", resource=q, service=service, error=1, span_type="sql", meta={ "out.host": "127.0.0.1", }, metrics={ "out.port": TEST_PORT, }, ), ) root = self.get_root_span() assert_is_measured(root) self.assertIsNone(root.get_tag("sql.query")) self.reset()
def test_request(self): """ When using ddtrace-run When making a request to flask app We generate the expected spans """ @self.app.route("/") def index(): return "Hello Flask", 200 res = self.client.get("/") self.assertEqual(res.status_code, 200) self.assertEqual(res.data, b"Hello Flask") spans = self.pop_spans() self.assertEqual(len(spans), 8) self.assertListEqual( [ "flask.request", "flask.try_trigger_before_first_request_functions", "flask.preprocess_request", "flask.dispatch_request", "tests.contrib.flask_autopatch.test_flask_autopatch.index", "flask.process_response", "flask.do_teardown_request", "flask.do_teardown_appcontext", ], [s.name for s in spans], ) # Assert span services for span in spans: self.assertEqual(span.service, "test-flask") # Root request span req_span = spans[0] assert_is_measured(req_span) self.assertEqual(req_span.service, "test-flask") self.assertEqual(req_span.name, "flask.request") self.assertEqual(req_span.resource, "GET /") self.assertEqual(req_span.span_type, "web") self.assertEqual(req_span.error, 0) self.assertIsNone(req_span.parent_id) # Request tags for tag in [ "flask.version", "http.url", "http.method", "http.status_code", "flask.endpoint", "flask.url_rule" ]: assert tag in req_span.meta self.assertEqual(req_span.get_tag("flask.endpoint"), "index") self.assertEqual(req_span.get_tag("flask.url_rule"), "/") self.assertEqual(req_span.get_tag("http.method"), "GET") self.assertEqual(req_span.get_tag(http.URL), "http://localhost/") assert_span_http_status_code(req_span, 200) # Handler span handler_span = spans[4] self.assertEqual(handler_span.service, "test-flask") self.assertEqual( handler_span.name, "tests.contrib.flask_autopatch.test_flask_autopatch.index") self.assertEqual(handler_span.resource, "/") self.assertEqual(req_span.error, 0)
def test_insert_find(self): tracer, client = self.get_tracer_and_client() start = time.time() db = client.testdb db.drop_collection('teams') teams = [{ 'name': 'Toronto Maple Leafs', 'established': 1917, }, { 'name': 'Montreal Canadiens', 'established': 1910, }, { 'name': 'New York Rangers', 'established': 1926, }] # create some data (exercising both ways of inserting) db.teams.insert_one(teams[0]) db.teams.insert_many(teams[1:]) # wildcard query (using the [] syntax) cursor = db['teams'].find() count = 0 for row in cursor: count += 1 assert count == len(teams) # scoped query (using the getattr syntax) q = {'name': 'Toronto Maple Leafs'} queried = list(db.teams.find(q)) end = time.time() assert len(queried) == 1 assert queried[0]['name'] == 'Toronto Maple Leafs' assert queried[0]['established'] == 1917 spans = tracer.pop() for span in spans: # ensure all the of the common metadata is set assert_is_measured(span) assert span.service == self.TEST_SERVICE assert span.span_type == 'mongodb' assert span.meta.get('mongodb.collection') == 'teams' assert span.meta.get('mongodb.db') == 'testdb' assert span.meta.get('out.host'), span.pprint() assert span.metrics.get('out.port'), span.pprint() assert span.start > start assert span.duration < end - start expected_resources = [ 'drop teams', 'insert teams', 'insert teams', ] # query names should be used in >3.1 name = 'find' if pymongo.version_tuple >= (3, 1, 0) else 'query' expected_resources.extend([ '{} teams'.format(name), '{} teams {{"name": "?"}}'.format(name), ]) assert expected_resources == list(s.resource for s in spans) # confirm query tag for find all assert spans[-2].get_tag('mongodb.query') is None # confirm query tag find with query criteria on name assert spans[-1].get_tag('mongodb.query') == '{\'name\': \'?\'}'
def assert_conn_is_traced(self, tracer, db, service): # ensure the trace aiopg client doesn't add non-standard # methods try: yield from db.execute('select \'foobar\'') except AttributeError: pass # Ensure we can run a query and it's correctly traced q = 'select \'foobarblah\'' start = time.time() cursor = yield from db.cursor() yield from cursor.execute(q) rows = yield from cursor.fetchall() end = time.time() assert rows == [('foobarblah', )] assert rows spans = self.pop_spans() assert spans assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.name == 'postgres.query' assert span.resource == q assert span.service == service assert span.meta['sql.query'] == q assert span.error == 0 assert span.span_type == 'sql' assert start <= span.start <= end assert span.duration <= end - start # Ensure OpenTracing compatibility ot_tracer = init_tracer('aiopg_svc', tracer) with ot_tracer.start_active_span('aiopg_op'): cursor = yield from db.cursor() yield from cursor.execute(q) rows = yield from cursor.fetchall() assert rows == [('foobarblah', )] spans = self.pop_spans() assert len(spans) == 2 ot_span, dd_span = spans # confirm the parenting assert ot_span.parent_id is None assert dd_span.parent_id == ot_span.span_id assert ot_span.name == 'aiopg_op' assert ot_span.service == 'aiopg_svc' assert dd_span.name == 'postgres.query' assert dd_span.resource == q assert dd_span.service == service assert dd_span.meta['sql.query'] == q assert dd_span.error == 0 assert dd_span.span_type == 'sql' # run a query with an error and ensure all is well q = 'select * from some_non_existant_table' cur = yield from db.cursor() try: yield from cur.execute(q) except Exception: pass else: assert 0, 'should have an error' spans = self.pop_spans() assert spans, spans assert len(spans) == 1 span = spans[0] assert span.name == 'postgres.query' assert span.resource == q assert span.service == service assert span.meta['sql.query'] == q assert span.error == 1 # assert span.meta['out.host'] == 'localhost' assert span.metrics['out.port'] == TEST_PORT assert span.span_type == 'sql'
def test_update_ot(self): """OpenTracing version of test_update.""" tracer, client = self.get_tracer_and_client() ot_tracer = init_tracer("mongo_svc", tracer) with ot_tracer.start_active_span("mongo_op"): db = client["testdb"] db.drop_collection("songs") input_songs = [ { "name": "Powderfinger", "artist": "Neil" }, { "name": "Harvest", "artist": "Neil" }, { "name": "Suzanne", "artist": "Leonard" }, { "name": "Partisan", "artist": "Leonard" }, ] db.songs.insert_many(input_songs) result = db.songs.update_many( {"artist": "Neil"}, {"$set": { "artist": "Shakey" }}, ) assert result.matched_count == 2 assert result.modified_count == 2 # ensure all is traced. spans = tracer.pop() assert spans, spans assert len(spans) == 4 ot_span = spans[0] assert ot_span.parent_id is None assert ot_span.name == "mongo_op" assert ot_span.service == "mongo_svc" for span in spans[1:]: # ensure the parenting assert span.parent_id == ot_span.span_id # ensure all the of the common metadata is set assert_is_measured(span) assert span.service == self.TEST_SERVICE assert span.span_type == "mongodb" assert span.meta.get("mongodb.collection") == "songs" assert span.meta.get("mongodb.db") == "testdb" assert span.meta.get("out.host") assert span.metrics.get("out.port") expected_resources = set([ "drop songs", 'update songs {"artist": "?"}', "insert songs", ]) assert expected_resources == {s.resource for s in spans[1:]}
def test_insert_find(self): tracer, client = self.get_tracer_and_client() start = time.time() db = client.testdb db.drop_collection("teams") teams = [ { "name": "Toronto Maple Leafs", "established": 1917, }, { "name": "Montreal Canadiens", "established": 1910, }, { "name": "New York Rangers", "established": 1926, }, ] # create some data (exercising both ways of inserting) db.teams.insert_one(teams[0]) db.teams.insert_many(teams[1:]) # wildcard query (using the [] syntax) cursor = db["teams"].find() count = 0 for row in cursor: count += 1 assert count == len(teams) # scoped query (using the getattr syntax) q = {"name": "Toronto Maple Leafs"} queried = list(db.teams.find(q)) end = time.time() assert len(queried) == 1 assert queried[0]["name"] == "Toronto Maple Leafs" assert queried[0]["established"] == 1917 spans = tracer.pop() for span in spans: # ensure all the of the common metadata is set assert_is_measured(span) assert span.service == self.TEST_SERVICE assert span.span_type == "mongodb" assert span.meta.get("mongodb.collection") == "teams" assert span.meta.get("mongodb.db") == "testdb" assert span.meta.get("out.host"), span.pprint() assert span.metrics.get("out.port"), span.pprint() assert span.start > start assert span.duration < end - start expected_resources = [ "drop teams", "insert teams", "insert teams", ] # query names should be used in >3.1 name = "find" if pymongo.version_tuple >= (3, 1, 0) else "query" expected_resources.extend([ "{} teams".format(name), '{} teams {{"name": "?"}}'.format(name), ]) assert expected_resources == list(s.resource for s in spans) # confirm query tag for find all assert spans[-2].get_tag("mongodb.query") is None # confirm query tag find with query criteria on name assert spans[-1].get_tag("mongodb.query") == "{'name': '?'}"
def test_delete(self): # ensure we trace deletes tracer, client = self.get_tracer_and_client() db = client["testdb"] collection_name = "here.are.songs" db.drop_collection(collection_name) input_songs = [ { "name": "Powderfinger", "artist": "Neil" }, { "name": "Harvest", "artist": "Neil" }, { "name": "Suzanne", "artist": "Leonard" }, { "name": "Partisan", "artist": "Leonard" }, ] songs = db[collection_name] songs.insert_many(input_songs) # test delete one af = {"artist": "Neil"} assert songs.count(af) == 2 songs.delete_one(af) assert songs.count(af) == 1 # test delete many af = {"artist": "Leonard"} assert songs.count(af) == 2 songs.delete_many(af) assert songs.count(af) == 0 # ensure all is traced. spans = tracer.pop() assert spans, spans for span in spans: # ensure all the of the common metadata is set assert_is_measured(span) assert span.service == self.TEST_SERVICE assert span.span_type == "mongodb" assert span.meta.get("mongodb.collection") == collection_name assert span.meta.get("mongodb.db") == "testdb" assert span.meta.get("out.host") assert span.metrics.get("out.port") expected_resources = [ "drop here.are.songs", "count here.are.songs", "count here.are.songs", "count here.are.songs", "count here.are.songs", 'delete here.are.songs {"artist": "?"}', 'delete here.are.songs {"artist": "?"}', "insert here.are.songs", ] assert sorted(expected_resources) == sorted(s.resource for s in spans)
def test_set_tag_measured_no_value(): s = Span(tracer=None, name="test.span") s.set_tag(SPAN_MEASURED_KEY) assert_is_measured(s)
def test_update_ot(self): """OpenTracing version of test_update.""" tracer, client = self.get_tracer_and_client() ot_tracer = init_tracer('mongo_svc', tracer) with ot_tracer.start_active_span('mongo_op'): db = client['testdb'] db.drop_collection('songs') input_songs = [ { 'name': 'Powderfinger', 'artist': 'Neil' }, { 'name': 'Harvest', 'artist': 'Neil' }, { 'name': 'Suzanne', 'artist': 'Leonard' }, { 'name': 'Partisan', 'artist': 'Leonard' }, ] db.songs.insert_many(input_songs) result = db.songs.update_many( {'artist': 'Neil'}, {'$set': { 'artist': 'Shakey' }}, ) assert result.matched_count == 2 assert result.modified_count == 2 # ensure all is traced. spans = tracer.pop() assert spans, spans assert len(spans) == 4 ot_span = spans[0] assert ot_span.parent_id is None assert ot_span.name == 'mongo_op' assert ot_span.service == 'mongo_svc' for span in spans[1:]: # ensure the parenting assert span.parent_id == ot_span.span_id # ensure all the of the common metadata is set assert_is_measured(span) assert span.service == self.TEST_SERVICE assert span.span_type == 'mongodb' assert span.meta.get('mongodb.collection') == 'songs' assert span.meta.get('mongodb.db') == 'testdb' assert span.meta.get('out.host') assert span.metrics.get('out.port') expected_resources = set([ 'drop songs', 'update songs {"artist": "?"}', 'insert songs', ]) assert expected_resources == {s.resource for s in spans[1:]}
def test_sqs_send_message_batch_trace_injection_with_max_message_attributes( self): sqs = self.session.create_client("sqs", region_name="us-east-1", endpoint_url="http://localhost:4566") queue = sqs.create_queue(QueueName="test") Pin(service=self.TEST_SERVICE, tracer=self.tracer).onto(sqs) entries = [{ "Id": "1", "MessageBody": "ironmaiden", "MessageAttributes": { "one": { "DataType": "String", "StringValue": "one" }, "two": { "DataType": "String", "StringValue": "two" }, "three": { "DataType": "String", "StringValue": "three" }, "four": { "DataType": "String", "StringValue": "four" }, "five": { "DataType": "String", "StringValue": "five" }, "six": { "DataType": "String", "StringValue": "six" }, "seven": { "DataType": "String", "StringValue": "seven" }, "eight": { "DataType": "String", "StringValue": "eight" }, "nine": { "DataType": "String", "StringValue": "nine" }, "ten": { "DataType": "String", "StringValue": "ten" }, }, }] sqs.send_message_batch(QueueUrl=queue["QueueUrl"], Entries=entries) spans = self.get_spans() assert spans span = spans[0] self.assertEqual(len(spans), 1) self.assertEqual(span.get_tag("aws.region"), "us-east-1") self.assertEqual(span.get_tag("aws.operation"), "SendMessageBatch") assert_is_measured(span) assert_span_http_status_code(span, 200) self.assertEqual(span.service, "test-botocore-tracing.sqs") self.assertEqual(span.resource, "sqs.sendmessagebatch") response = sqs.receive_message(QueueUrl=queue["QueueUrl"], MessageAttributeNames=["_datadog"]) self.assertEqual(len(response["Messages"]), 1) trace_in_message = "MessageAttributes" in response["Messages"][0] self.assertEqual(trace_in_message, False) sqs.delete_queue(QueueUrl=queue["QueueUrl"])
def test_insert_update_delete_query(self): tracer = self.get_tracer_and_connect() start = time.time() Artist.drop_collection() end = time.time() # ensure we get a drop collection span spans = tracer.pop() assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.resource == "drop artist" assert span.span_type == "mongodb" assert span.service == self.TEST_SERVICE _assert_timing(span, start, end) start = end joni = Artist() joni.first_name = "Joni" joni.last_name = "Mitchell" joni.save() end = time.time() # ensure we get an insert span spans = tracer.pop() assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.resource == "insert artist" assert span.span_type == "mongodb" assert span.service == self.TEST_SERVICE _assert_timing(span, start, end) # ensure full scans work start = time.time() artists = [a for a in Artist.objects] end = time.time() assert len(artists) == 1 assert artists[0].first_name == "Joni" assert artists[0].last_name == "Mitchell" # query names should be used in pymongo>3.1 name = "find" if pymongo.version_tuple >= (3, 1, 0) else "query" spans = tracer.pop() assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.resource == "{} artist".format(name) assert span.span_type == "mongodb" assert span.service == self.TEST_SERVICE _assert_timing(span, start, end) # ensure filtered queries work start = time.time() artists = [a for a in Artist.objects(first_name="Joni")] end = time.time() assert len(artists) == 1 joni = artists[0] assert artists[0].first_name == "Joni" assert artists[0].last_name == "Mitchell" spans = tracer.pop() assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.resource == '{} artist {{"first_name": "?"}}'.format(name) assert span.span_type == "mongodb" assert span.service == self.TEST_SERVICE _assert_timing(span, start, end) # ensure updates work start = time.time() joni.last_name = "From Saskatoon" joni.save() end = time.time() spans = tracer.pop() assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.resource == 'update artist {"_id": "?"}' assert span.span_type == "mongodb" assert span.service == self.TEST_SERVICE _assert_timing(span, start, end) # ensure deletes start = time.time() joni.delete() end = time.time() spans = tracer.pop() assert len(spans) == 1 span = spans[0] assert_is_measured(span) assert span.resource == 'delete artist {"_id": "?"}' assert span.span_type == "mongodb" assert span.service == self.TEST_SERVICE _assert_timing(span, start, end)
def test_delete(self): # ensure we trace deletes tracer, client = self.get_tracer_and_client() db = client['testdb'] collection_name = 'here.are.songs' db.drop_collection(collection_name) input_songs = [ { 'name': 'Powderfinger', 'artist': 'Neil' }, { 'name': 'Harvest', 'artist': 'Neil' }, { 'name': 'Suzanne', 'artist': 'Leonard' }, { 'name': 'Partisan', 'artist': 'Leonard' }, ] songs = db[collection_name] songs.insert_many(input_songs) # test delete one af = {'artist': 'Neil'} assert songs.count(af) == 2 songs.delete_one(af) assert songs.count(af) == 1 # test delete many af = {'artist': 'Leonard'} assert songs.count(af) == 2 songs.delete_many(af) assert songs.count(af) == 0 # ensure all is traced. spans = tracer.pop() assert spans, spans for span in spans: # ensure all the of the common metadata is set assert_is_measured(span) assert span.service == self.TEST_SERVICE assert span.span_type == 'mongodb' assert span.meta.get('mongodb.collection') == collection_name assert span.meta.get('mongodb.db') == 'testdb' assert span.meta.get('out.host') assert span.metrics.get('out.port') expected_resources = [ 'drop here.are.songs', 'count here.are.songs', 'count here.are.songs', 'count here.are.songs', 'count here.are.songs', 'delete here.are.songs {"artist": "?"}', 'delete here.are.songs {"artist": "?"}', 'insert here.are.songs', ] assert sorted(expected_resources) == sorted(s.resource for s in spans)