Merge lp:~allenap/maas/chassis-delete-and-create-trigger into lp:~maas-committers/maas/trunk
- chassis-delete-and-create-trigger
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Gavin Panella |
Approved revision: | no longer in the source branch. |
Merged at revision: | 5632 |
Proposed branch: | lp:~allenap/maas/chassis-delete-and-create-trigger |
Merge into: | lp:~maas-committers/maas/trunk |
Diff against target: |
407 lines (+226/-142) 4 files modified
src/maasserver/models/signals/nodes.py (+3/-8) src/maasserver/models/signals/tests/test_nodes.py (+3/-6) src/maasserver/triggers/tests/test_init.py (+220/-1) src/maasserver/triggers/tests/test_websocket.py (+0/-127) |
To merge this branch: | bzr merge lp:~allenap/maas/chassis-delete-and-create-trigger |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Blake Rouse (community) | Approve | ||
Review via email: mp+314161@code.launchpad.net |
Commit message
In the node_type_
There are some related drive-by fixes and simplifications too.
Description of the change
Most of this branch is drive-by changes. However...
The interesting bit is in src/maasserver/
Nevertheless, this is an omission. I originally added a PERFORM pg_notify(...) here, but this opened other cans of worms. Most notably I tried adding a couple of scenarios — device_to_chassis and chassis_to_device — to TestNodeTypeChange but the former failed with a time-out. It turns out that nothing is sending a chassis_update message. I attempt to add that in register_
Comments in the code are sparse. What tests there are do not give me answers. I had no idea if I should continue along this path, so I chose the least can-of-worms option I could, which is to explicitly do nothing in node_type_
Gavin Panella (allenap) wrote : | # |
Thanks Blake.
Should I be concerned about the overlap between node_type_
and those at the top of register_
@transactional
def register_
"""Register all websocket triggers into the database."""
for (proc_name_prefix, event_name_prefix, node_type) in (
# Non-Device Node types
--> '%s_create' % event_name_prefix,
--> '%s_delete' % event_name_prefix,
...
Either or both the database and the listener will deduplicate these, but
it still looks like duplicated work. If that's by design we should leave
some comments behind so that my forgetful mind doesn't come back to this
like a goldfish circling the tank.
Gavin Panella (allenap) wrote : | # |
I'll land this now, but the question of overlap still stands.
Blake Rouse (blake-rouse) wrote : | # |
I am confused? Can you explain this a little more?
Do the procedures overlap in name?
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~allenap/maas/chassis-delete-and-create-trigger into lp:maas failed. Below is the output from the failed tests.
Hit:1 http://
Get:2 http://
Get:3 http://
Get:4 http://
Fetched 306 kB in 0s (624 kB/s)
Reading package lists...
sudo DEBIAN_
--no-
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~
build-essential is already the newest version (12.1ubuntu2).
debhelper is already the newest version (9.20160115ubun
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+
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.1build...
Gavin Panella (allenap) wrote : | # |
This branch was based on a pre-non-
tests were based on some outdated assumptions. I've reformulated those.
Gavin Panella (allenap) wrote : | # |
Blake wrote:
> I am confused? Can you explain this a little more?
>
> Do the procedures overlap in name?
There are many triggers on maasserver_node, but the following will
illustrate the overlap:
First is the trigger that calls node_type_
update:
node_
AFTER UPDATE ON maasserver_node
FOR EACH ROW
EXECUTE PROCEDURE node_type_
The node_type_
following pattern:
{machine,
The other interesting triggers on maasserver_node are:
node_
AFTER UPDATE ON maasserver_node
FOR EACH ROW WHEN (new.node_type = 1)
EXECUTE PROCEDURE device_
node_
AFTER UPDATE ON maasserver_node
FOR EACH ROW WHEN (new.node_type = 0)
EXECUTE PROCEDURE machine_
node_
AFTER UPDATE ON maasserver_node
FOR EACH ROW WHEN (new.node_type = 2)
EXECUTE PROCEDURE rack_controller
node_
AFTER UPDATE ON maasserver_node
FOR EACH ROW WHEN (new.node_type = 4)
EXECUTE PROCEDURE region_
node_
AFTER UPDATE ON maasserver_node
FOR EACH ROW WHEN (new.node_type = 3)
EXECUTE PROCEDURE region_
Take machine_
DECLARE
BEGIN
PERFORM pg_notify(
RETURN NEW;
END;
So, when a node is converted from, say, a rack controller to a machine,
the following messages will be NOTIFY'ed:
machine_update (via node_machine_
controller_delete (via node_node_
machine_create (via node_node_
This is a confusing order for things to appear in: the update before the
create.
FWIW, the order is stable: PostgreSQL says that NOTIFY'ed messages are
delivered in order [1] and triggers are run in alphabetical order [2].
Converting back from a machine to a rack controller will, I think,
result in:
machine_delete (via node_node_
controller_create (via node_node_
controller_update (via node_rack_
This is a more sensible order, but it also differs from before. The
presence of both *_create and *_update messages in both examples is also
repetition: both messages arise from the same event, an update.
Now, I don't know of anything that depends on this ordering, but I also
don't know all of the code. A few things stand out:
- We may already have bugs related to this ordering.
- We may create bugs related to this ordering in future.
- It's hard to figure all of MAAS's trigger stuff out.
I don't have an answer to this, but I do think that the way we compose
procedures and triggers has been outgrown by the complexity of the
systems that are reliant upon it. There are still manual steps required
to join up all the pieces. I'd like to be able to say it declaritively,
like:
When a row in table foo is u...
Preview Diff
1 | === modified file 'src/maasserver/models/signals/nodes.py' |
2 | --- src/maasserver/models/signals/nodes.py 2017-01-03 19:37:46 +0000 |
3 | +++ src/maasserver/models/signals/nodes.py 2017-01-10 13:35:41 +0000 |
4 | @@ -115,15 +115,10 @@ |
5 | |
6 | def create_chassis_hints(sender, instance, created, **kwargs): |
7 | """Create `ChassisHints` when `Chassis` is created.""" |
8 | - try: |
9 | - chassis_hints = instance.chassis_hints |
10 | - except ChassisHints.DoesNotExist: |
11 | - chassis_hints = None |
12 | if instance.node_type == NODE_TYPE.CHASSIS: |
13 | - if chassis_hints is None: |
14 | - ChassisHints.objects.create(chassis=instance) |
15 | - elif chassis_hints is not None: |
16 | - chassis_hints.delete() |
17 | + ChassisHints.objects.get_or_create(chassis=instance) |
18 | + else: |
19 | + ChassisHints.objects.filter(chassis=instance).delete() |
20 | |
21 | for klass in NODE_CLASSES: |
22 | signals.watch( |
23 | |
24 | === modified file 'src/maasserver/models/signals/tests/test_nodes.py' |
25 | --- src/maasserver/models/signals/tests/test_nodes.py 2017-01-05 15:21:29 +0000 |
26 | +++ src/maasserver/models/signals/tests/test_nodes.py 2017-01-10 13:35:41 +0000 |
27 | @@ -163,9 +163,6 @@ |
28 | chassis = factory.make_Node(node_type=NODE_TYPE.CHASSIS) |
29 | chassis.node_type = NODE_TYPE.DEVICE |
30 | chassis.save() |
31 | - error = None |
32 | - try: |
33 | - reload_object(chassis).chassis_hints |
34 | - except ChassisHints.DoesNotExist as exc: |
35 | - error = exc |
36 | - self.assertIsNotNone(error) |
37 | + self.assertRaises( |
38 | + ChassisHints.DoesNotExist, |
39 | + lambda: chassis.chassis_hints) |
40 | |
41 | === modified file 'src/maasserver/triggers/tests/test_init.py' |
42 | --- src/maasserver/triggers/tests/test_init.py 2016-03-28 13:54:47 +0000 |
43 | +++ src/maasserver/triggers/tests/test_init.py 2017-01-10 13:35:41 +0000 |
44 | @@ -13,7 +13,15 @@ |
45 | register_procedure, |
46 | register_trigger, |
47 | ) |
48 | -from maasserver.triggers.websocket import render_notification_procedure |
49 | +from maasserver.triggers.system import register_system_triggers |
50 | +from maasserver.triggers.websocket import ( |
51 | + register_websocket_triggers, |
52 | + render_notification_procedure, |
53 | +) |
54 | +from testtools.matchers import Equals |
55 | + |
56 | + |
57 | +EMPTY_SET = frozenset() |
58 | |
59 | |
60 | class TestTriggers(MAASServerTestCase): |
61 | @@ -46,3 +54,214 @@ |
62 | triggers = cursor.fetchall() |
63 | |
64 | self.assertEqual(1, len(triggers), "Trigger was not created.") |
65 | + |
66 | + |
67 | +class TestTriggersUsed(MAASServerTestCase): |
68 | + """Tests relating to those triggers the MAAS application uses.""" |
69 | + |
70 | + triggers_system = { |
71 | + "config_sys_dhcp_config_ntp_servers_delete", |
72 | + "config_sys_dhcp_config_ntp_servers_insert", |
73 | + "config_sys_dhcp_config_ntp_servers_update", |
74 | + "config_sys_dns_config_insert", |
75 | + "config_sys_dns_config_update", |
76 | + "dhcpsnippet_sys_dhcp_snippet_delete", |
77 | + "dhcpsnippet_sys_dhcp_snippet_insert", |
78 | + "dhcpsnippet_sys_dhcp_snippet_update", |
79 | + "dnsdata_sys_dns_dnsdata_delete", |
80 | + "dnsdata_sys_dns_dnsdata_insert", |
81 | + "dnsdata_sys_dns_dnsdata_update", |
82 | + "dnspublication_sys_dns_publish", |
83 | + "dnsresource_ip_addresses_sys_dns_dnsresource_ip_link", |
84 | + "dnsresource_ip_addresses_sys_dns_dnsresource_ip_unlink", |
85 | + "dnsresource_sys_dns_dnsresource_delete", |
86 | + "dnsresource_sys_dns_dnsresource_insert", |
87 | + "dnsresource_sys_dns_dnsresource_update", |
88 | + "domain_sys_dns_domain_delete", |
89 | + "domain_sys_dns_domain_insert", |
90 | + "domain_sys_dns_domain_update", |
91 | + "interface_ip_addresses_sys_dns_nic_ip_link", |
92 | + "interface_ip_addresses_sys_dns_nic_ip_unlink", |
93 | + "interface_sys_dhcp_interface_update", |
94 | + "interface_sys_dns_interface_update", |
95 | + "iprange_sys_dhcp_iprange_delete", |
96 | + "iprange_sys_dhcp_iprange_insert", |
97 | + "iprange_sys_dhcp_iprange_update", |
98 | + "node_sys_dhcp_node_update", |
99 | + "node_sys_dns_node_delete", |
100 | + "node_sys_dns_node_update", |
101 | + "regionrackrpcconnection_sys_core_rpc_delete", |
102 | + "regionrackrpcconnection_sys_core_rpc_insert", |
103 | + "staticipaddress_sys_dhcp_staticipaddress_delete", |
104 | + "staticipaddress_sys_dhcp_staticipaddress_insert", |
105 | + "staticipaddress_sys_dhcp_staticipaddress_update", |
106 | + "staticipaddress_sys_dns_staticipaddress_update", |
107 | + "subnet_sys_dhcp_subnet_delete", |
108 | + "subnet_sys_dhcp_subnet_update", |
109 | + "subnet_sys_dns_subnet_delete", |
110 | + "subnet_sys_dns_subnet_insert", |
111 | + "subnet_sys_dns_subnet_update", |
112 | + "subnet_sys_proxy_subnet_delete", |
113 | + "subnet_sys_proxy_subnet_insert", |
114 | + "subnet_sys_proxy_subnet_update", |
115 | + "vlan_sys_dhcp_vlan_update", |
116 | + } |
117 | + |
118 | + triggers_websocket = { |
119 | + "auth_user_user_create_notify", |
120 | + "auth_user_user_delete_notify", |
121 | + "auth_user_user_update_notify", |
122 | + "blockdevice_nd_blockdevice_link_notify", |
123 | + "blockdevice_nd_blockdevice_unlink_notify", |
124 | + "blockdevice_nd_blockdevice_update_notify", |
125 | + "cacheset_nd_cacheset_link_notify", |
126 | + "cacheset_nd_cacheset_unlink_notify", |
127 | + "cacheset_nd_cacheset_update_notify", |
128 | + "config_config_create_notify", |
129 | + "config_config_delete_notify", |
130 | + "config_config_update_notify", |
131 | + "dhcpsnippet_dhcpsnippet_create_notify", |
132 | + "dhcpsnippet_dhcpsnippet_delete_notify", |
133 | + "dhcpsnippet_dhcpsnippet_update_notify", |
134 | + "dnsdata_dnsdata_domain_delete_notify", |
135 | + "dnsdata_dnsdata_domain_insert_notify", |
136 | + "dnsdata_dnsdata_domain_update_notify", |
137 | + "dnsresource_dnsresource_domain_delete_notify", |
138 | + "dnsresource_dnsresource_domain_insert_notify", |
139 | + "dnsresource_dnsresource_domain_update_notify", |
140 | + "dnsresource_ip_addresses_rrset_sipaddress_link_notify", |
141 | + "dnsresource_ip_addresses_rrset_sipaddress_unlink_notify", |
142 | + "domain_domain_create_notify", |
143 | + "domain_domain_delete_notify", |
144 | + "domain_domain_node_update_notify", |
145 | + "domain_domain_update_notify", |
146 | + "event_event_create_machine_device_notify", |
147 | + "event_event_create_notify", |
148 | + "fabric_fabric_create_notify", |
149 | + "fabric_fabric_delete_notify", |
150 | + "fabric_fabric_machine_update_notify", |
151 | + "fabric_fabric_update_notify", |
152 | + "filesystem_nd_filesystem_link_notify", |
153 | + "filesystem_nd_filesystem_unlink_notify", |
154 | + "filesystem_nd_filesystem_update_notify", |
155 | + "filesystemgroup_nd_filesystemgroup_link_notify", |
156 | + "filesystemgroup_nd_filesystemgroup_unlink_notify", |
157 | + "filesystemgroup_nd_filesystemgroup_update_notify", |
158 | + "interface_ip_addresses_nd_sipaddress_dns_link_notify", |
159 | + "interface_ip_addresses_nd_sipaddress_dns_unlink_notify", |
160 | + "interface_ip_addresses_nd_sipaddress_link_notify", |
161 | + "interface_ip_addresses_nd_sipaddress_unlink_notify", |
162 | + "interface_nd_interface_link_notify", |
163 | + "interface_nd_interface_unlink_notify", |
164 | + "interface_nd_interface_update_notify", |
165 | + "iprange_iprange_create_notify", |
166 | + "iprange_iprange_delete_notify", |
167 | + "iprange_iprange_subnet_delete_notify", |
168 | + "iprange_iprange_subnet_insert_notify", |
169 | + "iprange_iprange_subnet_update_notify", |
170 | + "iprange_iprange_update_notify", |
171 | + "metadataserver_noderesult_nd_noderesult_link_notify", |
172 | + "metadataserver_noderesult_nd_noderesult_unlink_notify", |
173 | + "neighbour_neighbour_create_notify", |
174 | + "neighbour_neighbour_delete_notify", |
175 | + "neighbour_neighbour_update_notify", |
176 | + "node_device_create_notify", |
177 | + "node_device_delete_notify", |
178 | + "node_device_update_notify", |
179 | + "node_machine_create_notify", |
180 | + "node_machine_delete_notify", |
181 | + "node_machine_update_notify", |
182 | + "node_node_type_change_notify", |
183 | + "node_rack_controller_create_notify", |
184 | + "node_rack_controller_delete_notify", |
185 | + "node_rack_controller_update_notify", |
186 | + "node_region_and_rack_controller_create_notify", |
187 | + "node_region_and_rack_controller_delete_notify", |
188 | + "node_region_and_rack_controller_update_notify", |
189 | + "node_region_controller_create_notify", |
190 | + "node_region_controller_delete_notify", |
191 | + "node_region_controller_update_notify", |
192 | + "node_tags_machine_device_tag_link_notify", |
193 | + "node_tags_machine_device_tag_unlink_notify", |
194 | + "packagerepository_packagerepository_create_notify", |
195 | + "packagerepository_packagerepository_delete_notify", |
196 | + "packagerepository_packagerepository_update_notify", |
197 | + "partition_nd_partition_link_notify", |
198 | + "partition_nd_partition_unlink_notify", |
199 | + "partition_nd_partition_update_notify", |
200 | + "partitiontable_nd_partitiontable_link_notify", |
201 | + "partitiontable_nd_partitiontable_unlink_notify", |
202 | + "partitiontable_nd_partitiontable_update_notify", |
203 | + "physicalblockdevice_nd_physblockdevice_update_notify", |
204 | + "service_service_create_notify", |
205 | + "service_service_delete_notify", |
206 | + "service_service_update_notify", |
207 | + "space_space_create_notify", |
208 | + "space_space_delete_notify", |
209 | + "space_space_machine_update_notify", |
210 | + "space_space_update_notify", |
211 | + "sshkey_sshkey_create_notify", |
212 | + "sshkey_sshkey_delete_notify", |
213 | + "sshkey_sshkey_update_notify", |
214 | + "sshkey_user_sshkey_link_notify", |
215 | + "sshkey_user_sshkey_unlink_notify", |
216 | + "sslkey_user_sslkey_link_notify", |
217 | + "sslkey_user_sslkey_unlink_notify", |
218 | + "staticipaddress_ipaddress_domain_delete_notify", |
219 | + "staticipaddress_ipaddress_domain_insert_notify", |
220 | + "staticipaddress_ipaddress_domain_update_notify", |
221 | + "staticipaddress_ipaddress_machine_update_notify", |
222 | + "staticipaddress_ipaddress_subnet_update_notify", |
223 | + "staticroute_staticroute_create_notify", |
224 | + "staticroute_staticroute_delete_notify", |
225 | + "staticroute_staticroute_update_notify", |
226 | + "subnet_subnet_create_notify", |
227 | + "subnet_subnet_delete_notify", |
228 | + "subnet_subnet_machine_update_notify", |
229 | + "subnet_subnet_update_notify", |
230 | + "tag_tag_create_notify", |
231 | + "tag_tag_delete_notify", |
232 | + "tag_tag_update_machine_device_notify", |
233 | + "tag_tag_update_notify", |
234 | + "virtualblockdevice_nd_virtblockdevice_update_notify", |
235 | + "vlan_vlan_create_notify", |
236 | + "vlan_vlan_delete_notify", |
237 | + "vlan_vlan_machine_update_notify", |
238 | + "vlan_vlan_update_notify", |
239 | + "zone_zone_create_notify", |
240 | + "zone_zone_delete_notify", |
241 | + "zone_zone_update_notify", |
242 | + } |
243 | + |
244 | + triggers_all = triggers_system | triggers_websocket |
245 | + |
246 | + def find_triggers_in_database(self): |
247 | + with connection.cursor() as cursor: |
248 | + cursor.execute( |
249 | + "SELECT tgname::text FROM pg_trigger " |
250 | + "WHERE NOT tgisinternal") |
251 | + return {tgname for tgname, in cursor.fetchall()} |
252 | + |
253 | + def check_triggers_in_database(self): |
254 | + # Note: if this test fails, a trigger may have been added, but not |
255 | + # added to the list of expected triggers. |
256 | + triggers_found = self.find_triggers_in_database() |
257 | + self.expectThat( |
258 | + (self.triggers_all - triggers_found), Equals(EMPTY_SET), |
259 | + "Some triggers were expected but not found.") |
260 | + self.expectThat( |
261 | + (triggers_found - self.triggers_all), Equals(EMPTY_SET), |
262 | + "Some triggers were unexpected.") |
263 | + |
264 | + def test_all_triggers_present_and_correct(self): |
265 | + # Running in a fully migrated database means all triggers should be |
266 | + # present from the get go. |
267 | + self.check_triggers_in_database() |
268 | + |
269 | + def test_register_system_triggers_does_not_introduce_more(self): |
270 | + register_system_triggers() |
271 | + self.check_triggers_in_database() |
272 | + |
273 | + def test_register_websocket_triggers_does_not_introduce_more(self): |
274 | + register_websocket_triggers() |
275 | + self.check_triggers_in_database() |
276 | |
277 | === removed file 'src/maasserver/triggers/tests/test_websocket.py' |
278 | --- src/maasserver/triggers/tests/test_websocket.py 2016-10-20 20:56:24 +0000 |
279 | +++ src/maasserver/triggers/tests/test_websocket.py 1970-01-01 00:00:00 +0000 |
280 | @@ -1,127 +0,0 @@ |
281 | -# Copyright 2015-2016 Canonical Ltd. This software is licensed under the |
282 | -# GNU Affero General Public License version 3 (see the file LICENSE). |
283 | - |
284 | -"""Tests for `maasserver.triggers.websocket`.""" |
285 | - |
286 | -__all__ = [] |
287 | - |
288 | -from contextlib import closing |
289 | - |
290 | -from django.db import connection |
291 | -from maasserver.testing.testcase import MAASServerTestCase |
292 | -from maasserver.triggers.websocket import register_websocket_triggers |
293 | -from maasserver.utils.orm import psql_array |
294 | - |
295 | - |
296 | -class TestTriggers(MAASServerTestCase): |
297 | - |
298 | - def test_register_websocket_triggers(self): |
299 | - register_websocket_triggers() |
300 | - triggers = [ |
301 | - "node_machine_create_notify", |
302 | - "node_machine_update_notify", |
303 | - "node_machine_delete_notify", |
304 | - "node_device_create_notify", |
305 | - "node_device_update_notify", |
306 | - "node_device_delete_notify", |
307 | - "config_config_create_notify", |
308 | - "config_config_update_notify", |
309 | - "config_config_delete_notify", |
310 | - "node_rack_controller_create_notify", |
311 | - "node_rack_controller_update_notify", |
312 | - "node_rack_controller_delete_notify", |
313 | - "node_region_controller_create_notify", |
314 | - "node_region_controller_update_notify", |
315 | - "node_region_controller_delete_notify", |
316 | - "node_region_and_rack_controller_create_notify", |
317 | - "node_region_and_rack_controller_update_notify", |
318 | - "node_region_and_rack_controller_delete_notify", |
319 | - "zone_zone_create_notify", |
320 | - "zone_zone_update_notify", |
321 | - "zone_zone_delete_notify", |
322 | - "tag_tag_create_notify", |
323 | - "tag_tag_update_notify", |
324 | - "tag_tag_delete_notify", |
325 | - "node_tags_machine_device_tag_link_notify", |
326 | - "node_tags_machine_device_tag_unlink_notify", |
327 | - "tag_tag_update_machine_device_notify", |
328 | - "auth_user_user_create_notify", |
329 | - "auth_user_user_update_notify", |
330 | - "auth_user_user_delete_notify", |
331 | - "event_event_create_notify", |
332 | - "event_event_create_machine_device_notify", |
333 | - "interface_ip_addresses_nd_sipaddress_link_notify", |
334 | - "interface_ip_addresses_nd_sipaddress_unlink_notify", |
335 | - "interface_ip_addresses_nd_sipaddress_dns_link_notify", |
336 | - "interface_ip_addresses_nd_sipaddress_dns_unlink_notify", |
337 | - "dnsresource_ip_addresses_rrset_sipaddress_link_notify", |
338 | - "dnsresource_ip_addresses_rrset_sipaddress_unlink_notify", |
339 | - "metadataserver_noderesult_nd_noderesult_link_notify", |
340 | - "metadataserver_noderesult_nd_noderesult_unlink_notify", |
341 | - "interface_nd_interface_link_notify", |
342 | - "interface_nd_interface_unlink_notify", |
343 | - "interface_nd_interface_update_notify", |
344 | - "blockdevice_nd_blockdevice_link_notify", |
345 | - "blockdevice_nd_blockdevice_unlink_notify", |
346 | - "physicalblockdevice_nd_physblockdevice_update_notify", |
347 | - "virtualblockdevice_nd_virtblockdevice_update_notify", |
348 | - "sshkey_user_sshkey_link_notify", |
349 | - "sshkey_user_sshkey_unlink_notify", |
350 | - "sshkey_sshkey_create_notify", |
351 | - "sshkey_sshkey_update_notify", |
352 | - "sshkey_sshkey_delete_notify", |
353 | - "sslkey_user_sslkey_link_notify", |
354 | - "sslkey_user_sslkey_unlink_notify", |
355 | - "fabric_fabric_create_notify", |
356 | - "fabric_fabric_update_notify", |
357 | - "fabric_fabric_delete_notify", |
358 | - "vlan_vlan_create_notify", |
359 | - "vlan_vlan_update_notify", |
360 | - "vlan_vlan_delete_notify", |
361 | - "neighbour_neighbour_create_notify", |
362 | - "neighbour_neighbour_update_notify", |
363 | - "neighbour_neighbour_delete_notify", |
364 | - "iprange_iprange_create_notify", |
365 | - "iprange_iprange_update_notify", |
366 | - "iprange_iprange_delete_notify", |
367 | - "staticroute_staticroute_create_notify", |
368 | - "staticroute_staticroute_update_notify", |
369 | - "staticroute_staticroute_delete_notify", |
370 | - "subnet_subnet_create_notify", |
371 | - "subnet_subnet_update_notify", |
372 | - "subnet_subnet_delete_notify", |
373 | - "space_space_create_notify", |
374 | - "space_space_update_notify", |
375 | - "space_space_delete_notify", |
376 | - "subnet_subnet_machine_update_notify", |
377 | - "fabric_fabric_machine_update_notify", |
378 | - "space_space_machine_update_notify", |
379 | - "vlan_vlan_machine_update_notify", |
380 | - "staticipaddress_ipaddress_machine_update_notify", |
381 | - "staticipaddress_ipaddress_subnet_update_notify", |
382 | - "dhcpsnippet_dhcpsnippet_create_notify", |
383 | - "dhcpsnippet_dhcpsnippet_update_notify", |
384 | - "dhcpsnippet_dhcpsnippet_delete_notify", |
385 | - "iprange_iprange_subnet_insert_notify", |
386 | - "iprange_iprange_subnet_update_notify", |
387 | - "iprange_iprange_subnet_delete_notify", |
388 | - ] |
389 | - sql, args = psql_array(triggers, sql_type="text") |
390 | - with closing(connection.cursor()) as cursor: |
391 | - cursor.execute( |
392 | - "SELECT tgname::text FROM pg_trigger WHERE " |
393 | - "tgname::text = ANY(%s) " % sql, args) |
394 | - db_triggers = cursor.fetchall() |
395 | - |
396 | - # Note: if this test fails, a trigger may have been added, but not |
397 | - # added to the list of expected triggers. |
398 | - triggers_found = [trigger[0] for trigger in db_triggers] |
399 | - self.assertEqual( |
400 | - len(triggers), len(db_triggers), |
401 | - "Missing %s triggers in the database. Triggers found: %s" % ( |
402 | - len(triggers) - len(db_triggers), triggers_found)) |
403 | - |
404 | - self.assertItemsEqual( |
405 | - triggers, triggers_found, |
406 | - "Missing triggers in the database. Triggers found: %s" % ( |
407 | - triggers_found)) |
This is actual fine since a machine or any other node type will not be converted to a chassis. Chassis are always created explicitly.
Thanks for the cleanup of the ChassisHints!