Merge lp:~canonical-isd-hackers/canonical-identity-provider/sqlcachedflush-consistency into lp:canonical-identity-provider/release

Proposed by Ricardo Kirkner
Status: Merged
Merge reported by: Łukasz Czyżykowski
Merged at revision: not available
Proposed branch: lp:~canonical-isd-hackers/canonical-identity-provider/sqlcachedflush-consistency
Merge into: lp:canonical-identity-provider/release
Diff against target: 117 lines (+88/-5)
2 files modified
identityprovider/management/commands/sqlcachedflush.py (+31/-5)
identityprovider/tests/test_command_sqlcachedflush.py (+57/-0)
To merge this branch: bzr merge lp:~canonical-isd-hackers/canonical-identity-provider/sqlcachedflush-consistency
Reviewer Review Type Date Requested Status
Łukasz Czyżykowski (community) Approve
Review via email: mp+25085@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Łukasz Czyżykowski (lukasz-czyzykowski) wrote :

Nothing to fix

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'identityprovider/management/commands/sqlcachedflush.py'
2--- identityprovider/management/commands/sqlcachedflush.py 2010-04-21 15:29:24 +0000
3+++ identityprovider/management/commands/sqlcachedflush.py 2010-05-11 17:01:29 +0000
4@@ -1,20 +1,46 @@
5 # Copyright 2010 Canonical Ltd. This software is licensed under the
6 # GNU Affero General Public License version 3 (see the file LICENSE).
7
8+from django.core.management.base import CommandError
9+from django.core.management.color import no_style
10 from django.core.management.commands.flush import Command as FlushCommand
11-from django.core.management.color import no_style
12
13
14 class Command(FlushCommand):
15 cached_flush = None
16
17 def handle_noargs(self, **options):
18- from django.db import connection
19- from django.core.management.sql import sql_flush
20+ from django.conf import settings
21+ from django.core.management.sql import sql_flush, emit_post_sync_signal
22+ from django.db import connection, transaction, models
23+
24+ verbosity = int(options.get('verbosity', 1))
25+ interactive = options.get('interactive')
26+
27 self.style = no_style()
28+
29 if self.cached_flush is not None:
30- cursor = connection.cursor()
31- cursor.execute(self.cached_flush)
32+ try:
33+ cursor = connection.cursor()
34+ cursor.execute(self.cached_flush)
35+ except Exception, e:
36+ transaction.rollback_unless_managed()
37+ raise CommandError("""Database %s couldn't be flushed. Possible reasons:
38+ * The database isn't running or isn't configured correctly.
39+ * At least one of the expected database tables doesn't exist.
40+ * The SQL was invalid.
41+ Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
42+ The full error: %s""" % (settings.DATABASE_NAME, e))
43+ transaction.commit_unless_managed()
44+
45+ # Emit the post sync signal. This allows individual
46+ # applications to respond as if the database had been
47+ # sync'd from scratch.
48+ emit_post_sync_signal(models.get_models(), verbosity, interactive)
49+
50+ # Reinstall the initial_data fixture.
51+ from django.core.management import call_command
52+ call_command('loaddata', 'initial_data', **options)
53 else:
54 super(Command, self).handle_noargs(**options)
55 # Call sql_flush instead of picking up the raw queries because
56
57=== added file 'identityprovider/tests/test_command_sqlcachedflush.py'
58--- identityprovider/tests/test_command_sqlcachedflush.py 1970-01-01 00:00:00 +0000
59+++ identityprovider/tests/test_command_sqlcachedflush.py 2010-05-11 17:01:29 +0000
60@@ -0,0 +1,57 @@
61+# Copyright 2010 Canonical Ltd. This software is licensed under the
62+# GNU Affero General Public License version 3 (see the file LICENSE).
63+
64+import signal
65+from subprocess import Popen, PIPE
66+
67+from django.conf import settings
68+from django.core.management import call_command
69+
70+from identityprovider.tests.utils import SQLCachedTestCase
71+
72+
73+class Alarm(Exception):
74+ pass
75+
76+
77+def alarm_handler(signum, frame):
78+ raise Alarm
79+
80+
81+class SQLCachedFlushCommandTestCase(SQLCachedTestCase):
82+ def setUp(self):
83+ # set alarm handler
84+ self.old_signal = signal.signal(signal.SIGALRM, alarm_handler)
85+
86+ def tearDown(self):
87+ # reset alarm handler
88+ signal.signal(signal.SIGALRM, self.old_signal)
89+
90+ def test_sqlcachedflush_command(self):
91+ args = ['pg_dump']
92+ if settings.DATABASE_USER:
93+ args.extend(['-U', settings.DATABASE_USER])
94+ if settings.DATABASE_PASSWORD:
95+ _PGPASS = os.environ['PGPASSWORD']
96+ os.environ['PGPASSWORD'] = settings.DATABASE_PASSWORD
97+ if settings.DATABASE_HOST:
98+ args.extend(['-h', settings.DATABASE_HOST])
99+ if settings.DATABASE_PORT:
100+ args.extend(['-p', settings.DATABASE_PORT])
101+ args.append(settings.DATABASE_NAME)
102+
103+ call_command('flush', interactive=False)
104+ flush_sql = Popen(args, stdout=PIPE).communicate()[0]
105+
106+ call_command('sqlcachedflush', interactive=False)
107+ # timeout after 5 seconds
108+ signal.alarm(5)
109+ try:
110+ sqlcachedflush_sql = Popen(args, stdout=PIPE).communicate()[0]
111+ # reset the alarm
112+ signal.alarm(0)
113+ except Alarm:
114+ self.fail()
115+
116+ self.assertEqual(sqlcachedflush_sql, flush_sql)
117+