Files
jupyterhub/jupyterhub/tests/test_db.py
Min RK 51b6376634 require sqlalchemy 1.4
removes some workarounds needed for sqlalchemy 1.1 + 2.0 support

1.4 backports most 2.0 behavior, keeping it off-by-default for an easier opt-in transition

opt-in with `session.future = True` flag
2023-01-27 14:15:02 +01:00

93 lines
2.8 KiB
Python

import os
import sys
import tempfile
from glob import glob
from subprocess import check_call
import pytest
from packaging.version import parse as V
from pytest import raises
from traitlets.config import Config
from .. import orm
from ..app import NewToken, UpgradeDB
from ..scopes import _check_scopes_exist
here = os.path.abspath(os.path.dirname(__file__))
populate_db = os.path.join(here, 'populate_db.py')
def generate_old_db(env_dir, hub_version, db_url):
"""Generate an old jupyterhub database
Installs a particular jupyterhub version in a virtualenv
and runs populate_db.py to populate a database
"""
env_pip = os.path.join(env_dir, 'bin', 'pip')
env_py = os.path.join(env_dir, 'bin', 'python')
check_call([sys.executable, '-m', 'virtualenv', env_dir])
pkgs = ['jupyterhub==' + hub_version]
# older jupyterhub needs older sqlachemy version
if V(hub_version) < V("2"):
pkgs.append('sqlalchemy<1.4')
elif V(hub_version) < V("3.1.1"):
pkgs.append('sqlalchemy<2')
if 'mysql' in db_url:
pkgs.append('mysql-connector-python')
elif 'postgres' in db_url:
pkgs.append('psycopg2-binary')
check_call([env_pip, 'install'] + pkgs)
check_call([env_py, populate_db, db_url])
# changes to this version list must also be reflected
# in ci/init-db.sh
@pytest.mark.parametrize('hub_version', ["1.1.0", "1.2.2", "1.3.0", "1.5.0", "2.1.1"])
async def test_upgrade(tmpdir, hub_version):
db_url = os.getenv('JUPYTERHUB_TEST_DB_URL')
if db_url:
db_url += '_upgrade_' + hub_version.replace('.', '')
else:
db_url = 'sqlite:///jupyterhub.sqlite'
tmpdir.chdir()
# use persistent temp env directory
# to reuse across multiple runs
env_dir = os.path.join(tempfile.gettempdir(), 'test-hub-upgrade-%s' % hub_version)
generate_old_db(env_dir, hub_version, db_url)
cfg = Config()
cfg.JupyterHub.db_url = db_url
tokenapp = NewToken(config=cfg)
tokenapp.initialize(['admin'])
with raises(SystemExit):
tokenapp.start()
if 'sqlite' in db_url:
fname = db_url.split(':///')[1]
sqlite_files = glob(os.path.join(str(tmpdir), 'jupyterhub.sqlite*'))
assert len(sqlite_files) == 1
upgradeapp = UpgradeDB(config=cfg)
upgradeapp.initialize([])
upgradeapp.start()
# check that backup was created:
if 'sqlite' in db_url:
sqlite_files = glob(os.path.join(str(tmpdir), 'jupyterhub.sqlite*'))
assert len(sqlite_files) == 2
# run tokenapp again, it should work
tokenapp.start()
db = orm.new_session_factory(db_url)()
query = db.query(orm.APIToken)
assert query.count() >= 1
for token in query:
assert token.scopes, f"Upgraded token {token} has no scopes"
_check_scopes_exist(token.scopes)