Skip to content

Commit 6680c85

Browse files
Demonstrating breaking connection
1 parent 59c1fe5 commit 6680c85

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,74 @@
1+
from clickhouse_driver.dbapi.errors import (
2+
OperationalError as ch_driver_OperationalError,
3+
)
4+
from clickhouse_driver.errors import PartiallyConsumedQueryError
5+
from django.db import connection
6+
from django.db.utils import OperationalError as django_OperationalError
17
from django.test import TestCase
28

39
from clickhouse_backend.driver import connect
410

11+
from .. import models
12+
513

614
class Tests(TestCase):
715
def test_pool_size(self):
816
conn = connect(host="localhost", connections_min=2, connections_max=4)
917
assert conn.pool.connections_min == 2
1018
assert conn.pool.connections_max == 4
1119
assert len(conn.pool._pool) == 2
20+
21+
22+
class IterationTests(TestCase):
23+
"""
24+
Testing connection behaviour when iterating over queryset is interrupted.
25+
"""
26+
27+
@classmethod
28+
def setUpTestData(cls):
29+
cls.a1, cls.a2, cls.a3 = models.Author.objects.bulk_create(
30+
[
31+
models.Author(name="a1"),
32+
models.Author(name="a2"),
33+
models.Author(name="a3"),
34+
]
35+
)
36+
37+
def test_connection_unusable_when_iteration_interrupted(self):
38+
"""
39+
This test demonstrates that if a queryset is iterated over and the iteration
40+
is interrupted (e.g. via a break statement), the connection used for that
41+
iteration is not cleaned up and is left in a broken state. Any subsequent
42+
queries using that connection will fail.
43+
"""
44+
pool = connection.connection.pool
45+
connection_count_before = len(pool._pool)
46+
47+
assert connection_count_before == 1
48+
49+
# Asserts most recent exception is Django OperationalError
50+
with self.assertRaises(django_OperationalError) as ex_context:
51+
# Get queryset
52+
authors = models.Author.objects.all()
53+
# Access iterator, but break after first item
54+
for author in authors.iterator(1):
55+
author = author.name
56+
break
57+
58+
# Assert connection pool size is unchanged despite broken connection
59+
connection_count_after_iterator = len(pool._pool)
60+
assert connection_count_after_iterator == 1
61+
62+
# Try to access queryset again, which won't work via same connection
63+
author = authors.get(id=self.a1.id)
64+
65+
# Caused by ch driver driver Operational error
66+
self.assertIsInstance(
67+
ex_context.exception.__cause__, ch_driver_OperationalError
68+
)
69+
70+
# ...The context of which is a PartiallyConsumedQueryError
71+
# https://github.com/mymarilyn/clickhouse-driver/blob/master/clickhouse_driver/connection.py#L801
72+
self.assertIsInstance(
73+
ex_context.exception.__cause__.__context__, PartiallyConsumedQueryError
74+
)

0 commit comments

Comments
 (0)