1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/pyinventory_ynh.git synced 2024-09-03 20:16:09 +02:00

Merge pull request #5 from YunoHost-Apps/local-test

Add scripts for local test for development
This commit is contained in:
Jens Diemer 2020-12-09 19:58:59 +01:00 committed by GitHub
commit f0fcaadcd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 229 additions and 5 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
!.gitignore
__pycache__
secret.txt
/local_test/

View file

@ -43,8 +43,9 @@ TODO: https://github.com/django-auth-ldap/django-auth-ldap
---
Developer info
----------------
# Developer info
## package installation / debugging
Please send your pull request to https://github.com/YunoHost-Apps/pyinventory_ynh
@ -103,3 +104,31 @@ root@yunohost:~# cat /etc/systemd/system/pyinventory.service
root@yunohost:~# systemctl reload-or-restart pyinventory
root@yunohost:~# journalctl --unit=pyinventory --follow
```
## local test
For quicker developing of PyInventory in the context of YunoHost app,
it's possible to run the Django developer server with the settings
and urls made for YunoHost installation.
For this, just run `local_test.py` in a PyInventory virtualenv.
e.g.:
```bash
~$ git clone https://github.com/jedie/PyInventory.git
~$ git clone https://github.com/YunoHost-Apps/pyinventory_ynh.git
~$ cd PyInventory/
~/PyInventory$ make install
~/PyInventory$ poetry shell
(pyinventory-yd_5sxYx-py3.8) ~/PyInventory$ cd ../pyinventory_ynh/
(pyinventory-yd_5sxYx-py3.8) ~/pyinventory_ynh$ ./local_test.py
...
Django version 2.2.17, using settings 'ynh_pyinventory_settings'
Starting development server at http://127.0.0.1:8000/
```
Notes:
* SQlite database will be used
* A super user with username `test` and password `test` is created
* The page is available under `http://127.0.0.1:8000/app_path/`

40
conf/create_superuser.py Normal file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python3
import argparse
import os
import sys
def main():
os.environ['DJANGO_SETTINGS_MODULE'] = 'ynh_pyinventory_settings'
parser = argparse.ArgumentParser(
description='Create or update Django super user.'
)
parser.add_argument('--username')
parser.add_argument('--password')
args = parser.parse_args()
username = args.username
password = args.password
import django
django.setup()
from django.contrib.auth import get_user_model
User = get_user_model()
super_user = User.objects.filter(username=username).first()
if super_user:
print('Update existing super user and set his password.', file=sys.stderr)
super_user.set_password(password)
super_user.save()
else:
print('Create new super user', file=sys.stderr)
User.objects.create_superuser(
username=username,
email='',
password=password
)
if __name__ == '__main__':
main()

View file

@ -23,7 +23,7 @@ assert FINAL_HOME_PATH.is_dir(), f'Directory not exists: {FINAL_HOME_PATH}'
FINAL_WWW_PATH = __Path('__FINAL_WWW_PATH__') # /var/www/$app
assert FINAL_WWW_PATH.is_dir(), f'Directory not exists: {FINAL_WWW_PATH}'
LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app//pyinventory.log
LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/pyinventory.log
assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}'
PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH

View file

@ -5,6 +5,10 @@ from django.urls import path
# settings.PATH_URL is the $YNH_APP_ARG_PATH
if settings.PATH_URL:
urlpatterns = [
# XXX: Hack - the MEDIA_URL contains the "PATH_URL" already:
path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')),
# Prefix all urls with "PATH_URL":
path(f'{settings.PATH_URL}/', include('inventory_project.urls'))
]
else:

150
local_test.py Executable file
View file

