Anton Shestakov <av6@dwimlabs.net>, Sun, 24 Sep 2017 12:25:05 +0800
viewer: use subqueries to get data on index page
Before, there were bare columns in the aggregate query, their values were
undefined (but it somehow worked), as SQLite docs say. Good news is that now
this bigger query uses (project_id, ordinal) index and is really fast.
tests/test_viewer.py
Permissions: -rw-r--r--
from datetime import datetime from xml.etree import ElementTree from pytest import raises from tornado.escape import json_encode from tornado.testing import AsyncHTTPTestCase from tornado.web import HTTPError from candolint.handlers import get_project_or_404 from candolint.models import database, Project, Change, Check from viewer import CandolintViewer 'atom': 'http://www.w3.org/2005/Atom', 'svg': 'http://www.w3.org/2000/svg' with database.transaction(): project = Project.create( url='https://example.com/alice/test-viewer', node='92cfceb39d57d914ed8b14d0e37643de0797ae56', date='2016-07-19 22:23 +0800', message='component: do a thing', ordinal=Check.get_next_ordinal(project), started=datetime.fromtimestamp(0), finished=datetime.fromtimestamp(0), 'text': '# C&O job started: 2016-08-20T02:38:06+00:00', 'text': '# C&O task: setup', 'text': '$ ../venv2/bin/flake8 --version', 'text': '# C&O task: checks', 'text': 'test.py:20:80: E501 line too long (82 > 79 characters)', 'text': '# C&O job finished: 2016-08-20T02:38:53+00:00', ordinal=Check.get_next_ordinal(project), lines=json_encode(lines), started=datetime(2016, 8, 20, 2, 38, 6), finished=datetime(2016, 8, 20, 2, 38, 53), def test_get_project_or_404(): with raises(HTTPError) as error: get_project_or_404('butt.cloud', 'cyber', 'wizard-attack') assert error.value.status_code == 404 project = get_project_or_404('example.com', 'alice', 'test-viewer') assert project.id is not None assert project.url == 'https://example.com/alice/test-viewer' class ViewerTestCase(AsyncHTTPTestCase): response = self.fetch('/') assert response.code == 200 assert 'online linter' in response.body assert 'test-viewer' in response.body assert '1 error' in response.body assert '1 warning' in response.body assert '<a href="#">default</a>' in response.body assert '2016-08-20T02:38:53Z' in response.body response = self.fetch('/nobodyhere') assert response.code == 404 assert 'online linter' in response.body response = self.fetch('/butt.cloud/cyber/wizard-attack') assert response.code == 404 assert 'online linter' in response.body response = self.fetch('/example.com/alice/test-viewer') assert response.code == 200 assert 'Clone URL' in response.body assert 'status.svg' in response.body assert '.. image:: http' in response.body assert '1 error' in response.body assert '1 warning' in response.body assert '<a href="#">default</a>' in response.body assert ('<link rel="alternate"' ' href="/example.com/alice/test-viewer/atom"' ' type="application/atom+xml"' ' title="test-viewer feed">') in response.body response = self.fetch('/example.com/alice/test-viewer/atom') assert response.code == 200 assert 'atom+xml' in response.headers['Content-Type'] root = ElementTree.fromstring(response.body) assert root.tag == '{%s}%s' % (XMLNS['atom'], 'feed') title = root.find('./atom:entry/atom:title', XMLNS) assert title.text.startswith('Check #') assert title.text.endswith(' 1 error, 1 warning') updates = [el.text for el in root.findall('.//atom:updated', XMLNS)] assert len(updates) == min(Check.select().count(), 20) + 1 assert updates[0] == updates[1] == '2016-08-20T02:38:53Z' response = self.fetch('/butt.cloud/cyber/wizard-attack/latest') assert response.code == 404 assert 'online linter' in response.body response = self.fetch('/example.com/alice/test-viewer/latest') assert response.code == 200 assert '1 error' in response.body assert '1 warning' in response.body assert '<a href="#">default</a>' in response.body assert '<a href="#" class="filelink">test.py:20</a>' in response.body assert ('<time datetime="2016-08-20T02:38:53Z"' ' title="2016-08-20 02:38:53 UTC">' '2016-08-20 02:38:53 UTC</time>') in response.body assert ('<time datetime="2016-07-19T22:23+0800"' ' title="2016-07-19 22:23 +0800">' '2016-07-19 22:23 +0800</time>') in response.body response = self.fetch('/example.com/alice/test-viewer/latest/raw') assert response.code == 200 assert response.headers['Content-Type'] == 'text/plain; charset=utf-8' assert 'test.py' in response.body base_url = '/example.com/alice/test-viewer/latest' response = self.fetch(base_url + '/compare/latest') assert response.code == 200 assert 'same commit' in response.body assert 'Diff is empty' in response.body response = self.fetch(base_url + '/compare/1') assert response.code == 200 assert 'same commit' in response.body assert 'E501' in response.body response = self.fetch('/butt.cloud/cyber/wizard-attack/status.svg') assert response.code == 404 assert 'online linter' in response.body response = self.fetch('/example.com/alice/test-viewer/status.svg') assert response.code == 200 root = ElementTree.fromstring(response.body) assert root.tag == '{%s}%s' % (XMLNS['svg'], 'svg') assert root.attrib.get('height') == '20' text = [el.text for el in root.findall('./svg:g/svg:text', XMLNS)] assert text[::2] == ['lint', '1 error', '1 warning'] response = self.fetch('/example.com/alice/test-viewer/latest/dot.svg') assert response.code == 200 root = ElementTree.fromstring(response.body) assert root.tag == '{%s}%s' % (XMLNS['svg'], 'svg') assert root.attrib.get('height') == '12' circles = root.findall('./svg:circle', XMLNS) assert circles[0].attrib.get('fill').startswith('#')