Skip to content

Commit

Permalink
Tests: Properly tear down and dispose resources in doctests
Browse files Browse the repository at this point in the history
  • Loading branch information
amotl committed Oct 14, 2022
1 parent 1b099bd commit 8b30897
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 11 deletions.
20 changes: 18 additions & 2 deletions docs/by-example/http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ Server configuration
A list of servers can be passed while creating an instance of the http client::

>>> http_client = HttpClient([crate_host])
>>> http_client.close()

Its also possible to pass a single server as a string::

>>> http_client = HttpClient(crate_host)
>>> http_client.close()

If no ``server`` argument (or no argument at all) is passed, the default one
``127.0.0.1:4200`` is used::

>>> http_client = HttpClient()
>>> http_client._active_servers
['http://127.0.0.1:4200']
>>> http_client.close()

When using a list of servers, the servers are selected by round-robin::

Expand All @@ -49,6 +52,8 @@ When using a list of servers, the servers are selected by round-robin::
>>> http_client._get_server()
'http://even_more_invalid_host:9999'

>>> http_client.close()

Servers with connection errors will be removed from the active server list::

>>> http_client = HttpClient([invalid_host, even_more_invalid_host, crate_host])
Expand All @@ -66,6 +71,7 @@ To validate this, set the interval very short and sleep for that interval::
['http://invalid_host:9999',
'http://even_more_invalid_host:9999',
'http://127.0.0.1:44209']
>>> http_client.close()

If no active servers are available and the retry interval is not reached, just use the oldest
inactive one::
Expand All @@ -75,6 +81,7 @@ inactive one::
>>> http_client._active_servers = []
>>> http_client._get_server()
'http://invalid_host:9999'
>>> http_client.close()

SQL Statements
==============
Expand Down Expand Up @@ -117,8 +124,7 @@ Trying to get a non-existing blob throws an exception::
...
crate.client.exceptions.DigestNotFoundException: myfiles/041f06fd774092478d450774f5ba30c5da78acc8

Creating a new blob - this method returns True if the blob was newly
created, false if it already exists::
Creating a new blob - this method returns True if the blob was newly created::

>>> from tempfile import TemporaryFile
>>> f = TemporaryFile()
Expand All @@ -128,6 +134,8 @@ created, false if it already exists::
... 'myfiles', '040f06fd774092478d450774f5ba30c5da78acc8', f)
True

Uploading the same content again returns ``False``::

>>> _ = f.seek(0)
>>> http_client.blob_put(
... 'myfiles', '040f06fd774092478d450774f5ba30c5da78acc8', f)
Expand Down Expand Up @@ -171,6 +179,10 @@ Uploading a blob to a table with disabled blob support throws an exception::
...
crate.client.exceptions.BlobLocationNotFoundException: locations/040f06fd774092478d450774f5ba30c5da78acc8

>>> http_client.close()
>>> f.close()


Error Handling
==============

