def test_saving_tag_schedules_node_population(self): clock = self.patch(tag_module, "reactor", Clock()) with post_commit_hooks: # Make a Tag by hand to trigger normal node population handling # behaviour rather than the (generally more convenient) default # behaviour in the factory. tag = Tag(name=factory.make_name("tag"), definition="true()") tag.save() # A call has been scheduled to populate tags. calls = clock.getDelayedCalls() self.assertThat(calls, HasLength(1)) [call] = calls self.assertThat( call, MatchesAll( IsInstance(DelayedCall), MatchesStructure.byEquality( time=0, func=deferToDatabase, args=(populate_tags, tag), kw={}, ), first_only=True, ), )
def test_PUT_updates_node_associations(self): populate_nodes = self.patch_autospec(Tag, "populate_nodes") tag = Tag(name=factory.make_name("tag"), definition="//node/foo") tag.save() self.expectThat(populate_nodes, MockCalledOnceWith(tag)) self.become_admin() response = self.client.put(self.get_tag_uri(tag), {"definition": "//node/bar"}) self.assertEqual(http.client.OK, response.status_code) self.expectThat(populate_nodes, MockCallsMatch(call(tag), call(tag)))
def test_ignores_tags_without_definition(self): node = factory.make_Node() make_lshw_result(node, b"<foo/>") tags = [ factory.make_Tag("foo", "/foo", populate=False), Tag(name="empty", definition=""), Tag(name="null", definition=None), ] populate_tags_for_single_node(tags, node) # Look mom, no exception! self.assertSequenceEqual(["foo"], [tag.name for tag in node.tags.all()])
def test_POST_rebuild_rebuilds_node_mapping(self): populate_nodes = self.patch_autospec(Tag, "populate_nodes") tag = Tag(name=factory.make_name("tag"), definition='//foo/bar') tag.save() self.become_admin() self.assertThat(populate_nodes, MockCalledOnceWith(tag)) response = self.client.post(self.get_tag_uri(tag), {'op': 'rebuild'}) self.assertEqual(http.client.OK, response.status_code) parsed_result = json.loads( response.content.decode(settings.DEFAULT_CHARSET)) self.assertEqual({'rebuilding': tag.name}, parsed_result) self.assertThat(populate_nodes, MockCallsMatch(call(tag), call(tag)))
def test_ignores_tags_without_definition(self): node = factory.make_node() factory.make_node_commission_result( node, commissioningscript.LSHW_OUTPUT_NAME, 0, b"<foo/>") tags = [ factory.make_tag("foo", "/foo"), Tag(name="empty", definition=""), Tag(name="null", definition=None), ] populate_tags_for_single_node(tags, node) # Look mom, no exception! self.assertSequenceEqual( ["foo"], [tag.name for tag in node.tags.all()])
def test_populate_in_region_when_no_clients(self): clock = self.patch(tag_module, "reactor", Clock()) # Ensure there are no clients. self.patch(rpc_module, "getAllClients").return_value = [] with post_commit_hooks: node = factory.make_Node() # Make a Tag by hand to trigger normal node population handling # behaviour rather than the (generally more convenient) default # behaviour in the factory. tag = Tag(name=factory.make_name("tag"), definition="true()") tag.save() # A call has been scheduled to populate tags. [call] = clock.getDelayedCalls() # Execute the call ourselves in the real reactor. blockingCallFromThread(reactor, call.func, *call.args, **call.kw) # The tag's node set has been updated. self.assertItemsEqual([node], tag.node_set.all())
def make_tag(self, name=None, definition=None, comment='', kernel_opts=None, created=None, updated=None): if name is None: name = self.make_name('tag') if definition is None: # Is there a 'node' in this xml? definition = '//node' tag = Tag(name=name, definition=definition, comment=comment, kernel_opts=kernel_opts) self._save_node_unchecked(tag) # Update the 'updated'/'created' fields with a call to 'update' # preventing a call to save() from overriding the values. if updated is not None: Tag.objects.filter(id=tag.id).update(updated=updated) if created is not None: Tag.objects.filter(id=tag.id).update(created=created) return reload_object(tag)