2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-09-13 14:11:37 +00:00

Docker fixes again (#10145)

* Add helper function for debugging query counts

* Adjust counts again

* Add docs to contributing.md
This commit is contained in:
Oliver
2025-08-07 23:28:13 +10:00
committed by GitHub
parent 61c8a8f703
commit 7327efbafd
3 changed files with 50 additions and 20 deletions

View File

@@ -208,6 +208,21 @@ coverage html -i
The coverage database is also generated in the CI-pipeline and exposd for 14 days as a artifact named `coverage`.
### Database Query Profiling
It may be useful during development to profile parts of the backend code to see how many database queries are executed. To that end, the `count_queries` context manager can be used to count the number of queries executed in a specific code block.
```python
from InvenTree.helpers import count_queries
with count_queries("My code block"):
# Code block to profile
...
```
A developer can use this to profile a specific code block, and the number of queries executed will be printed to the console.
## Code Style
Code style is automatically checked as part of the project's CI pipeline on GitHub. This means that any pull requests which do not conform to the style guidelines will fail CI checks.

View File

@@ -8,6 +8,7 @@ import re
import time
from contextlib import contextmanager
from pathlib import Path
from typing import Optional
from unittest import mock
from django.contrib.auth import get_user_model
@@ -25,6 +26,33 @@ from plugin import registry
from plugin.models import PluginConfig
@contextmanager
def count_queries(
msg: Optional[str] = None, log_to_file: bool = False, using: str = 'default'
): # pragma: no cover
"""Helper function to count the number of queries executed.
Arguments:
msg: Optional message to print after counting queries
log_to_file: If True, log the queries to a file (default = False)
using: The database connection to use (default = 'default')
"""
with CaptureQueriesContext(connections[using]) as context:
yield
n = len(context.captured_queries)
if log_to_file:
with open('queries.txt', 'w', encoding='utf-8') as f:
for q in context.captured_queries:
f.write(str(q['sql']) + '\n\n')
if msg:
print(f'{msg}: Executed {n} queries')
else:
print(f'Executed {n} queries')
def addUserPermission(user: User, app_name: str, model_name: str, perm: str) -> None:
"""Add a specific permission for the provided user.

View File

@@ -61,8 +61,6 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase):
def test_plugin_install(self):
"""Test the plugin install command."""
from django.conf import settings
url = reverse('api-plugin-install')
# invalid package name
@@ -87,23 +85,18 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase):
{'confirm': True, 'packagename': self.PKG_NAME},
expected_code=201,
max_query_time=30,
max_query_count=400,
max_query_count=450,
).data
self.assertEqual(data['success'], 'Installed plugin successfully')
# If we are running in docker mode, the plugin file is reinstalled too
# In that case, the expected query count is higher
query_count = 450 if settings.DOCKER else 350
query_time = 60 if settings.DOCKER else 30
# valid - github url
data = self.post(
url,
{'confirm': True, 'url': self.PKG_URL},
expected_code=201,
max_query_count=query_count,
max_query_time=query_time,
max_query_count=450,
max_query_time=60,
).data
self.assertEqual(data['success'], 'Installed plugin successfully')
@@ -613,31 +606,25 @@ class PluginFullAPITest(PluginMixin, InvenTreeAPITestCase):
@override_settings(PLUGIN_TESTING_SETUP=True)
def test_full_process(self):
"""Test the full plugin install/uninstall process via API."""
from django.conf import settings
install_slug = 'inventree-brother-plugin'
slug = 'brother'
# Note that if testing in docker mode, the plugin file is reinstalled too
# In that case, the expected query count is higher
query_count = 450 if settings.DOCKER else 350
query_time = 60 if settings.DOCKER else 30
# Install a plugin
data = self.post(
reverse('api-plugin-install'),
{'confirm': True, 'packagename': install_slug},
expected_code=201,
max_query_time=query_time,
max_query_count=query_count,
max_query_time=30,
max_query_count=450,
).data
self.assertEqual(data['success'], 'Installed plugin successfully')
# Activate the plugin
data = self.patch(
reverse('api-plugin-detail-activate', kwargs={'plugin': slug}),
data={'active': True},
max_query_count=320,
max_query_count=450,
).data
self.assertEqual(data['active'], True)