Expand All @@ -185,6 +197,7 @@ timeout exception::
... '
... ''')
{...}
>>> http_client.close()

It's possible to define a HTTP timeout in seconds on client instantiation, so
an exception is raised when the timeout is reached::
Expand All @@ -194,6 +207,7 @@ an exception is raised when the timeout is reached::
Traceback (most recent call last):
...
crate.client.exceptions.ConnectionError: No more Servers available, exception from last server: ...
>>> http_client.close()

When connecting to non-CrateDB servers, the HttpClient will raise a ConnectionError like this::

Expand All @@ -203,6 +217,7 @@ When connecting to non-CrateDB servers, the HttpClient will raise a ConnectionEr
...
crate.client.exceptions.ProgrammingError: Invalid server response of content-type 'text/html; charset=utf-8':
...
>>> http_client.close()

When using the ``error_trace`` kwarg a full traceback of the server exception
will be provided::
Expand All @@ -217,3 +232,4 @@ will be provided::
>>> print(trace)
TRACE: ... mismatched input 'error' expecting {<EOF>, ...
at io.crate...
>>> http_client.close()
5 changes: 4 additions & 1 deletion docs/by-example/sqlalchemy/cru.rst
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ Refresh "characters" table:
>>> pprint(char.details)
{'name': {'first': 'Trillian', 'last': 'Dent'}, 'size': 45}

.. Hidden: close connection

.. hidden: Disconnect from database
>>> session.close()
>>> connection.close()
>>> engine.dispose()
18 changes: 12 additions & 6 deletions docs/by-example/sqlalchemy/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -380,22 +380,23 @@ First the table definition as class:

As seen below the table doesn't exist yet:

>>> conn = engine.connect()
>>> engine.dialect.has_table(conn, table_name='departments')
>>> engine.dialect.has_table(connection, table_name='departments')
False

In order to create all missing tables the ``create_all`` method can be used:
In order to create all missing tables, the ``create_all`` method can be used:

>>> Base.metadata.create_all(bind=engine)

>>> engine.dialect.has_table(conn, table_name='departments')
With that, the table has been created:

>>> engine.dialect.has_table(connection, table_name='departments')
True

>>> stmt = ("select table_name, column_name, ordinal_position, data_type "
... "from information_schema.columns "
... "where table_name = 'departments' "
... "order by column_name")
>>> pprint([str(r) for r in conn.execute(stmt)])
>>> pprint([str(r) for r in connection.execute(stmt)])
["('departments', 'code', 3, 'integer')",
"('departments', 'id', 1, 'text')",
"('departments', 'name', 2, 'text')"]
Expand All @@ -408,7 +409,7 @@ delete a single table use ``drop(...)`` as shown below:

>>> Base.metadata.tables['departments'].drop(engine)

>>> engine.dialect.has_table(conn, table_name='departments')
>>> engine.dialect.has_table(connection, table_name='departments')
False

Insert From Select
Expand Down Expand Up @@ -466,5 +467,10 @@ This will result in the following query:
>>> pprint([str(r) for r in session.execute("Select content from archived_tasks")])
["('Write Tests',)"]

.. hidden: Disconnect from database
>>> session.close()
>>> connection.close()
>>> engine.dispose()
.. _count result rows: http://docs.sqlalchemy.org/en/14/orm/tutorial.html#counting
2 changes: 1 addition & 1 deletion docs/by-example/sqlalchemy/inspection-reflection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Check if table exists:
True


.. Hidden: close connection
.. hidden: Disconnect from database
>>> connection.close()
>>> engine.dispose()
Expand Down
6 changes: 5 additions & 1 deletion src/crate/client/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ def setUpWithCrateLayer(test):
cursor.execute("CREATE USER me WITH (password = 'my_secret_pw')")
cursor.execute("CREATE USER trusted_me")

cursor.close()


def setUpCrateLayerAndSqlAlchemy(test):
setUpWithCrateLayer(test)
Expand Down Expand Up @@ -166,6 +168,7 @@ def setUpCrateLayerAndSqlAlchemy(test):
engine = sa.create_engine(f"crate://{crate_host}")
for ddl_statement in ddl_statements:
engine.execute(sa.text(ddl_statement))
engine.dispose()


class HttpsTestServerLayer:
Expand Down Expand Up @@ -280,6 +283,7 @@ def _try_execute(cursor, stmt):
def tearDownWithCrateLayer(test):
# clear testing data
with connect(crate_host) as conn:
cursor = conn.cursor()
for stmt in ["DROP TABLE locations",
"DROP BLOB TABLE myfiles",
"DROP TABLE characters",
Expand All @@ -288,7 +292,7 @@ def tearDownWithCrateLayer(test):
"DROP USER me",
"DROP USER trusted_me",
]:
_try_execute(conn.cursor(), stmt)
_try_execute(cursor, stmt)


def test_suite():
Expand Down

0 comments on commit 8b30897

Please sign in to comment.