| # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 |
| # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt |
| |
| """Tests for coverage.sqlitedb""" |
| |
| from __future__ import annotations |
| |
| from typing import NoReturn |
| from unittest import mock |
| |
| import pytest |
| |
| import coverage.sqlitedb |
| from coverage.exceptions import DataError |
| from coverage.sqlitedb import SqliteDb |
| |
| from tests.coveragetest import CoverageTest |
| from tests.helpers import DebugControlString, FailingProxy |
| |
| DB_INIT = """\ |
| create table name (first text, last text); |
| insert into name (first, last) values ("pablo", "picasso"); |
| """ |
| |
| |
| class SqliteDbTest(CoverageTest): |
| """Tests of tricky parts of SqliteDb.""" |
| |
| def test_error_reporting(self) -> None: |
| msg = "Couldn't use data file 'test.db': no such table: bar" |
| with SqliteDb("test.db", DebugControlString(options=["sql"])) as db: |
| with pytest.raises(DataError, match=msg): |
| with db.execute("select foo from bar"): |
| # Entering the context manager raises the error, this line doesn't run: |
| pass # pragma: not covered |
| |
| def test_retry_execute(self) -> None: |
| with SqliteDb("test.db", DebugControlString(options=["sql"])) as db: |
| db.executescript(DB_INIT) |
| proxy = FailingProxy(db.con, "execute", [Exception("WUT")]) |
| with mock.patch.object(db, "con", proxy): |
| with db.execute("select first from name order by 1") as cur: |
| assert list(cur) == [("pablo",)] |
| |
| def test_retry_execute_failure(self) -> None: |
| with SqliteDb("test.db", DebugControlString(options=["sql"])) as db: |
| db.executescript(DB_INIT) |
| proxy = FailingProxy(db.con, "execute", [Exception("WUT"), RuntimeError("Fake")]) |
| with mock.patch.object(db, "con", proxy): |
| with pytest.raises(RuntimeError, match="Fake"): |
| with db.execute("select first from name order by 1"): |
| # Entering the context manager raises the error, this line doesn't run: |
| pass # pragma: not covered |
| |
| def test_retry_executemany_void(self) -> None: |
| with SqliteDb("test.db", DebugControlString(options=["sql"])) as db: |
| db.executescript(DB_INIT) |
| proxy = FailingProxy(db.con, "executemany", [Exception("WUT")]) |
| with mock.patch.object(db, "con", proxy): |
| db.executemany_void( |
| "insert into name (first, last) values (?, ?)", |
| [("vincent", "van gogh")], |
| ) |
| with db.execute("select first from name order by 1") as cur: |
| assert list(cur) == [("pablo",), ("vincent",)] |
| |
| def test_retry_executemany_void_failure(self) -> None: |
| with SqliteDb("test.db", DebugControlString(options=["sql"])) as db: |
| db.executescript(DB_INIT) |
| proxy = FailingProxy(db.con, "executemany", [Exception("WUT"), RuntimeError("Fake")]) |
| with mock.patch.object(db, "con", proxy): |
| with pytest.raises(RuntimeError, match="Fake"): |
| db.executemany_void( |
| "insert into name (first, last) values (?, ?)", |
| [("vincent", "van gogh")], |
| ) |
| |
| def test_open_fails_on_bad_db(self) -> None: |
| self.make_file("bad.db", "boogers") |
| |
| def fake_failing_open(filename: str, mode: str) -> NoReturn: |
| assert (filename, mode) == ("bad.db", "rb") |
| raise RuntimeError("No you can't!") |
| |
| with mock.patch.object(coverage.sqlitedb, "open", fake_failing_open): |
| msg = "Couldn't use data file 'bad.db': file is not a database" |
| with pytest.raises(DataError, match=msg): |
| with SqliteDb("bad.db", DebugControlString(options=["sql"])): |
| pass # pragma: not covered |
| |
| def test_execute_void_can_allow_failure(self) -> None: |
| with SqliteDb("fail.db", DebugControlString(options=["sql"])) as db: |
| db.executescript(DB_INIT) |
| proxy = FailingProxy(db.con, "execute", [Exception("WUT")]) |
| with mock.patch.object(db, "con", proxy): |
| db.execute_void("select x from nosuchtable", fail_ok=True) |
| |
| def test_execute_void_can_refuse_failure(self) -> None: |
| with SqliteDb("fail.db", DebugControlString(options=["sql"])) as db: |
| db.executescript(DB_INIT) |
| proxy = FailingProxy(db.con, "execute", [Exception("WUT")]) |
| with mock.patch.object(db, "con", proxy): |
| msg = "Couldn't use data file 'fail.db': no such table: nosuchtable" |
| with pytest.raises(DataError, match=msg): |
| db.execute_void("select x from nosuchtable", fail_ok=False) |