def test_context_fn_isolation(self): engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind = engine2) class B(Base): __tablename__ = "b" id = Column("id", Integer, primary_key = True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) sqltap.start(self.engine, lambda *args: 1) sqltap.start(engine2, lambda *args: 2) sess = self.Session() sess.query(self.A).all() sess2 = Session() sess2.query(B).all() stats = sqltap.collect() ctxs = [qstats.user_context for qstats in _startswith(stats, 'SELECT')] assert ctxs.count(1) == 1 assert ctxs.count(2) == 1
def test_engine_global(self): """ Test that registering globally for all queries correctly pulls queries from multiple engines. This test passes, but because SQLAlchemy won't ever let us unregister our event handlers, this causes side-effects in other tests that will break them. """ return engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind = engine2) class B(Base): __tablename__ = "b" id = Column("id", Integer, primary_key = True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) sqltap.start() sess = self.Session() sess.query(self.A).all() sess2 = Session() sess2.query(B).all() stats = _startswith(sqltap.collect(), 'SELECT') assert len(stats) == 2
def test_engine_scoped(self): """ Test that calling sqltap.start with a particular engine instance properly captures queries only to that engine. """ engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind = engine2) class B(Base): __tablename__ = "b" id = Column("id", Integer, primary_key = True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) sqltap.start(engine2) sess = self.Session() sess.query(self.A).all() sess2 = Session() sess2.query(B).all() stats = _startswith(sqltap.collect(), 'SELECT') assert len(stats) == 1
def test_stop(self): """ Ensure queries after you call sqltap.stop() are not recorded. """ sqltap.start(self.engine) sess = self.Session() sess.query(self.A).all() sqltap.stop(self.engine) sess.query(self.A).all() assert len(sqltap.collect()) == 1
def test_select(self): """ Simple test that sqltap collects a select query. """ sqltap.start(self.engine) sess = self.Session() sess.query(self.A).all() stats = sqltap.collect() assert len(_startswith(stats, 'SELECT')) == 1
def test_insert(self): """ Simple test that sqltap collects an insert query. """ sqltap.start(self.engine) sess = self.Session() sess.add(self.A()) sess.flush() stats = sqltap.collect() assert len(_startswith(stats, 'INSERT')) == 1
def test_context_fn(self): sqltap.start(self.engine, lambda *args: 1) sess = self.Session() q = sess.query(self.A) q.all() stats = sqltap.collect() ctxs = [qstats.user_context for qstats in _startswith(stats, 'SELECT')] assert ctxs[0] == 1
def test_start_twice(self): """ Ensure that if multiple calls to sqltap.start on the same engine do not cause us to record more than one event per query. """ sqltap.start(self.engine) sqltap.start(self.engine) sess = self.Session() sess.query(self.A).all() stats = _startswith(sqltap.collect(), 'SELECT') assert len(stats) == 1
def test_report(self): sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A) qtext = str(q) q.all() report = sqltap.report(sqltap.collect()) assert 'SQLTap Report' in report assert qtext in report
def test_stop_global(self): """ Ensure queries after you call sqltap.stop() are not recorded when passing in the 'global' Engine object to record queries across all engines. This test passes, but because SQLAlchemy won't ever let us unregister our event handlers, this causes side-effects in other tests and will. """ return sqltap.start() sess = self.Session() sess.query(self.A).all() sqltap.stop() sess.query(self.A).all() assert len(sqltap.collect()) == 1
def f(): engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind = engine2) class B(Base): __tablename__ = "b" id = Column("id", Integer, primary_key = True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) sqltap.start(engine2) sqltap.start(self.engine) sess2 = Session() sess2.query(B).all()
def test_collect_fn_execption_on_collect(self): def noop(): pass profiler = sqltap.start(self.engine, collect_fn=noop) profiler.collect() profiler.stop()
def test_engine_scoped(self): """ Test that calling sqltap.start with a particular engine instance properly captures queries only to that engine. """ engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind = engine2) class B(Base): __tablename__ = "b" id = Column("id", Integer, primary_key = True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) profiler = sqltap.start(engine2) sess = self.Session() sess.query(self.A).all() sess2 = Session() sess2.query(B).all() stats = _startswith(profiler.collect(), 'SELECT') assert len(stats) == 1
def wrapper(*args, **kwargs): if not request.query.do_log: return callback(*args, **kwargs) import os fname = 'logs/{}.html'.format(request.path .replace('/', '.') .replace('<', '') .replace('>', '') .lstrip('.') ) try: os.remove(fname) except: pass import sqltap profiler = sqltap.start() try: return callback(*args, **kwargs) finally: try: statistics = profiler.collect() profiler.stop() sqltap.report(statistics, fname) except Exception: raise
def test_engine_global(self): """ Test that registering globally for all queries correctly pulls queries from multiple engines. """ engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind=engine2) class B(Base): __tablename__ = "b" id = Column("id", Integer, primary_key=True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) profiler = sqltap.start() sess = self.Session() sess.query(self.A).all() sess2 = Session() sess2.query(B).all() stats = _startswith(profiler.collect(), 'SELECT') assert len(stats) == 2 profiler.stop()
def test_report_aggregation_w_different_param_sets(self): """ Test that report rendering works with groups of queries containing different parameter sets """ sess = self.Session() a1 = self.A(name=uuid.uuid4().hex, description='') a2 = self.A(name=uuid.uuid4().hex, description='') sess.add_all([a1, a2]) sess.commit() a1 = sess.query(self.A).get(a1.id) a2 = sess.query(self.A).get(a2.id) profiler = sqltap.start(self.engine) # this will create queries with the same text, but different param sets # (different query.params.keys() collections) a1.name = uuid.uuid4().hex a2.description = uuid.uuid4().hex sess.flush() report = sqltap.report(profiler.collect()) print(report) profiler.stop() self.check_report(report)
def test_it_loads_one_author(client, app): query = """ query getAuthor($id: Int!){ author(id: $id){ id firstName books { id isbn readers { id } } } } """ with app.app_context(): author = Author.create(first_name="test1", last_name="test2") book = Book.create(title="test", isbn="r123213", author=author) reader = Reader.create(first_name="test", last_name="test2") reader.books.append(book) reader.save() profiler = sqltap.start() result = schema.execute(query, variable_values={'id': author.id}).data statistics = profiler.collect() assert len(statistics) == 2 assert result['author']['firstName'] == author.first_name assert result['author']['books'][0]['isbn'] == book.isbn
def test_it_loads_books(client, app): query = """ { books{ id title author { id firstName } readers { id } } } """ with app.app_context(): author = Author.create(first_name="test1", last_name="test2") book = Book.create(title="test", isbn="r123213", author=author) book2 = Book.create(title="test2", isbn="r12321312", author=author) reader = Reader.create(first_name="test", last_name="test2") reader.books.append(book) reader.save() profiler = sqltap.start() result = schema.execute(query) statistics = profiler.collect() assert result.data['books'][0]['title'] == book.title assert result.data['books'][0]['author']['firstName'] == author.first_name assert result.data['books'][1]['title'] == book2.title assert result.data['books'][1]['author']['firstName'] == author.first_name assert len(statistics) == 1
def test_report_aggregation_w_different_param_sets(self): """ Test that report rendering works with groups of queries containing different parameter sets """ sess = self.Session() a1 = self.A(name=uuid.uuid4().hex, description="") a2 = self.A(name=uuid.uuid4().hex, description="") sess.add_all([a1, a2]) sess.commit() a1 = sess.query(self.A).get(a1.id) a2 = sess.query(self.A).get(a2.id) profiler = sqltap.start(self.engine) # this will create queries with the same text, but different param sets # (different query.params.keys() collections) a1.name = uuid.uuid4().hex a2.description = uuid.uuid4().hex sess.flush() report = sqltap.report(profiler.collect()) print(report) profiler.stop() self.check_report(report)
def test_select(self): """ Simple test that sqltap collects a select query. """ profiler = sqltap.start(self.engine) sess = self.Session() sess.query(self.A).all() stats = profiler.collect() assert len(_startswith(stats, 'SELECT')) == 1
def test_stop(self): """ Ensure queries after you call ProfilingSession.stop() are not recorded. """ profiler = sqltap.start(self.engine) sess = self.Session() sess.query(self.A).all() profiler.stop() sess.query(self.A).all() assert len(profiler.collect()) == 1
def test_select(self): """ Simple test that sqltap collects a select query. """ profiler = sqltap.start(self.engine) sess = self.Session() sess.query(self.A).all() stats = profiler.collect() assert len(_startswith(stats, "SELECT")) == 1 profiler.stop()
def test_context_fn(self): profiler = sqltap.start(self.engine, lambda *args: 1) sess = self.Session() q = sess.query(self.A) q.all() stats = profiler.collect() ctxs = [qstats.user_context for qstats in _startswith(stats, 'SELECT')] assert ctxs[0] == 1
def test_insert(self): """ Simple test that sqltap collects an insert query. """ profiler = sqltap.start(self.engine) sess = self.Session() sess.add(self.A()) sess.flush() stats = profiler.collect() assert len(_startswith(stats, 'INSERT')) == 1
def test_insert(self): """ Simple test that sqltap collects an insert query. """ profiler = sqltap.start(self.engine) sess = self.Session() sess.add(self.A()) sess.flush() stats = profiler.collect() assert len(_startswith(stats, "INSERT")) == 1 profiler.stop()
def decorated_get(*args, **kwargs): if 'tuning' in kwargs and kwargs['tuning']: if not current_app.config['DEBUG']: abort(403, message="`DEBUG` must be on for tuning page") profiler = sqltap.start() result = f(*args, **kwargs) profiler.stop() stats = profiler.collect() return make_response(sqltap.report(stats, 'tuning.html')) result = f(*args, **kwargs) return result
def test_report(self): profiler = sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A) qtext = str(q) q.all() report = sqltap.report(profiler.collect()) assert 'sqltap profile report' in report assert qtext in report
def test_stop_global(self): """ Ensure queries after you call ProfilingSession.stop() are not recorded when passing in the 'global' Engine object to record queries across all engines. """ profiler = sqltap.start() sess = self.Session() sess.query(self.A).all() profiler.stop() sess.query(self.A).all() assert len(profiler.collect()) == 1
def test_report_aggregation(self): """ Test that we aggregate stats for the same query called from different locations as well as aggregating queries called from the same stack trace. """ sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A) q.all() q.all() q2 = sess.query(self.A).filter(self.A.id == 10) for i in xrange(10): q2.all() report = sqltap.report(sqltap.collect()) assert '2 unique' in report assert 'Query count: 10' in report
def test_report_to_file(self): profiler = sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A).filter(self.A.name == u"معاذ") q.all() stats = profiler.collect() fd, temp_path = tempfile.mkstemp() os.close(fd) report = sqltap.report(stats, filename=temp_path) with open(temp_path) as fp: self.assertEqual(report, fp.read())
def test_collect_fn(self): collection = [] def my_collector(q): collection.append(q) sess = self.Session() profiler = sqltap.start(self.engine, collect_fn=my_collector) sess.query(self.A).all() assert len(collection) == 1 sess.query(self.A).all() assert len(collection) == 2
def test_report_raw_sql(self): """ Ensure that reporting works when raw SQL queries were emitted. """ profiler = sqltap.start(self.engine) sess = self.Session() sql = 'SELECT * FROM %s' % self.A.__tablename__ sess.connection().execute(sql) stats = profiler.collect() report = sqltap.report(stats, report_format="html") assert REPORT_TITLE in report assert sqltap.format_sql(sql) in report report = sqltap.report(stats, report_format="text") assert REPORT_TITLE in report assert sqlparse.format(sql, reindent=True) in report profiler.stop()
def test_report(self): profiler = sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A) qtext = sqltap.format_sql(str(q)) q.all() stats = profiler.collect() report = sqltap.report(stats, report_format="html") assert REPORT_TITLE in report assert qtext in report report = sqltap.report(stats, report_format="text") assert REPORT_TITLE in report assert sqlparse.format(qtext, reindent=True) in report profiler.stop()
def test_report_ddl(self): """ Ensure that reporting works when DDL were emitted """ engine2 = create_engine('sqlite:///:memory:', echo=True) Base2 = declarative_base(bind=engine2) class B(Base2): __tablename__ = "b" id = Column("id", Integer, primary_key=True) profiler = sqltap.start(engine2) Base2.metadata.create_all(engine2) stats = profiler.collect() report = sqltap.report(stats, report_format="html") assert REPORT_TITLE in report report = sqltap.report(stats, report_format="text") assert REPORT_TITLE in report profiler.stop()
def test_context_fn_isolation(self): x = { "i": 0 } def context_fn(*args): x['i'] += 1 return x['i'] profiler = sqltap.start(self.engine, context_fn) sess = self.Session() sess.query(self.A).all() sess2 = Session() sess2.query(self.A).all() stats = profiler.collect() ctxs = [qstats.user_context for qstats in _startswith(stats, 'SELECT')] assert ctxs.count(1) == 1 assert ctxs.count(2) == 1
def test_report_escaped(self): """ Test that . """ engine2 = create_engine('sqlite:///:memory:', echo=True) Base = declarative_base(bind = engine2) class B(Base): __tablename__ = "b" id = Column("id", Unicode, primary_key = True) Base.metadata.create_all(engine2) Session = sessionmaker(bind=engine2) profiler = sqltap.start(engine2) sess = Session() sess.query(B).filter(B.id == u"<blockquote class='test'>").all() report = sqltap.report(profiler.collect()) assert "<blockquote class='test'>" not in report assert ""<blockquote class='test'>"" in report
def test_report_aggregation(self): """ Test that we aggregate stats for the same query called from different locations as well as aggregating queries called from the same stack trace. """ profiler = sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A) q.all() q.all() q2 = sess.query(self.A).filter(self.A.id == 10) for i in range(10): q2.all() report = sqltap.report(profiler.collect()) print(report) assert '2 unique' in report assert '<dd>10</dd>' in report
def test_report_aggregation(self): """ Test that we aggregate stats for the same query called from different locations as well as aggregating queries called from the same stack trace. """ profiler = sqltap.start(self.engine) sess = self.Session() q = sess.query(self.A) q.all() q.all() q2 = sess.query(self.A).filter(self.A.id == 10) for i in range(10): q2.all() report = sqltap.report(profiler.collect()) print(report) assert '2 unique' in report assert '<dd>10</dd>' in report profiler.stop()
try: import sqltap except: app.logger.error( 'Cannot import sqltap. Install it with pip to use profiling!') raise def context_fn(*args): import uuid try: return g.req_id except AttributeError: g.req_id = uuid.uuid4().hex return g.req_id sqltap_sess = sqltap.start(user_context_fn=context_fn) # -- main menu handing (context processor) -- @app.context_processor def _myapp_contextproc_menu(): """ Context processor for the main menu Adds the main menu data into the template context. Menu items are sorted by sort-order, then (case-insensitively) by label. """ return dict( menu=sorted(app._myapp_menudata, key=lambda mi: (mi['sortorder'], mi['label'].lower())))
def session(self): if self.dbsession is None: self.dbsession = self.application.Session() if SQLTAP: sqltap.start(self.application.engine) return self.dbsession
async def add_sql_tap(request: Request, call_next): profiler = sqltap.start() response = await call_next(request) statistics = profiler.collect() sqltap.report(statistics, "report.txt", report_format="text") return response
def test_collect_empty(self): profiler = sqltap.start(self.engine) assert len(profiler.collect()) == 0
def before_request(self): if request.path not in os.environ.get('SQLTAP_EXCLUDE'): self.processing = True self.profiler = tap.start() else: self.processing = False
import os import sys from webcheck.cmd import parser, main if __name__ == '__main__': try: args = parser.parse_args() if args.profile: fname = os.path.join(args.output_dir, 'webcheck.prof') try: import cProfile except ImportError: import profile as cProfile try: import sqltap sqltap.start() except ImportError: pass cProfile.run('main(vars(args))', fname) if 'sqltap' in locals(): statistics = sqltap.collect() sqltap.report(statistics, os.path.join(args.output_dir, 'sqltap.html')) else: main(vars(args)) except KeyboardInterrupt: sys.stderr.write('Interrupted\n') sys.exit(1)
def before_request(self): if request.path not in conf.SQLTAP_EXCLUDE: self.processing = True self.profiler = tap.start() else: self.processing = False