forked from ungleich-public/dynamicweb
Add a smoke test that opens every site and logs in to the admin
This commit is contained in:
parent
07de15c795
commit
a0d4ed2497
3 changed files with 103 additions and 13 deletions
87
smoke_test.py
Normal file
87
smoke_test.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"""
|
||||
Smoke test for a running stack: opens every site and the admin login.
|
||||
|
||||
docker compose exec web python smoke_test.py [base_url]
|
||||
|
||||
Needs no extra packages, so it runs the same on every Python/Django version.
|
||||
Exits non-zero if anything fails. Expects the sample data (SEED_DUMMY_DATA).
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from http.cookiejar import CookieJar
|
||||
|
||||
from utils.sample_sites import SITE_TEXTS
|
||||
|
||||
BASE = sys.argv[1] if len(sys.argv) > 1 else 'http://127.0.0.1:8000'
|
||||
ADMIN = ('dummy-admin@example.com',
|
||||
os.environ.get('DUMMY_ADMIN_PASSWORD') or 'dummy-admin')
|
||||
SUB_PAGES = ['about', 'services', 'pricing', 'contact']
|
||||
failures = []
|
||||
|
||||
|
||||
def fetch(opener, path, host, data=None):
|
||||
request = urllib.request.Request(BASE + path, data=data)
|
||||
request.add_header('Host', host)
|
||||
try:
|
||||
response = opener.open(request, timeout=60)
|
||||
except urllib.error.HTTPError as error:
|
||||
return error.code, error.read().decode('utf-8', 'replace'), path
|
||||
return (response.status if hasattr(response, 'status')
|
||||
else response.getcode(),
|
||||
response.read().decode('utf-8', 'replace'), response.geturl())
|
||||
|
||||
|
||||
def check(name, ok, detail=''):
|
||||
print('{} {}{}'.format('ok ' if ok else 'FAIL', name,
|
||||
'' if ok else ' -> ' + detail))
|
||||
if not ok:
|
||||
failures.append(name)
|
||||
|
||||
|
||||
def sites():
|
||||
configs = json.loads(os.environ.get('UNGLEICH_SITE_CONFIGS') or '{}')
|
||||
return sorted(d for d in configs if ':' not in d)
|
||||
|
||||
|
||||
def main():
|
||||
for domain in sites():
|
||||
opener = urllib.request.build_opener(
|
||||
urllib.request.HTTPCookieProcessor(CookieJar()))
|
||||
name, tagline = SITE_TEXTS.get(domain, (domain, ''))
|
||||
status, body, _ = fetch(opener, '/', domain)
|
||||
check('{} /'.format(domain), status == 200, 'status %s' % status)
|
||||
status, body, _ = fetch(opener, '/en-us/cms/', domain)
|
||||
check('{} home'.format(domain),
|
||||
status == 200 and name in body and tagline in body,
|
||||
'status %s, content missing' % status)
|
||||
for slug in SUB_PAGES:
|
||||
status, _, _ = fetch(opener, '/en-us/cms/%s/' % slug, domain)
|
||||
check('{} {}'.format(domain, slug), status == 200,
|
||||
'status %s' % status)
|
||||
|
||||
# admin login on the first site
|
||||
domain = sites()[0]
|
||||
opener = urllib.request.build_opener(
|
||||
urllib.request.HTTPCookieProcessor(CookieJar()))
|
||||
status, body, _ = fetch(opener, '/en-us/admin/login/', domain)
|
||||
token = re.search(r"name=.csrfmiddlewaretoken. value=.([^'\"]+)", body)
|
||||
check('admin login page', status == 200 and token, 'status %s' % status)
|
||||
if token:
|
||||
form = urllib.parse.urlencode({
|
||||
'csrfmiddlewaretoken': token.group(1), 'username': ADMIN[0],
|
||||
'password': ADMIN[1], 'next': '/en-us/admin/'}).encode()
|
||||
status, body, url = fetch(
|
||||
opener, '/en-us/admin/login/', domain, data=form)
|
||||
check('admin login works',
|
||||
status == 200 and 'login' not in url, 'status %s, ended on %s' % (status, url))
|
||||
|
||||
print('\n{} failure(s)'.format(len(failures)))
|
||||
sys.exit(1 if failures else 0)
|
||||
|
||||
|
||||
main()
|
||||
|
|
@ -24,25 +24,13 @@ from django.contrib.sites.models import Site
|
|||
from django.core.management.base import BaseCommand
|
||||
|
||||
from membership.models import CustomUser
|
||||
from utils.sample_sites import SITE_TEXTS
|
||||
|
||||
REVERSE_ID = 'dummy-home'
|
||||
ADMIN_EMAIL = 'dummy-admin@example.com'
|
||||
CUSTOMER_EMAIL_FORMAT = 'dummy-customer-{}@example.com'
|
||||
CUSTOMER_COUNT = 12
|
||||
DEFAULT_ADMIN_PASSWORD = 'dummy-admin'
|
||||
# domain -> (name, tagline); other domains are named after their domain
|
||||
SITE_TEXTS = {
|
||||
'ungleich.ch': ('ungleich', 'Swiss IT infrastructure, hosting and open source.'),
|
||||
'blog.ungleich.ch': ('ungleich blog', 'Notes from running data centers, networks and free software.'),
|
||||
'comic.ungleich.ch': ('ungleich comic', 'Life in the data center, one panel at a time.'),
|
||||
'digitalglarus.ch': ('Digital Glarus', 'The Swiss IT valley in Schwanden, Glarus.'),
|
||||
'datacenterlight.ch': ('Data Center Light', 'Virtual machines from a Swiss, ecological data center.'),
|
||||
'rails-hosting.ch': ('Rails Hosting', 'Managed hosting for Ruby on Rails applications.'),
|
||||
'django-hosting.ch': ('Django Hosting', 'Managed hosting for Django applications.'),
|
||||
'node-hosting.ch': ('Node.js Hosting', 'Managed hosting for Node.js applications.'),
|
||||
'devuanhosting.ch': ('Devuan Hosting', 'Hosting on Devuan, the systemd-free Linux.'),
|
||||
'devuanhosting.com': ('Devuan Hosting', 'Hosting on Devuan, the systemd-free Linux.'),
|
||||
}
|
||||
# (slug, title, text) for the pages below each site's home page
|
||||
SUB_PAGES = [
|
||||
('about', 'About', '{name} is operated by ungleich GmbH in Switzerland. '
|
||||
|
|
|
|||
15
utils/sample_sites.py
Normal file
15
utils/sample_sites.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
"""Sample site names and taglines, shared by the seeder and smoke_test.py.
|
||||
No Django imports, so it works anywhere."""
|
||||
# domain -> (name, tagline); other domains are named after their domain
|
||||
SITE_TEXTS = {
|
||||
'ungleich.ch': ('ungleich', 'Swiss IT infrastructure, hosting and open source.'),
|
||||
'blog.ungleich.ch': ('ungleich blog', 'Notes from running data centers, networks and free software.'),
|
||||
'comic.ungleich.ch': ('ungleich comic', 'Life in the data center, one panel at a time.'),
|
||||
'digitalglarus.ch': ('Digital Glarus', 'The Swiss IT valley in Schwanden, Glarus.'),
|
||||
'datacenterlight.ch': ('Data Center Light', 'Virtual machines from a Swiss, ecological data center.'),
|
||||
'rails-hosting.ch': ('Rails Hosting', 'Managed hosting for Ruby on Rails applications.'),
|
||||
'django-hosting.ch': ('Django Hosting', 'Managed hosting for Django applications.'),
|
||||
'node-hosting.ch': ('Node.js Hosting', 'Managed hosting for Node.js applications.'),
|
||||
'devuanhosting.ch': ('Devuan Hosting', 'Hosting on Devuan, the systemd-free Linux.'),
|
||||
'devuanhosting.com': ('Devuan Hosting', 'Hosting on Devuan, the systemd-free Linux.'),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue