Skip to content

Commit

Permalink
Adds test class for checking query durations
Browse files Browse the repository at this point in the history
This is a first pass and I wrote it specifically so that it would fail
on the query in test_book.py
  • Loading branch information
mouse-reeve committed Jun 9, 2024
1 parent 3545a1c commit fdc6ae2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
39 changes: 39 additions & 0 deletions bookwyrm/tests/query_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
""" Log query runtimes for testing """
import time


class QueryLogger:
"""Returns the sql and duration for any query run
Taken wholesale from:
https://docs.djangoproject.com/en/dev/topics/db/instrumentation/
"""

def __init__(self):
self.queries = []

# pylint: disable=too-many-arguments
def __call__(self, execute, sql, params, many, context):
current_query = {"sql": sql, "params": params, "many": many}
start = time.monotonic()
try:
result = execute(sql, params, many, context)
except Exception as err: # pylint: disable=broad-except
current_query["status"] = "error"
current_query["exception"] = err
raise
else:
current_query["status"] = "ok"
return result
finally:
duration = time.monotonic() - start
current_query["duration"] = duration
self.queries.append(current_query)


def raise_long_query_runtime(queries, threshold=0.0006):
"""Raises an exception if any query took longer than the threshold"""
for query in queries:
if query["duration"] > threshold:
raise Exception( # pylint: disable=broad-exception-raised
"This looks like a slow query:", query["duration"], query["sql"]
)
16 changes: 12 additions & 4 deletions bookwyrm/tests/views/books/test_book.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import connection
from django.http import Http404
from django.template.response import TemplateResponse
from django.test import TestCase
Expand All @@ -16,8 +17,9 @@
from bookwyrm import forms, models, views
from bookwyrm.activitypub import ActivitypubResponse
from bookwyrm.tests.validate_html import validate_html
from bookwyrm.tests.query_logger import QueryLogger, raise_long_query_runtime


# pylint: disable=invalid-name
class BookViews(TestCase):
"""books books books"""

Expand Down Expand Up @@ -68,9 +70,15 @@ def test_book_page(self):
)
request = self.factory.get("")
request.user = self.local_user
with patch("bookwyrm.views.books.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, self.book.id)

query_logger = QueryLogger()
with connection.execute_wrapper(query_logger):
with patch("bookwyrm.views.books.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, self.book.id)

raise_long_query_runtime(query_logger.queries)

Check failure on line 80 in bookwyrm/tests/views/books/test_book.py

View workflow job for this annotation

GitHub Actions / Tests (pytest)

BookViews.test_book_page Exception: ('This looks like a slow query:', 0.001422224999998889, 'SELECT "bookwyrm_book"."id", "bookwyrm_book"."created_date", "bookwyrm_book"."updated_date", "bookwyrm_book"."remote_id", "bookwyrm_book"."origin_id", "bookwyrm_book"."openlibrary_key", "bookwyrm_book"."inventaire_id", "bookwyrm_book"."librarything_key", "bookwyrm_book"."goodreads_key", "bookwyrm_book"."bnf_id", "bookwyrm_book"."viaf", "bookwyrm_book"."wikidata", "bookwyrm_book"."asin", "bookwyrm_book"."aasin", "bookwyrm_book"."isfdb", "bookwyrm_book"."search_vector", "bookwyrm_book"."last_edited_by_id", "bookwyrm_book"."connector_id", "bookwyrm_book"."title", "bookwyrm_book"."sort_title", "bookwyrm_book"."subtitle", "bookwyrm_book"."description", "bookwyrm_book"."languages", "bookwyrm_book"."series", "bookwyrm_book"."series_number", "bookwyrm_book"."subjects", "bookwyrm_book"."subject_places", "bookwyrm_book"."cover", "bookwyrm_book"."preview_image", "bookwyrm_book"."first_published_date", "bookwyrm_book"."published_date", "bookwyrm_book"."first_published_date_precision", "bookwyrm_book"."published_date_precision", "bookwyrm_edition"."book_ptr_id", "bookwyrm_edition"."isbn_10", "bookwyrm_edition"."isbn_13", "bookwyrm_edition"."oclc_number", "bookwyrm_edition"."pages", "bookwyrm_edition"."physical_format", "bookwyrm_edition"."physical_format_detail", "bookwyrm_edition"."publishers", "bookwyrm_edition"."parent_work_id", "bookwyrm_edition"."edition_rank", T4."id", T4."created_date", T4."updated_date", T4."remote_id", T4."origin_id", T4."openlibrary_key", T4."inventaire_id", T4."librarything_key", T4."goodreads_key", T4."bnf_id", T4."viaf", T4."wikidata", T4."asin", T4."aasin", T4."isfdb", T4."search_vector", T4."last_edited_by_id", T4."connector_id", T4."title", T4."sort_title", T4."subtitle", T4."description", T4."languages", T4."series", T4."series_number", T4."subjects", T4."subject_places", T4."cover", T4."preview_image", T4."first_published_date", T4."published_date", T4."first_published_date_precision", T4."published_date_precision", "bookwyrm_work"."book_ptr_id", "bookwyrm_work"."lccn" FROM "bookwyrm_edition" INNER JOIN "bookwyrm_book" ON ("bookwyrm_edition"."book_ptr_id" = "bookwyrm_book"."id") LEFT OUTER JOIN "bookwyrm_work" ON ("bookwyrm_edition"."parent_work_id" = "bookwyrm_work"."book_ptr_id") LEFT OUTER JOIN "bookwyrm_book" T4 ON ("bookwyrm_work"."book_ptr_id" = T4."id") LEFT OUTER JOIN "bookwyrm_mergedbook" ON ("bookwyrm_book"."id" = "bookwyrm_mergedbook"."merged_into_id") WHERE ("bookwyrm_edition"."book_ptr_id" = %s OR "bookwyrm_edition"."parent_work_id" = %s OR "bookwyrm_mergedbook"."deleted_id" = %s) ORDER BY "bookwyrm_edition"."edition_rank" DESC LIMIT 1')

self.assertIsInstance(result, TemplateResponse)
validate_html(result.render())

Expand Down

0 comments on commit fdc6ae2

Please sign in to comment.