django-nose
django-nose copied to clipboard
REUSE_DB for tests fails when using django-guardian's ANONYMOUS_USER_ID as -1
Was unsure whether this one really belonged here or with django-guardian, so apologies in advance if this is inappropriate.
Briefly, when using django-guardian (https://github.com/lukaszb/django-guardian) with the ANONYMOUS_USER_ID set to -1, tests work perfectly the first time round. However, when using REUSE_DB, on a second pass, django_nose cannot reset the database successfully.
Using the ANONYMOUS_USER_ID of -1 as suggested in the documentation for django-guardian (http://django-guardian.readthedocs.org/en/latest/configuration.html), reusing the database to run tests fails when resetting the database to it's 'clean' state. The error given is as follows:
django.db.utils.DatabaseError: setval: value -1 is out of bounds for sequence "auth_user_id_seq" (1..9223372036854775807)
Examining the reset statements, the one causing the error is:
SELECT setval(pg_get_serial_sequence('"auth_user"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "auth_user";
The User object with id of -1 is created automatically by a signal hooked to post_syncdb in django_guardian's management/init.py.
Using: Django 1.4.3, django-guardian 1.0.4, postgres 9.1 with postgis 1.5.
Django engine: django.contrib.gis.db.backends.postgis
The full stack trace:
Traceback (most recent call last):
File "./manage.py", line 9, in <module>
execute_from_command_line(sys.argv)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
utility.execute()
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 49, in run_from_argv
super(Command, self).run_from_argv(argv)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv
self.execute(*args, **options.__dict__)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute
output = self.handle(*args, **options)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/south/management/commands/test.py", line 8, in handle
super(Command, self).handle(*args, **kwargs)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 72, in handle
failures = test_runner.run_tests(test_labels)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django_nose/runner.py", line 155, in run_tests
result = self.run_suite(nose_argv)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django_nose/runner.py", line 117, in run_suite
addplugins=plugins_to_add)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/nose/core.py", line 118, in __init__
**extra_args)
File "/usr/lib/python2.7/unittest/main.py", line 95, in __init__
self.runTests()
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/nose/core.py", line 197, in runTests
result = self.testRunner.run(self.test)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/nose/core.py", line 50, in run
wrapper = self.config.plugins.prepareTest(test)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/nose/plugins/manager.py", line 99, in __call__
return self.call(*arg, **kw)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/nose/plugins/manager.py", line 167, in simple
result = meth(*arg, **kw)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django_nose/plugin.py", line 78, in prepareTest
self.old_names = self.runner.setup_databases()
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django_nose/runner.py", line 308, in setup_databases
cursor.execute(reset_statement)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/db/backends/util.py", line 40, in execute
return self.cursor.execute(sql, params)
File "/home/tony/.virtualenvs/trialreach/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 52, in execute
return self.cursor.execute(query, args)
django.db.utils.DatabaseError: setval: value -1 is out of bounds for sequence "auth_user_id_seq" (1..9223372036854775807)
I tried to reproduce this but I literally ran out of HD space installing the required PG / GIS stuff. If you have spatialite installed, could you try it, to see if it fixes the bug?
This is what you get when you partition a 90G hard drive in two.
I have exactly the same error using postgres. What about spatialite? What should we try?
Same thing here! Any idea on how to tackle this?
I came across the same problem. Is there a solution for this yet?
I remember we found a workaround at the time but I don't remember how. Quite a long time ago already.
I actually did find a workaround by simply defining ANONYMOUS_USER_ID = 2147483647 in the settings for my tests
Oh yes I remember we did ANONYMOUS_USER_ID = 0
rather than -1
I tried that, but i got the same error since the sequence seems to start at 1, so I simply selected max_int.
ok, it gets weird:
If i set ANONYMOUS_USER_ID = 2147483647
as I said before, everything works fine as long as I don't actually generate any users.
I just wrote the first test where I need a user, so I create one. If I delete the database and start off fresh, the new user gets ID 1 as expected. If it is the second time, the new user gets ID 2147483648 which is out of range and throws an error.
I therefor now switched to using ANONYMOUS_USER_ID = 1073741824
since it gives me the most amount of users for the first and all following runs.
~~Interestingly enough, for ALL subsequent runs, the first ID that is assigned to a user is always 1073741825, so it seems to get reseted on every run.~~ Never mind this part. This only happened since my test did not run through.
In case this helps anyone else struggling with this: For me, ANONYMOUS_USER_ID = 2147483647
failed with an out-of-range error that I didn't investigate. Setting it to 99999 did the trick though. After that, I got another error from runner.py: "TypeError: method expected 2 arguments, got 3", but that was because I had an old version of django_nose, fixed by upgrading to 1.4.1. Then I was scared of the reports that this connects to the real (not test) database for (perhaps) the first test in every test run, which I think I defused by manually applying this change to the django_nose in my virtualenv: https://github.com/django-nose/django-nose/pull/137/files. REUSE_DB now works for me, am very happy.