@ -0,0 +1,150 @@
#!/usr/bin/env python3
"""
Start PyInventory in YunoHost setup locally.
Note:
You can only run this script, if you are in a activated PyInventory venv!
see README for details ;)
"""
import os
import shlex
import subprocess
import sys
from pathlib import Path
os.environ['DJANGO_SETTINGS_MODULE'] = 'ynh_pyinventory_settings'
try:
import inventory_project # noqa
except ImportError as err:
raise ImportError(
'Couldn\'t import PyInventory. Did you '
'forget to activate a virtual environment?'
) from err
BASE_PATH = Path(__file__).parent.absolute()
TEST_PATH = BASE_PATH / 'local_test'
CONF_PATH = BASE_PATH / 'conf'
FINAL_HOME_PATH = TEST_PATH / 'opt_yunohost'
FINAL_WWW_PATH = TEST_PATH / 'var_www'
LOG_FILE = TEST_PATH / 'var_log_pyinventory.log'
MANAGE_PY_FILE = CONF_PATH / 'manage.py'
CREATE_SUPERUSER_FILE = CONF_PATH / 'create_superuser.py'
SETTINGS_FILE = CONF_PATH / 'ynh_pyinventory_settings.py'
URLS_FILE = CONF_PATH / 'ynh_urls.py'
REPLACES = {
'__FINAL_HOME_PATH__': str(FINAL_HOME_PATH),
'__FINAL_WWW_PATH__': str(FINAL_WWW_PATH),
'__LOG_FILE__': str(TEST_PATH / 'var_log_pyinventory.log'),
'__PATH_URL__': 'app_path',
'__DOMAIN__': '127.0.0.1',
'django.db.backends.postgresql': 'django.db.backends.sqlite3',
"'NAME': '__APP__',": f"'NAME': '{TEST_PATH / 'test_db.sqlite'}',",
'django_redis.cache.RedisCache': 'django.core.cache.backends.dummy.DummyCache',
'DEBUG = False': 'DEBUG = True',
# Just use the default logging setup from PyInventory project:
'LOGGING = {': 'HACKED_DEACTIVATED_LOGGING = {',
}
def verbose_check_call(command, verbose=True, **kwargs):
""" 'verbose' version of subprocess.check_call() """
if verbose:
print('_' * 100)
msg = f'Call: {command!r}'
verbose_kwargs = ', '.join(f'{k}={v!r}' for k, v in sorted(kwargs.items()))
if verbose_kwargs:
msg += f' (kwargs: {verbose_kwargs})'
print(f'{msg}\n', flush=True)
env = os.environ.copy()
env['PYTHONUNBUFFERED'] = '1'
popenargs = shlex.split(command)
subprocess.check_call(
popenargs,
universal_newlines=True,
env=env,
**kwargs
)
def call_manage_py(args):
verbose_check_call(
command=f'{sys.executable} manage.py {args}',
cwd=FINAL_HOME_PATH,
)
def copy_patch(src_file, replaces=None):
dst_file = FINAL_HOME_PATH / src_file.name
print(f'{src_file.relative_to(BASE_PATH)} -> {dst_file.relative_to(BASE_PATH)}')
with src_file.open('r') as f:
content = f.read()
if replaces:
for old, new in replaces.items():
content = content.replace(old, new)
with dst_file.open('w') as f:
f.write(content)
def main():
print('-' * 100)
assert BASE_PATH.is_dir()
assert CONF_PATH.is_dir()
assert SETTINGS_FILE.is_file()
assert URLS_FILE.is_file()
for p in (TEST_PATH, FINAL_HOME_PATH, FINAL_WWW_PATH):
if p.is_dir():
print(f'Already exists: "{p.relative_to(BASE_PATH)}", ok.')
else:
print(f'Create: "{p.relative_to(BASE_PATH)}"')
p.mkdir(parents=True, exist_ok=True)
LOG_FILE.touch(exist_ok=True)
# conf/manage.py -> local_test/manage.py
copy_patch(src_file=MANAGE_PY_FILE)
# conf/create_superuser.py -> local_test/opt_yunohost/create_superuser.py
copy_patch(src_file=CREATE_SUPERUSER_FILE)
# conf/ynh_pyinventory_settings.py -> local_test/ynh_pyinventory_settings.py
copy_patch(src_file=SETTINGS_FILE, replaces=REPLACES)
# conf/ynh_urls.py -> local_test/ynh_urls.py
copy_patch(src_file=URLS_FILE, replaces=REPLACES)
# call "local_test/manage.py" via subprocess:
call_manage_py('check --deploy')
call_manage_py('migrate --no-input')
call_manage_py('collectstatic --no-input')
verbose_check_call(
command=f'{sys.executable} create_superuser.py --username="test" --password="test"',
cwd=FINAL_HOME_PATH,
)
try:
call_manage_py('runserver --nostatic')
except KeyboardInterrupt:
print('\nBye ;)')
if __name__ == '__main__':
main()