Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tell warehouse.db to reuse db_session pytest fixture #16031

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
aec26e8
WIP -- test still fails with 404.
jzohrab Mar 31, 2024
0097571
Merge branch 'main' of https://github.com/pypi/warehouse into issue_1…
benjaoming May 31, 2024
9957047
Tell warehouse.db to reuse db_session test fixture
benjaoming May 31, 2024
179424d
Clean up, add some comments
benjaoming May 31, 2024
fc7ad47
Remove debugging from previous PR
benjaoming May 31, 2024
6f337c7
Add `request.environ` to stubs
benjaoming May 31, 2024
4a188d1
Merge branch 'main' of https://github.com/pypi/warehouse into issue_1…
benjaoming May 31, 2024
fea5974
Possibility to replace warehouse.db._create_session: Add an alternati…
benjaoming Jun 2, 2024
a58ce9f
Update a comment
benjaoming Jun 2, 2024
f255c0d
Remove commented out line
benjaoming Jun 2, 2024
9369e47
Don't register with zope.sqlalchemy.register, handled elsewhere
benjaoming Jun 2, 2024
7a83ec5
Merge branch 'issue_15634_test_user_profile-investigation-new-app_con…
benjaoming Jun 11, 2024
fa19e40
Use `config.registry.settings` instead of `config.get_settings()`
benjaoming Jun 11, 2024
e818365
Revert unnecessary changes to test_db
benjaoming Jun 11, 2024
44f70aa
Apply suggestions from code review
benjaoming Jun 17, 2024
a18fb6b
Code review: Combine into one line
benjaoming Jun 17, 2024
8a1ce79
Merge previous TransactionManager (`tm`) fixture into `webtest` fixture
benjaoming Jun 17, 2024
17322d1
Create database sessions in a fixture helper, reading from an app_config
benjaoming Jun 20, 2024
fdcfac3
Merge branch 'main' into issue_15634_test_user_profile-investigation
miketheman Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/common/db/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class UserFactory(WarehouseFactory):
class Meta:
model = User
# sqlalchemy_session_persistence = 'commit'
benjaoming marked this conversation as resolved.
Show resolved Hide resolved

username = factory.Faker("pystr", max_chars=12)
name = factory.Faker("word")
Expand Down
39 changes: 31 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import pyramid.testing
import pytest
import stripe
import transaction
import webtest as _webtest
import zope.sqlalchemy

from jinja2 import Environment, FileSystemLoader
from psycopg.errors import InvalidCatalogName
Expand Down Expand Up @@ -622,18 +624,39 @@ def xmlrpc(self, path, method, *args):


@pytest.fixture
def webtest(app_config):
# TODO: Ensure that we have per test isolation of the database level
# changes. This probably involves flushing the database or something
# between test cases to wipe any committed changes.
def tm():
tm = transaction.TransactionManager(explicit=True)
tm.begin()
tm.doom()

yield tm

tm.abort()


@pytest.fixture
def webtest(app_config, tm, db_session):
# We want to disable anything that relies on TLS here.
app_config.add_settings(enforce_https=False)

try:
yield _TestApp(app_config.make_wsgi_app())
finally:
app_config.registry["sqlalchemy.engine"].dispose()
miketheman marked this conversation as resolved.
Show resolved Hide resolved
# Register the transaction manager with the db_session
zope.sqlalchemy.register(db_session, transaction_manager=tm)
benjaoming marked this conversation as resolved.
Show resolved Hide resolved

# Create WSGI app with current test settings
# (this could be a fixture)
app = app_config.make_wsgi_app()

# Register the app with the external test environment, telling
# warehouse.db to use this db_session and use the Transaction manager.
benjaoming marked this conversation as resolved.
Show resolved Hide resolved
testapp = _TestApp(
app,
extra_environ={
"warehouse.db_session": db_session,
"tm.active": True, # disable pyramid_tm
"tm.manager": tm, # pass in our own tm for the app to use
},
)
yield testapp


class _MockRedis:
Expand Down
30 changes: 30 additions & 0 deletions tests/functional/test_user_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tests.common.db.accounts import UserFactory


def test_user_profile(webtest):
"""
This test is maintained as a POC for future tests that want to add data to
the database and test HTTP endpoints afterwards.

The trick is to use the ``webtest`` fixture which will create a special
instance of the Warehouse WSGI app, sharing the same DB session as is active
in pytest.
"""
# Create a user
user = UserFactory.create()
assert user.username
# ...and verify that the user's profile page exists
resp = webtest.get(f"/user/{user.username}/")
assert resp.status_code == 200
3 changes: 3 additions & 0 deletions tests/unit/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def raiser():
request = pretend.stub(
find_service=pyramid_services.find_service,
registry={"sqlalchemy.engine": engine},
environ={},
)

with pytest.raises(DatabaseNotAvailableError):
Expand Down Expand Up @@ -151,6 +152,7 @@ def test_create_session(monkeypatch, pyramid_services):
registry={"sqlalchemy.engine": engine},
tm=pretend.stub(),
add_finished_callback=pretend.call_recorder(lambda callback: None),
environ={},
)

request2 = pretend.stub()
Expand Down Expand Up @@ -212,6 +214,7 @@ def test_create_session_read_only_mode(
tm=pretend.stub(doom=pretend.call_recorder(lambda: None)),
add_finished_callback=lambda callback: None,
user=pretend.stub(is_superuser=is_superuser),
environ={},
)

assert _create_session(request) is session_obj
Expand Down
6 changes: 6 additions & 0 deletions warehouse/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ def _configure_alembic(config):


def _create_session(request):

benjaoming marked this conversation as resolved.
Show resolved Hide resolved
# Use pre-configured db session (usually for integration test transactions)
db_session = request.environ.get("warehouse.db_session")
miketheman marked this conversation as resolved.
Show resolved Hide resolved
if db_session:
return db_session

metrics = request.find_service(IMetricsService, context=None)
metrics.increment("warehouse.db.session.start")

Expand Down