launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #21988
[Merge] lp:~cjwatson/launchpad/hasquerycount-legible-mismatch into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/hasquerycount-legible-mismatch into lp:launchpad.
Commit message:
Make HasQueryCount mismatches legible, using formatting similar to LP_DEBUG_SQL(_EXTRA) output.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/hasquerycount-legible-mismatch/+merge/333244
The rendering of HasQueryCount mismatches has annoyed me for years: trying to read reprs of enormous multi-line backtraces is not as much fun as a fun thing. This is actually more or less readable now (length notwithstanding), and is colourised sensibly by bin/test -c.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/hasquerycount-legible-mismatch into lp:launchpad.
=== modified file 'lib/lp/testing/matchers.py'
--- lib/lp/testing/matchers.py 2016-12-02 12:52:56 +0000
+++ lib/lp/testing/matchers.py 2017-11-06 00:25:41 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010-2016 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2017 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -207,8 +207,17 @@
@staticmethod
def _getQueryDetails(collector):
- result = [unicode(query).encode('utf8') for query in collector.queries]
- return Content(UTF8_TEXT, lambda: ['\n'.join(result)])
+ result = []
+ for query in collector.queries:
+ start, stop, dbname, statement, backtrace = query
+ result.append(u'%d-%d@%s %s' % (
+ start, stop, dbname, statement.rstrip()))
+ result.append(u'-' * 70)
+ if backtrace is not None:
+ result.append(backtrace.rstrip())
+ result.append(u'.' * 70)
+ result = [item.encode('UTF-8') for item in result]
+ return Content(UTF8_TEXT, lambda: [b'\n'.join(result)])
def get_details(self):
details = {}
=== modified file 'lib/lp/testing/tests/test_matchers.py'
--- lib/lp/testing/tests/test_matchers.py 2015-10-13 16:58:20 +0000
+++ lib/lp/testing/tests/test_matchers.py 2017-11-06 00:25:41 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2017 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -218,17 +218,59 @@
matcher = HasQueryCount(LessThan(2))
collector = RequestTimelineCollector()
collector.count = 2
- collector.queries = [("foo", "bar"), ("baaz", "quux")]
- mismatch = matcher.match(collector)
- self.assertThat(mismatch, Not(Is(None)))
- details = mismatch.get_details()
- lines = []
- for name, content in details.items():
- self.assertEqual("queries", name)
- self.assertEqual("text", content.content_type.type)
- lines.append(''.join(content.iter_text()))
- self.assertEqual(["('foo', 'bar')\n('baaz', 'quux')"],
- lines)
+ collector.queries = [
+ (0, 1, "SQL-main-slave", "SELECT 1 FROM Person", None),
+ (2, 3, "SQL-main-slave", "SELECT 1 FROM Product", None),
+ ]
+ mismatch = matcher.match(collector)
+ self.assertThat(mismatch, Not(Is(None)))
+ details = mismatch.get_details()
+ lines = []
+ for name, content in details.items():
+ self.assertEqual("queries", name)
+ self.assertEqual("text", content.content_type.type)
+ lines.append(''.join(content.iter_text()))
+ separator = "-" * 70
+ expected_lines = [
+ "0-1@SQL-main-slave SELECT 1 FROM Person\n" + separator + "\n" +
+ "2-3@SQL-main-slave SELECT 1 FROM Product\n" + separator,
+ ]
+ self.assertEqual(expected_lines, lines)
+ self.assertEqual(
+ "queries do not match: %s" % (LessThan(2).match(2).describe(),),
+ mismatch.describe())
+
+ def test_with_backtrace(self):
+ matcher = HasQueryCount(LessThan(2))
+ collector = RequestTimelineCollector()
+ collector.count = 2
+ collector.queries = [
+ (0, 1, "SQL-main-slave", "SELECT 1 FROM Person",
+ ' File "example", line 2, in <module>\n'
+ ' Store.of(Person).one()\n'),
+ (2, 3, "SQL-main-slave", "SELECT 1 FROM Product",
+ ' File "example", line 3, in <module>\n'
+ ' Store.of(Product).one()\n'),
+ ]
+ mismatch = matcher.match(collector)
+ self.assertThat(mismatch, Not(Is(None)))
+ details = mismatch.get_details()
+ lines = []
+ for name, content in details.items():
+ self.assertEqual("queries", name)
+ self.assertEqual("text", content.content_type.type)
+ lines.append(''.join(content.iter_text()))
+ separator = "-" * 70
+ backtrace_separator = "." * 70
+ expected_lines = [
+ '0-1@SQL-main-slave SELECT 1 FROM Person\n' + separator + '\n' +
+ ' File "example", line 2, in <module>\n' +
+ ' Store.of(Person).one()\n' + backtrace_separator + '\n' +
+ '2-3@SQL-main-slave SELECT 1 FROM Product\n' + separator + '\n' +
+ ' File "example", line 3, in <module>\n' +
+ ' Store.of(Product).one()\n' + backtrace_separator,
+ ]
+ self.assertEqual(expected_lines, lines)
self.assertEqual(
"queries do not match: %s" % (LessThan(2).match(2).describe(),),
mismatch.describe())
@@ -236,10 +278,17 @@
def test_byEquality(self):
old_collector = RequestTimelineCollector()
old_collector.count = 2
- old_collector.queries = [("a", "1"), ("b", "2")]
+ old_collector.queries = [
+ (0, 1, "SQL-main-slave", "SELECT 1 FROM Person", None),
+ (2, 3, "SQL-main-slave", "SELECT 1 FROM Product", None),
+ ]
new_collector = RequestTimelineCollector()
new_collector.count = 3
- new_collector.queries = [("a", "1"), ("b", "2"), ("c", "3")]
+ new_collector.queries = [
+ (0, 1, "SQL-main-slave", "SELECT 1 FROM Person", None),
+ (2, 3, "SQL-main-slave", "SELECT 1 FROM Product", None),
+ (4, 5, "SQL-main-slave", "SELECT 1 FROM Distribution", None),
+ ]
matcher = HasQueryCount.byEquality(old_collector)
mismatch = matcher.match(new_collector)
self.assertThat(mismatch, Not(Is(None)))
@@ -251,8 +300,18 @@
old_lines.append("".join(details["other_queries"].iter_text()))
self.assertEqual("text", details["queries"].content_type.type)
new_lines.append("".join(details["queries"].iter_text()))
- self.assertEqual(["('a', '1')\n('b', '2')"], old_lines)
- self.assertEqual(["('a', '1')\n('b', '2')\n('c', '3')"], new_lines)
+ separator = "-" * 70
+ expected_old_lines = [
+ "0-1@SQL-main-slave SELECT 1 FROM Person\n" + separator + "\n" +
+ "2-3@SQL-main-slave SELECT 1 FROM Product\n" + separator,
+ ]
+ expected_new_lines = [
+ "0-1@SQL-main-slave SELECT 1 FROM Person\n" + separator + "\n" +
+ "2-3@SQL-main-slave SELECT 1 FROM Product\n" + separator + "\n" +
+ "4-5@SQL-main-slave SELECT 1 FROM Distribution\n" + separator,
+ ]
+ self.assertEqual(expected_old_lines, old_lines)
+ self.assertEqual(expected_new_lines, new_lines)
self.assertEqual(
"queries do not match: %s" % (Equals(2).match(3).describe(),),
mismatch.describe())
Follow ups