added count query decorator

This commit is contained in:
jsangmeister 2019-11-01 09:11:12 +01:00 committed by FinnStutzenstein
parent 1246dd54ad
commit 6605934a33
14 changed files with 123 additions and 39 deletions

View File

@ -192,9 +192,7 @@ class MotionViewSet(TreeSortMixin, ModelViewSet):
if isinstance(request.data, QueryDict): if isinstance(request.data, QueryDict):
submitters_id = request.data.getlist("submitters_id") submitters_id = request.data.getlist("submitters_id")
else: else:
submitters_id = request.data.get("submitters_id") submitters_id = request.data.get("submitters_id", [])
if submitters_id is None:
submitters_id = []
if not isinstance(submitters_id, list): if not isinstance(submitters_id, list):
raise ValidationError( raise ValidationError(
{"detail": "If submitters_id is given, it has to be a list."} {"detail": "If submitters_id is given, it has to be a list."}

View File

@ -329,7 +329,11 @@ class ElementCache:
for collection_string, value_list in raw_changed_elements.items() for collection_string, value_list in raw_changed_elements.items()
} }
if user_id is not None: if user_id is None:
for elements in changed_elements.values():
for element in elements:
element.pop("_no_delete_on_restriction", False)
else:
# the list(...) is important, because `changed_elements` will be # the list(...) is important, because `changed_elements` will be
# altered during iteration and restricting data # altered during iteration and restricting data
for collection_string, elements in list(changed_elements.items()): for collection_string, elements in list(changed_elements.items()):

32
tests/count_queries.py Normal file
View File

@ -0,0 +1,32 @@
from django.db import DEFAULT_DB_ALIAS, connections
from django.test.utils import CaptureQueriesContext
def count_queries(func, verbose=False, *args, **kwargs) -> int:
context = CaptureQueriesContext(connections[DEFAULT_DB_ALIAS])
with context:
func(*args, **kwargs)
if verbose:
queries = "\n".join(
f"{i}. {query['sql']}"
for i, query in enumerate(context.captured_queries, start=1)
)
print(f"{len(context)} queries executed\nCaptured queries were:\n{queries}")
return len(context)
def assert_query_count(should_be, verbose=False):
"""
Decorator to easily count queries on any test you want.
should_be defines how many queries are to be expected
"""
def outer(func):
def inner(*args, **kwargs):
assert count_queries(func, verbose, *args, **kwargs) == should_be
return inner
return outer

View File

@ -16,10 +16,10 @@ from openslides.motions.models import Motion
from openslides.topics.models import Topic from openslides.topics.models import Topic
from openslides.users.models import Group from openslides.users.models import Group
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ...common_groups import GROUP_DEFAULT_PK from ...common_groups import GROUP_DEFAULT_PK
from ..helpers import count_queries
class ContentObjects(TestCase): class ContentObjects(TestCase):

View File

