On 12/28/2010 01:33 PM, Gaetan de Menten wrote:
On Tue, Dec 28, 2010 at 17:10, Rob<[email protected]> wrote:
We have several unit tests for our Elixir-based app. One of them is
failing after calling an external program (also elixir-based), which
modifies the row. An email address field with a default='', is
returned from the instance as empty string, while in reality it has
been set to some real email address.
This occurs intermittently!
. . .
If I change the setUp to re-bind each time, it seems the problem goes
away.
Can't say much without seeing some code. This smells like a thread
problem. If you are using a sqlite in-memory database, look no further
(they are thread-local).
Thank you. I greatly appreciate your reply.
I'm using Postgresql 8.4, Elixir 0.7.1-1, SQLAlchemy 0.5.8-1, on Ubuntu
10.4 (lucid).
When I set metadata.bind.echo=True, I can see the query on the table in
question, but the elixir entity instance doesn't seem to apply it to
it's email_address attribute. It's crazy because it only happens maybe
one out 5 or 10 runs. If I do the session.refresh(obj) on the instance
immediately after the query, the correct values show up. Also, instead
if I call expunge_all() immediately after the return of the externally
spawned elixir process, the correct value also shows up. Plus as I
mentioned, if I instead re-bind to the database before each unit test of
the TestCase, then the correct value also shows consistently. Also, if
all other tests are disabled, the error never occurs.
Here's some actual code snippets to get the idea of the flow:
Process Initialization:
self.engine = sqlalchemy.create_engine(dburl)
elixir.metadata.bind = self.engine
elixir.setup_all()
Prior to each unit test (setUp):
# if I re-assign to metadata.bind here,
# the problem goes away.
# metadata.bind = 'postgres://:@/testdb' #fixes it.
session.bind = metadata.bind
self.check_version(min_postgres_version())
session.rollback()
self.DropDependentObjects() #drop triggers, views, PL/pgSQL.
metadata.drop_all()
session.commit()
metadata.create_all()
session.commit()
#following use session.execute(sql):
self.InitializeDefaults()
session.commit()
session.flush()
session.expunge_all()
After each unit test:
# previously I had only session.close(),
# I've been trying combinations of these:
try:
elixir.session.commit()
except:
elixir.session.rollback()
elixir.session.expire_all()
elixir.session.expunge_all()
elixir.session.close_all()
elixir.session.close()
elixir.session.remove()
This is the actual failing unit test (any of the lines commented "THIS
HELPS" will individually fix the problem.)
def test_record_created(self):
self.assertEquals(0, len(model.Foo.query.all()))
AddTestData(True, date.today())
self.assertEquals(0, len(model.Foo.query.all()))
self.assertEquals(1, len(model.Bar.query.all()))
output, return_code = RunGenerateFoo()
#elixir.session.expunge_all() #THIS
HELPS
self.assertEqual(output, 'RECORD_CREATED')
self.assertEqual(return_code, 0)
self.assertEquals(1, len(model.Foo.query.all()))
self.assertEquals(1, len(model.Bar.query.all()))
#elixir.session.expunge_all() #THIS
HELPS
foo = model.Foo.query.first()
self.assertEquals(model.TransferStatus.get_by(name='pending'),
foo.transfer_status)
self.assertEquals('test_AB_20101223141359.foo', foo.foo_filename)
#
# Problem area:
#
bar = model.Bar.get_by(license='LICENSE1', prefix='pref2')
#elixir.session.refresh(bar) #THIS HELPS
#elixir.session.expunge(bar) #THIS
HELPS (2 lines)
#bar = model.Bar.get_by(license='LICENSE1', prefix='pref2')
self.assertEquals('[email protected]', bar.email_address) #
<-- fails if all of the "THIS HELPS" lines are commented
# and the metatdata is not re-binded before the test.
Thank you,
Rob
--
You received this message because you are subscribed to the Google Groups
"SQLElixir" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlelixir?hl=en.