|
10 | 10 | import pytest |
11 | 11 | from alembic import config |
12 | 12 | from alembic.command import upgrade |
| 13 | +from sqlalchemy import event |
| 14 | +from sqlalchemy.engine import Engine |
13 | 15 | from sqlalchemy.orm import Session, scoped_session, sessionmaker |
14 | 16 |
|
15 | 17 | from grader_service import GraderService, handlers |
|
18 | 20 | from grader_service.orm import User |
19 | 21 | from grader_service.registry import HandlerPathRegistry |
20 | 22 | from grader_service.server import GraderServer |
21 | | -from grader_service.tests.handlers.db_util import insert_assignments, insert_lectures |
| 23 | +from grader_service.tests.handlers.db_util import ( |
| 24 | + insert_assignments, |
| 25 | + insert_default_user, |
| 26 | + insert_lectures, |
| 27 | +) |
| 28 | + |
| 29 | + |
| 30 | +@pytest.fixture(scope="function") |
| 31 | +def set_database_type_to_sqlite(): |
| 32 | + """ |
| 33 | + Set the DATABASE_TYPE env var to "sqlite" and register a listener |
| 34 | + which enables foreign keys support for SQLite database. |
| 35 | + Unset the var after the test runs. |
| 36 | +
|
| 37 | + This is a hack, because normally `DATABASE_TYPE` is not set when tests run. |
| 38 | + It also cannot be set to "sqlite" by default, because we have some tests |
| 39 | + running on PostgreSQL, where executing the sqlite pragma would cause an error. |
| 40 | +
|
| 41 | + Outside the test setting, the DATABASE_TYPE environment variable is set, and |
| 42 | + the event listener is registered in grader_service/orm/base.py. |
| 43 | + """ |
| 44 | + os.environ["DATABASE_TYPE"] = "sqlite" |
| 45 | + |
| 46 | + # Original code taken from the SQLAlchemy documentation, here slightly adjusted: |
| 47 | + # https://docs.sqlalchemy.org/en/20/dialects/sqlite.html#foreign-key-support |
| 48 | + @event.listens_for(Engine, "connect") |
| 49 | + def set_sqlite_pragma(dbapi_connection, connection_record): |
| 50 | + database_type = os.getenv("DATABASE_TYPE") |
| 51 | + if database_type == "sqlite": |
| 52 | + # the sqlite3 driver will not set PRAGMA foreign_keys |
| 53 | + # if autocommit=False; set to True temporarily |
| 54 | + ac = dbapi_connection.autocommit |
| 55 | + dbapi_connection.autocommit = True |
| 56 | + |
| 57 | + cursor = dbapi_connection.cursor() |
| 58 | + # Note: this is a SQLite-specific pragma |
| 59 | + cursor.execute("PRAGMA foreign_keys=ON") |
| 60 | + cursor.close() |
| 61 | + |
| 62 | + # restore previous autocommit setting |
| 63 | + dbapi_connection.autocommit = ac |
| 64 | + |
| 65 | + yield |
| 66 | + # Unset the variable for other tests, which may use a different database type |
| 67 | + os.environ.pop("DATABASE_TYPE") |
22 | 68 |
|
23 | 69 |
|
24 | 70 | @pytest.fixture(scope="function") |
@@ -68,6 +114,7 @@ def sql_alchemy_sessionmaker(db_test_config): |
68 | 114 | upgrade(db_test_config, "head") |
69 | 115 | insert_lectures(engine) |
70 | 116 | insert_assignments(engine) |
| 117 | + insert_default_user(engine) |
71 | 118 | yield session_maker |
72 | 119 |
|
73 | 120 |
|
|
0 commit comments