@ -18,10 +18,9 @@ from openslides.poll.models import BasePoll
from openslides.utils.auth import get_group_model from openslides.utils.auth import get_group_model
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK
from tests.count_queries import assert_query_count, count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_assignment_poll_db_queries(): def test_assignment_poll_db_queries():
@ -95,6 +94,8 @@ class CreateAssignmentPoll(TestCase):
) )
self.assignment.add_candidate(self.admin) self.assignment.add_candidate(self.admin)
# TODO lower query count
@assert_query_count(47, True)
def test_simple(self): def test_simple(self):
response = self.client.post( response = self.client.post(
reverse("assignmentpoll-list"), reverse("assignmentpoll-list"),

View File

@ -9,10 +9,9 @@ from openslides.assignments.models import Assignment
from openslides.core.models import Tag from openslides.core.models import Tag
from openslides.mediafiles.models import Mediafile from openslides.mediafiles.models import Mediafile
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_assignment_db_queries(): def test_assignment_db_queries():

View File

@ -14,10 +14,9 @@ from openslides.users.models import User
from openslides.utils.auth import get_group_model from openslides.utils.auth import get_group_model
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_projector_db_queries(): def test_projector_db_queries():

View File

@ -1,8 +1,5 @@
from typing import Any, Dict, List from typing import Any, Dict, List
from django.db import DEFAULT_DB_ALIAS, connections
from django.test.utils import CaptureQueriesContext
from openslides.core.config import config from openslides.core.config import config
from openslides.core.models import Projector from openslides.core.models import Projector
from openslides.users.models import User from openslides.users.models import User
@ -118,20 +115,6 @@ register_projector_slide("test/slide1", slide1)
register_projector_slide("test/slide2", slide2) register_projector_slide("test/slide2", slide2)
def count_queries(func, *args, **kwargs) -> int:
context = CaptureQueriesContext(connections[DEFAULT_DB_ALIAS])
with context:
func(*args, **kwargs)
queries = "\n".join(
f"{i}. {query['sql']}"
for i, query in enumerate(context.captured_queries, start=1)
)
print(f"{len(context)} queries executed\nCaptured queries were:\n{queries}")
return len(context)
def all_data_config() -> AllData: def all_data_config() -> AllData:
return { return {
TConfig().get_collection_string(): { TConfig().get_collection_string(): {

View File

@ -7,10 +7,9 @@ from rest_framework import status
from rest_framework.test import APIClient from rest_framework.test import APIClient
from openslides.mediafiles.models import Mediafile from openslides.mediafiles.models import Mediafile
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_mediafiles_db_queries(): def test_mediafiles_db_queries():

View File

@ -24,10 +24,9 @@ from openslides.poll.models import BasePoll
from openslides.utils.auth import get_group_model from openslides.utils.auth import get_group_model
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.common_groups import GROUP_ADMIN_PK, GROUP_DEFAULT_PK, GROUP_DELEGATE_PK from tests.common_groups import GROUP_ADMIN_PK, GROUP_DEFAULT_PK, GROUP_DELEGATE_PK
from tests.count_queries import assert_query_count, count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_motion_db_queries(): def test_motion_db_queries():
@ -126,10 +125,13 @@ class CreateMotion(TestCase):
Tests motion creation. Tests motion creation.
""" """
maxDiff = None
def setUp(self): def setUp(self):
self.client = APIClient() self.client = APIClient()
self.client.login(username="admin", password="admin") self.client.login(username="admin", password="admin")
@assert_query_count(85, True)
def test_simple(self): def test_simple(self):
""" """
Tests that a motion is created with a specific title and text. Tests that a motion is created with a specific title and text.
@ -146,6 +148,76 @@ class CreateMotion(TestCase):
) )
self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
motion = Motion.objects.get() motion = Motion.objects.get()
changed_autoupdate, deleted_autoupdate = self.get_last_autoupdate()
del changed_autoupdate["motions/motion:1"]["created"]
del changed_autoupdate["motions/motion:1"]["last_modified"]
self.assertEqual(
changed_autoupdate,
{
"agenda/list-of-speakers:1": {
"id": 1,
"title_information": {
"title": "test_title_OoCoo3MeiT9li5Iengu9",
"identifier": "1",
},
"speakers": [],
"closed": False,
"content_object": {"collection": "motions/motion", "id": 1},
},
"motions/motion:1": {
"id": 1,
"identifier": "1",
"title": "test_title_OoCoo3MeiT9li5Iengu9",
"text": "test_text_thuoz0iecheiheereiCi",
"amendment_paragraphs": None,
"modified_final_version": "",
"reason": "",
"parent_id": None,
"category_id": None,
"category_weight": 10000,
"comments": [],
"motion_block_id": None,
"origin": "",
"submitters": [
{"id": 1, "user_id": 1, "motion_id": 1, "weight": 1}
],
"supporters_id": [],
"state_id": 1,
"state_extension": None,
"state_restriction": [],
"statute_paragraph_id": None,
"workflow_id": 1,
"recommendation_id": None,
"recommendation_extension": None,
"tags_id": [],
"attachments_id": [],
"agenda_item_id": 1,
"list_of_speakers_id": 1,
"sort_parent_id": None,
"weight": 10000,
"change_recommendations_id": [],
},
"agenda/item:1": {
"id": 1,
"item_number": "",
"title_information": {
"title": "test_title_OoCoo3MeiT9li5Iengu9",
"identifier": "1",
},
"comment": None,
"closed": False,
"type": 3,
"is_internal": False,
"is_hidden": True,
"duration": None,
"content_object": {"collection": "motions/motion", "id": 1},
"weight": 10000,
"parent_id": None,
"level": 0,
},
},
)
self.assertEqual(deleted_autoupdate, [])
self.assertEqual(motion.title, "test_title_OoCoo3MeiT9li5Iengu9") self.assertEqual(motion.title, "test_title_OoCoo3MeiT9li5Iengu9")
self.assertEqual(motion.identifier, "1") self.assertEqual(motion.identifier, "1")
self.assertTrue(motion.submitters.exists()) self.assertTrue(motion.submitters.exists())

View File

@ -12,10 +12,9 @@ from openslides.poll.models import BasePoll
from openslides.utils.auth import get_group_model from openslides.utils.auth import get_group_model
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.common_groups import GROUP_ADMIN_PK, GROUP_DEFAULT_PK, GROUP_DELEGATE_PK from tests.common_groups import GROUP_ADMIN_PK, GROUP_DEFAULT_PK, GROUP_DELEGATE_PK
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_motion_poll_db_queries(): def test_motion_poll_db_queries():

View File

@ -19,10 +19,9 @@ from openslides.motions.models import (
from openslides.utils.auth import get_group_model from openslides.utils.auth import get_group_model
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK, GROUP_STAFF_PK from tests.common_groups import GROUP_ADMIN_PK, GROUP_DELEGATE_PK, GROUP_STAFF_PK
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_category_db_queries(): def test_category_db_queries():

View File

@ -4,10 +4,9 @@ from rest_framework import status
from openslides.agenda.models import Item from openslides.agenda.models import Item
from openslides.topics.models import Topic from openslides.topics.models import Topic
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)
def test_topic_item_db_queries(): def test_topic_item_db_queries():

View File

@ -8,6 +8,7 @@ from rest_framework.test import APIClient
from openslides.core.config import config from openslides.core.config import config
from openslides.users.models import Group, PersonalNote, User from openslides.users.models import Group, PersonalNote, User
from openslides.utils.autoupdate import inform_changed_data from openslides.utils.autoupdate import inform_changed_data
from tests.count_queries import count_queries
from tests.test_case import TestCase from tests.test_case import TestCase
from ...common_groups import ( from ...common_groups import (
@ -16,7 +17,6 @@ from ...common_groups import (
GROUP_DELEGATE_PK, GROUP_DELEGATE_PK,
GROUP_STAFF_PK, GROUP_STAFF_PK,
) )
from ..helpers import count_queries
@pytest.mark.django_db(transaction=False) @pytest.mark.django_db(transaction=False)