From 59f5beff1928e752b33d65a541cd68295ae0a5f1 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 7 Dec 2022 14:23:45 -0500 Subject: [PATCH] move more Session weakref tests to test_memusage py311 may be more sensitive here, or maybe the machines are acting differently these days, in any case move memory / GC sensitive tests to test_memusage. Change-Id: I218295150efc2f7ea88da9960ff10fda63dc60b1 --- test/aaa_profiling/test_memusage.py | 167 ++++++++++++++++++++++++++++ test/orm/test_session.py | 163 +-------------------------- 2 files changed, 169 insertions(+), 161 deletions(-) diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py index 4756a3fd5c..d30ccb3b8c 100644 --- a/test/aaa_profiling/test_memusage.py +++ b/test/aaa_profiling/test_memusage.py @@ -2,6 +2,7 @@ import decimal import gc import itertools import multiprocessing +import pickle import weakref import sqlalchemy as sa @@ -38,6 +39,7 @@ from sqlalchemy.sql.visitors import replacement_traverse from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures +from sqlalchemy.testing import pickleable from sqlalchemy.testing.fixtures import fixture_session from sqlalchemy.testing.schema import Column from sqlalchemy.testing.schema import Table @@ -1778,3 +1780,168 @@ class MiscMemoryIntensiveTests(fixtures.TestBase): s.flush() eq_(s.scalar(select(func.count("*")).select_from(User.__table__)), 0) s.commit() + + +class WeakIdentityMapTest(_fixtures.FixtureTest): + run_inserts = None + + @testing.requires.predictable_gc + def test_weakref(self): + """test the weak-referencing identity map, which strongly- + references modified items.""" + + users, User = self.tables.users, self.classes.User + + s = fixture_session() + self.mapper_registry.map_imperatively(User, users) + gc_collect() + + s.add(User(name="ed")) + s.flush() + assert not s.dirty + + user = s.query(User).one() + + # heisenberg the GC a little bit, since #7823 caused a lot more + # GC when mappings are set up, larger test suite started failing + # on this being gc'ed + user_is = user._sa_instance_state + del user + gc_collect() + gc_collect() + gc_collect() + assert user_is.obj() is None + + assert len(s.identity_map) == 0 + + user = s.query(User).one() + user.name = "fred" + del user + gc_collect() + assert len(s.identity_map) == 1 + assert len(s.dirty) == 1 + assert None not in s.dirty + s.flush() + gc_collect() + assert not s.dirty + assert not s.identity_map + + user = s.query(User).one() + assert user.name == "fred" + assert s.identity_map + + @testing.requires.predictable_gc + def test_weakref_pickled(self): + users, User = self.tables.users, pickleable.User + + s = fixture_session() + self.mapper_registry.map_imperatively(User, users) + gc_collect() + + s.add(User(name="ed")) + s.flush() + assert not s.dirty + + user = s.query(User).one() + user.name = "fred" + s.expunge(user) + + u2 = pickle.loads(pickle.dumps(user)) + + del user + s.add(u2) + + del u2 + gc_collect() + + assert len(s.identity_map) == 1 + assert len(s.dirty) == 1 + assert None not in s.dirty + s.flush() + gc_collect() + assert not s.dirty + + assert not s.identity_map + + @testing.requires.predictable_gc + def test_weakref_with_cycles_o2m(self): + Address, addresses, users, User = ( + self.classes.Address, + self.tables.addresses, + self.tables.users, + self.classes.User, + ) + + s = fixture_session() + self.mapper_registry.map_imperatively( + User, + users, + properties={"addresses": relationship(Address, backref="user")}, + ) + self.mapper_registry.map_imperatively(Address, addresses) + gc_collect() + + s.add(User(name="ed", addresses=[Address(email_address="ed1")])) + s.commit() + + user = s.query(User).options(joinedload(User.addresses)).one() + user.addresses[0].user # lazyload + eq_(user, User(name="ed", addresses=[Address(email_address="ed1")])) + + del user + gc_collect() + assert len(s.identity_map) == 0 + + user = s.query(User).options(joinedload(User.addresses)).one() + user.addresses[0].email_address = "ed2" + user.addresses[0].user # lazyload + del user + gc_collect() + assert len(s.identity_map) == 2 + + s.commit() + user = s.query(User).options(joinedload(User.addresses)).one() + eq_(user, User(name="ed", addresses=[Address(email_address="ed2")])) + + @testing.requires.predictable_gc + def test_weakref_with_cycles_o2o(self): + Address, addresses, users, User = ( + self.classes.Address, + self.tables.addresses, + self.tables.users, + self.classes.User, + ) + + s = fixture_session() + self.mapper_registry.map_imperatively( + User, + users, + properties={ + "address": relationship(Address, backref="user", uselist=False) + }, + ) + self.mapper_registry.map_imperatively(Address, addresses) + gc_collect() + + s.add(User(name="ed", address=Address(email_address="ed1"))) + s.commit() + + user = s.query(User).options(joinedload(User.address)).one() + user.address.user + eq_(user, User(name="ed", address=Address(email_address="ed1"))) + + del user + gc_collect() + assert len(s.identity_map) == 0 + + user = s.query(User).options(joinedload(User.address)).one() + user.address.email_address = "ed2" + user.address.user # lazyload + + del user + gc_collect() + assert len(s.identity_map) == 2 + + s.commit() + user = s.query(User).options(joinedload(User.address)).one() + eq_(user, User(name="ed", address=Address(email_address="ed2"))) diff --git a/test/orm/test_session.py b/test/orm/test_session.py index 5ba180f5f0..79ea5d1703 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -18,7 +18,6 @@ from sqlalchemy.orm import attributes from sqlalchemy.orm import backref from sqlalchemy.orm import close_all_sessions from sqlalchemy.orm import exc as orm_exc -from sqlalchemy.orm import joinedload from sqlalchemy.orm import make_transient from sqlalchemy.orm import make_transient_to_detached from sqlalchemy.orm import object_session @@ -1644,166 +1643,8 @@ class NoCyclesOnTransientDetachedTest(_fixtures.FixtureTest): class WeakIdentityMapTest(_fixtures.FixtureTest): run_inserts = None - @testing.requires.predictable_gc - def test_weakref(self): - """test the weak-referencing identity map, which strongly- - references modified items.""" - - users, User = self.tables.users, self.classes.User - - s = fixture_session() - self.mapper_registry.map_imperatively(User, users) - gc_collect() - - s.add(User(name="ed")) - s.flush() - assert not s.dirty - - user = s.query(User).one() - - # heisenberg the GC a little bit, since #7823 caused a lot more - # GC when mappings are set up, larger test suite started failing - # on this being gc'ed - user_is = user._sa_instance_state - del user - gc_collect() - gc_collect() - gc_collect() - assert user_is.obj() is None - - assert len(s.identity_map) == 0 - - user = s.query(User).one() - user.name = "fred" - del user - gc_collect() - assert len(s.identity_map) == 1 - assert len(s.dirty) == 1 - assert None not in s.dirty - s.flush() - gc_collect() - assert not s.dirty - assert not s.identity_map - - user = s.query(User).one() - assert user.name == "fred" - assert s.identity_map - - @testing.requires.predictable_gc - def test_weakref_pickled(self): - users, User = self.tables.users, pickleable.User - - s = fixture_session() - self.mapper_registry.map_imperatively(User, users) - gc_collect() - - s.add(User(name="ed")) - s.flush() - assert not s.dirty - - user = s.query(User).one() - user.name = "fred" - s.expunge(user) - - u2 = pickle.loads(pickle.dumps(user)) - - del user - s.add(u2) - - del u2 - gc_collect() - - assert len(s.identity_map) == 1 - assert len(s.dirty) == 1 - assert None not in s.dirty - s.flush() - gc_collect() - assert not s.dirty - - assert not s.identity_map - - @testing.requires.predictable_gc - def test_weakref_with_cycles_o2m(self): - Address, addresses, users, User = ( - self.classes.Address, - self.tables.addresses, - self.tables.users, - self.classes.User, - ) - - s = fixture_session() - self.mapper_registry.map_imperatively( - User, - users, - properties={"addresses": relationship(Address, backref="user")}, - ) - self.mapper_registry.map_imperatively(Address, addresses) - gc_collect() - - s.add(User(name="ed", addresses=[Address(email_address="ed1")])) - s.commit() - - user = s.query(User).options(joinedload(User.addresses)).one() - user.addresses[0].user # lazyload - eq_(user, User(name="ed", addresses=[Address(email_address="ed1")])) - - del user - gc_collect() - assert len(s.identity_map) == 0 - - user = s.query(User).options(joinedload(User.addresses)).one() - user.addresses[0].email_address = "ed2" - user.addresses[0].user # lazyload - del user - gc_collect() - assert len(s.identity_map) == 2 - - s.commit() - user = s.query(User).options(joinedload(User.addresses)).one() - eq_(user, User(name="ed", addresses=[Address(email_address="ed2")])) - - @testing.requires.predictable_gc - def test_weakref_with_cycles_o2o(self): - Address, addresses, users, User = ( - self.classes.Address, - self.tables.addresses, - self.tables.users, - self.classes.User, - ) - - s = fixture_session() - self.mapper_registry.map_imperatively( - User, - users, - properties={ - "address": relationship(Address, backref="user", uselist=False) - }, - ) - self.mapper_registry.map_imperatively(Address, addresses) - gc_collect() - - s.add(User(name="ed", address=Address(email_address="ed1"))) - s.commit() - - user = s.query(User).options(joinedload(User.address)).one() - user.address.user - eq_(user, User(name="ed", address=Address(email_address="ed1"))) - - del user - gc_collect() - assert len(s.identity_map) == 0 - - user = s.query(User).options(joinedload(User.address)).one() - user.address.email_address = "ed2" - user.address.user # lazyload - - del user - gc_collect() - assert len(s.identity_map) == 2 - - s.commit() - user = s.query(User).options(joinedload(User.address)).one() - eq_(user, User(name="ed", address=Address(email_address="ed2"))) + # see test/aaa_profiling/test_memusage.py for more + # WeakIdentityMap tests def test_auto_detach_on_gc_session(self): users, User = self.tables.users, self.classes.User -- 2.47.2