Merge lp:~allenap/maas/notifications-triggers into lp:~maas-committers/maas/trunk

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 5646
Proposed branch: lp:~allenap/maas/notifications-triggers
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 177 lines (+141/-0)
3 files modified
src/maasserver/triggers/tests/test_init.py (+4/-0)
src/maasserver/triggers/tests/test_websocket_listener.py (+86/-0)
src/maasserver/triggers/websocket.py (+51/-0)
To merge this branch: bzr merge lp:~allenap/maas/notifications-triggers
Reviewer Review Type Date Requested Status
Lee Trager (community) Approve
Review via email: mp+314606@code.launchpad.net

Commit message

Database triggers for the Notification and NotificationDismissal models.

To post a comment you must log in.
Revision history for this message
Lee Trager (ltrager) :
review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.7 MiB)

The attempt to merge lp:~allenap/maas/notifications-triggers into lp:maas failed. Below is the output from the failed tests.

Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Hit:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:3 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Hit:4 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Fetched 204 kB in 0s (459 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind avahi-utils bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common isc-dhcp-server libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libnss-wrapper libpq-dev make nodejs-legacy npm postgresql pxelinux python3-all python3-apt python3-attr python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
authbind is already the newest version (2.1.1+nmu1).
avahi-utils is already the newest version (0.6.32~rc+dfsg-1ubuntu2).
build-essential is already the newest version (12.1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
git is already the newest version (1:2.7.4-0ubuntu1).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
pxelinux is already the newest version (3:6.03+dfsg-11ubuntu1).
python-formencode is already the newest version (1.3.0-0ubuntu5).
python-lxml is already the newest version (3.5.0-1build1).
python-netaddr is already the newest version (0.7.18-1).
python-netifaces is already the newest version (0.10.4-0.1build2).
python-psycopg2 ...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/triggers/tests/test_init.py'
--- src/maasserver/triggers/tests/test_init.py 2017-01-10 13:34:54 +0000
+++ src/maasserver/triggers/tests/test_init.py 2017-01-20 15:33:18 +0000
@@ -183,6 +183,10 @@
183 "node_region_controller_update_notify",183 "node_region_controller_update_notify",
184 "node_tags_machine_device_tag_link_notify",184 "node_tags_machine_device_tag_link_notify",
185 "node_tags_machine_device_tag_unlink_notify",185 "node_tags_machine_device_tag_unlink_notify",
186 "notification_notification_create_notify",
187 "notification_notification_delete_notify",
188 "notification_notification_update_notify",
189 "notificationdismissal_notificationdismissal_create_notify",
186 "packagerepository_packagerepository_create_notify",190 "packagerepository_packagerepository_create_notify",
187 "packagerepository_packagerepository_delete_notify",191 "packagerepository_packagerepository_delete_notify",
188 "packagerepository_packagerepository_update_notify",192 "packagerepository_packagerepository_update_notify",
189193
=== modified file 'src/maasserver/triggers/tests/test_websocket_listener.py'
--- src/maasserver/triggers/tests/test_websocket_listener.py 2016-12-07 14:53:00 +0000
+++ src/maasserver/triggers/tests/test_websocket_listener.py 2017-01-20 15:33:18 +0000
@@ -3246,3 +3246,89 @@
3246 finally:3246 finally:
3247 yield listener1.stopService()3247 yield listener1.stopService()
3248 yield listener2.stopService()3248 yield listener2.stopService()
3249
3250
3251class TestNotificationListener(
3252 MAASTransactionServerTestCase, TransactionalHelpersMixin):
3253 """Tests for notifications relating to the `Notification` model."""
3254
3255 @wait_for_reactor
3256 @inlineCallbacks
3257 def test__calls_handler_on_create_notification(self):
3258 yield deferToDatabase(register_websocket_triggers)
3259 listener = self.make_listener_without_delay()
3260 dv = DeferredValue()
3261 listener.register("notification", lambda *args: dv.set(args))
3262 yield listener.startService()
3263 try:
3264 notification = yield deferToDatabase(factory.make_Notification)
3265 yield dv.get(timeout=2)
3266 self.assertEqual(('create', '%s' % notification.id), dv.value)
3267 finally:
3268 yield listener.stopService()
3269
3270 @wait_for_reactor
3271 @inlineCallbacks
3272 def test__calls_handler_on_update_notification(self):
3273 yield deferToDatabase(register_websocket_triggers)
3274 listener = self.make_listener_without_delay()
3275 dv = DeferredValue()
3276 listener.register("notification", lambda *args: dv.set(args))
3277 notification = yield deferToDatabase(factory.make_Notification)
3278
3279 def update_notification(notification):
3280 notification.users = not notification.users
3281 notification.admins = not notification.admins
3282 notification.save()
3283
3284 yield listener.startService()
3285 try:
3286 yield deferToDatabase(update_notification, notification)
3287 yield dv.get(timeout=2)
3288 self.assertEqual(('update', '%s' % notification.id), dv.value)
3289 finally:
3290 yield listener.stopService()
3291
3292 @wait_for_reactor
3293 @inlineCallbacks
3294 def test__calls_handler_on_delete_notification(self):
3295 yield deferToDatabase(register_websocket_triggers)
3296 listener = self.make_listener_without_delay()
3297 dv = DeferredValue()
3298 listener.register("notification", lambda *args: dv.set(args))
3299 notification = yield deferToDatabase(factory.make_Notification)
3300 notification_id = notification.id # Capture before delete.
3301 yield listener.startService()
3302 try:
3303 yield deferToDatabase(notification.delete)
3304 yield dv.get(timeout=2)
3305 self.assertEqual(('delete', '%s' % notification_id), dv.value)
3306 finally:
3307 yield listener.stopService()
3308
3309
3310class TestNotificationDismissalListener(
3311 MAASTransactionServerTestCase, TransactionalHelpersMixin):
3312 """Tests relating to the `NotificationDismissal` model.
3313
3314 At present `NotificationDismissal` rows are only ever created.
3315 """
3316
3317 @wait_for_reactor
3318 @inlineCallbacks
3319 def test__calls_handler_on_create_notification(self):
3320 yield deferToDatabase(register_websocket_triggers)
3321 listener = self.make_listener_without_delay()
3322 dv = DeferredValue()
3323 listener.register("notificationdismissal", lambda *args: dv.set(args))
3324 yield listener.startService()
3325 try:
3326 user = yield deferToDatabase(factory.make_User)
3327 notification = yield deferToDatabase(factory.make_Notification)
3328 yield deferToDatabase(notification.dismiss, user)
3329 yield dv.get(timeout=2)
3330 self.assertEqual(
3331 ('create', '%d:%d' % (notification.id, user.id)),
3332 dv.value)
3333 finally:
3334 yield listener.stopService()
32493335
=== modified file 'src/maasserver/triggers/websocket.py'
--- src/maasserver/triggers/websocket.py 2017-01-10 13:11:08 +0000
+++ src/maasserver/triggers/websocket.py 2017-01-20 15:33:18 +0000
@@ -960,6 +960,30 @@
960 region_and_rack_controller=NODE_TYPE.REGION_AND_RACK_CONTROLLER))960 region_and_rack_controller=NODE_TYPE.REGION_AND_RACK_CONTROLLER))
961961
962962
963def render_notification_dismissal_notification_procedure(
964 proc_name, event_name):
965 """Send the notification_id and user_id when a notification is dismissed.
966
967 Why not send the surrogate primary key as we do for most/all other models?
968 The surrogate primary key exists only because Django won't let us do
969 without. It's just not interesting. We only want the notification's ID and
970 the user's ID, and we may as well put those in the notification because
971 they're really short and it saves an extra trip to the database to load
972 the row.
973 """
974 return dedent("""\
975 CREATE OR REPLACE FUNCTION %s() RETURNS trigger AS $$
976 DECLARE
977 BEGIN
978 PERFORM pg_notify(
979 '%s', CAST(NEW.notification_id AS text) || ':' ||
980 CAST(NEW.user_id AS text));
981 RETURN NEW;
982 END;
983 $$ LANGUAGE plpgsql;
984 """ % (proc_name, event_name))
985
986
963@transactional987@transactional
964def register_websocket_triggers():988def register_websocket_triggers():
965 """Register all websocket triggers into the database."""989 """Register all websocket triggers into the database."""
@@ -1736,6 +1760,33 @@
1736 "maasserver_packagerepository", "packagerepository_delete_notify",1760 "maasserver_packagerepository", "packagerepository_delete_notify",
1737 "delete")1761 "delete")
17381762
1763 # Node type change.
1739 register_procedure(node_type_change())1764 register_procedure(node_type_change())
1740 register_trigger(1765 register_trigger(
1741 "maasserver_node", "node_type_change_notify", "update")1766 "maasserver_node", "node_type_change_notify", "update")
1767
1768 # Notification table.
1769 register_procedure(
1770 render_notification_procedure(
1771 'notification_create_notify', 'notification_create', 'NEW.id'))
1772 register_procedure(
1773 render_notification_procedure(
1774 'notification_update_notify', 'notification_update', 'NEW.id'))
1775 register_procedure(
1776 render_notification_procedure(
1777 'notification_delete_notify', 'notification_delete', 'OLD.id'))
1778 register_trigger(
1779 "maasserver_notification", "notification_create_notify", "insert")
1780 register_trigger(
1781 "maasserver_notification", "notification_update_notify", "update")
1782 register_trigger(
1783 "maasserver_notification", "notification_delete_notify", "delete")
1784
1785 # NotificationDismissal table.
1786 register_procedure(
1787 render_notification_dismissal_notification_procedure(
1788 'notificationdismissal_create_notify',
1789 'notificationdismissal_create'))
1790 register_trigger(
1791 "maasserver_notificationdismissal",
1792 "notificationdismissal_create_notify", "insert")