def test_add_node(self): # Ensure previous node information is cleared uuid2 = uuidutils.generate_uuid() session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid).save(session) db.Node(uuid=uuid2).save(session) db.Attribute(name='mac', value='11:22:11:22:11:22', uuid=self.uuid).save(session) node = node_cache.add_node(self.node.uuid, mac=self.macs, bmc_address='1.2.3.4', foo=None) self.assertEqual(self.uuid, node.uuid) self.assertTrue(time.time() - 60 < node.started_at < time.time() + 60) self.assertFalse(node._locked) res = set(db.model_query(db.Node.uuid, db.Node.started_at).all()) expected = {(node.uuid, node.started_at), (uuid2, None)} self.assertEqual(expected, res) res = (db.model_query(db.Attribute.name, db.Attribute.value, db.Attribute.uuid).order_by( db.Attribute.name, db.Attribute.value).all()) self.assertEqual([('bmc_address', '1.2.3.4', self.uuid), ('mac', self.macs[0], self.uuid), ('mac', self.macs[1], self.uuid)], [(row.name, row.value, row.uuid) for row in res])
def test_add_node(self): # Ensure previous node information is cleared session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid).save(session) db.Node(uuid='uuid2').save(session) db.Attribute(name='mac', value='11:22:11:22:11:22', uuid=self.uuid).save(session) res = node_cache.add_node(self.node.uuid, mac=self.macs, bmc_address='1.2.3.4', foo=None) self.assertEqual(self.uuid, res.uuid) self.assertTrue(time.time() - 60 < res.started_at < time.time() + 60) res = (db.model_query(db.Node.uuid, db.Node.started_at).order_by(db.Node.uuid).all()) self.assertEqual(['1a1a1a1a-2b2b-3c3c-4d4d-5e5e5e5e5e5e', 'uuid2'], [t.uuid for t in res]) self.assertTrue(time.time() - 60 < res[0].started_at < time.time() + 60) res = (db.model_query(db.Attribute.name, db.Attribute.value, db.Attribute.uuid). order_by(db.Attribute.name, db.Attribute.value).all()) self.assertEqual([('bmc_address', '1.2.3.4', self.uuid), ('mac', self.macs[0], self.uuid), ('mac', self.macs[1], self.uuid)], [(row.name, row.value, row.uuid) for row in res])
def test__list_node_uuids(self): session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid).save(session) db.Node(uuid='uuid2').save(session) node_uuid_list = node_cache._list_node_uuids() self.assertEqual({self.uuid, 'uuid2'}, node_uuid_list)
def test__list_node_uuids(self): session = db.get_session() uuid2 = uuidutils.generate_uuid() with session.begin(): db.Node(uuid=self.node.uuid).save(session) db.Node(uuid=uuid2).save(session) node_uuid_list = node_cache._list_node_uuids() self.assertEqual({self.uuid, uuid2}, node_uuid_list)
def setUp(self): super(TestNodeCacheListNode, self).setUp() self.uuid2 = uuidutils.generate_uuid() session = db.get_session() with session.begin(): db.Node(uuid=self.uuid, started_at=datetime.datetime(1, 1, 2)).save(session) db.Node(uuid=self.uuid2, started_at=datetime.datetime(1, 1, 1), finished_at=datetime.datetime(1, 1, 3)).save(session)
def add_node(uuid, state, manage_boot=True, **attributes): """Store information about a node under introspection. All existing information about this node is dropped. Empty values are skipped. :param uuid: Ironic node UUID :param state: The initial state of the node :param manage_boot: whether to manage boot for this node :param attributes: attributes known about this node (like macs, BMC etc); also ironic client instance may be passed under 'ironic' :returns: NodeInfo """ started_at = timeutils.utcnow() with db.ensure_transaction() as session: _delete_node(uuid) version_id = uuidutils.generate_uuid() db.Node(uuid=uuid, state=state, version_id=version_id, started_at=started_at, manage_boot=manage_boot).save(session) node_info = NodeInfo(uuid=uuid, state=state, started_at=started_at, version_id=version_id, manage_boot=manage_boot, ironic=attributes.pop('ironic', None)) for (name, value) in attributes.items(): if not value: continue node_info.add_attribute(name, value, session=session) return node_info
def setUp(self): super(TestReapplyNode, self).setUp() CONF.set_override('processing_hooks', '$processing.default_processing_hooks,example', 'processing') CONF.set_override('store_data', 'swift', 'processing') self.data['macs'] = self.macs self.ports = self.all_ports self.node_info = node_cache.NodeInfo(uuid=self.uuid, started_at=self.started_at, node=self.node) self.node_info.invalidate_cache = mock.Mock() self.cli.port.create.side_effect = self.ports self.cli.node.update.return_value = self.node self.cli.node.list_ports.return_value = [] self.node_info._state = istate.States.finished self.commit_fixture = self.useFixture( fixtures.MockPatchObject(node_cache.NodeInfo, 'commit', autospec=True)) db.Node(uuid=self.node_info.uuid, state=self.node_info._state, started_at=self.node_info.started_at, finished_at=self.node_info.finished_at, error=self.node_info.error).save(self.session)
def test_timeout(self, time_mock, get_lock_mock): # Add a finished node to confirm we don't try to timeout it time_mock.return_value = self.started_at session = db.get_session() finished_at = self.started_at + datetime.timedelta(seconds=60) with session.begin(): db.Node(uuid=self.uuid + '1', started_at=self.started_at, state=istate.States.waiting, finished_at=finished_at).save(session) CONF.set_override('timeout', 99) time_mock.return_value = (self.started_at + datetime.timedelta(seconds=100)) self.assertEqual([self.uuid], node_cache.clean_up()) res = [(row.state, row.finished_at, row.error) for row in db.model_query(db.Node).all()] self.assertEqual( [(istate.States.error, self.started_at + datetime.timedelta(seconds=100), 'Introspection timeout'), (istate.States.waiting, self.started_at + datetime.timedelta(seconds=60), None)], res) self.assertEqual([], db.model_query(db.Attribute).all()) self.assertEqual([], db.model_query(db.Option).all()) get_lock_mock.assert_called_once_with(self.uuid) get_lock_mock.return_value.acquire.assert_called_once_with()
def setUp(self): super(TestProcessNode, self).setUp() CONF.set_override('processing_hooks', '$processing.default_processing_hooks,example', 'processing') self.validate_attempts = 5 self.data['macs'] = self.macs # validate_interfaces hook self.valid_interfaces['eth3'] = { 'mac': self.macs[1], 'ip': self.ips[1], 'extra': {}, 'pxe': False } self.data['interfaces'] = self.valid_interfaces self.ports = self.all_ports self.cli.node.get_boot_device.side_effect = ( [RuntimeError()] * self.validate_attempts + [None]) self.cli.port.create.side_effect = self.ports self.cli.node.update.return_value = self.node self.cli.node.list_ports.return_value = [] self.useFixture( fixtures.MockPatchObject(pxe_filter, 'driver', autospec=True)) self.useFixture( fixtures.MockPatchObject(eventlet.greenthread, 'sleep', autospec=True)) self.node_info._state = istate.States.waiting db.Node(uuid=self.node_info.uuid, state=self.node_info._state, started_at=self.node_info.started_at, finished_at=self.node_info.finished_at, error=self.node_info.error).save(self.session)
def setUp(self): super(TestDatabaseStore, self).setUp() self.driver = introspection_data.DatabaseStore() session = db.get_writer_session() with session.begin(): db.Node(uuid=self.node_info.uuid, state=istate.States.starting).save(session)
def add_node(uuid, **attributes): """Store information about a node under introspection. All existing information about this node is dropped. Empty values are skipped. :param uuid: Ironic node UUID :param attributes: attributes known about this node (like macs, BMC etc); also ironic client instance may be passed under 'ironic' :returns: NodeInfo """ started_at = time.time() with db.ensure_transaction() as session: _delete_node(uuid) db.Node(uuid=uuid, started_at=started_at).save(session) node_info = NodeInfo(uuid=uuid, started_at=started_at, ironic=attributes.pop('ironic', None)) for (name, value) in attributes.items(): if not value: continue node_info.add_attribute(name, value, session=session) return node_info
def test_add_node_duplicate_mac(self): session = db.get_session() with session.begin(): db.Node(uuid='another-uuid').save(session) db.Attribute(name='mac', value='11:22:11:22:11:22', uuid='another-uuid').save(session) self.assertRaises(utils.Error, node_cache.add_node, self.node.uuid, mac=['11:22:11:22:11:22'])
def setUp(self): super(TestNodeCacheCleanUp, self).setUp() self.started_at = 100.0 session = db.get_session() with session.begin(): db.Node(uuid=self.uuid, started_at=self.started_at).save(session) for v in self.macs: db.Attribute(name='mac', value=v, uuid=self.uuid).save(session) db.Option(uuid=self.uuid, name='foo', value='bar').save(session)
def test_ok(self): started_at = time.time() - 42 session = db.get_session() with session.begin(): db.Node(uuid=self.uuid, started_at=started_at).save(session) info = node_cache.get_node(self.uuid) self.assertEqual(self.uuid, info.uuid) self.assertEqual(started_at, info.started_at) self.assertIsNone(info.finished_at) self.assertIsNone(info.error)
def test_active_macs(self): session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid).save(session) values = [('mac', '11:22:11:22:11:22', self.uuid), ('mac', '22:11:22:11:22:11', self.uuid)] for value in values: db.Attribute(name=value[0], value=value[1], uuid=value[2]).save(session) self.assertEqual({'11:22:11:22:11:22', '22:11:22:11:22:11'}, node_cache.active_macs())
def setUp(self): super(NodeStateTest, self).setUp() self.node_info._version_id = uuidutils.generate_uuid() self.node_info._state = istate.States.starting self.db_node = db.Node(uuid=self.node_info.uuid, version_id=self.node_info._version_id, state=self.node_info._state, started_at=self.node_info.started_at, finished_at=self.node_info.finished_at, error=self.node_info.error) self.db_node.save(self.session)
def test_active_macs(self): session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid, state=istate.States.starting).save(session) values = [('mac', '11:22:11:22:11:22', self.uuid), ('mac', '22:11:22:11:22:11', self.uuid)] for value in values: db.Attribute(uuid=uuidutils.generate_uuid(), name=value[0], value=value[1], node_uuid=value[2]).save(session) self.assertEqual({'11:22:11:22:11:22', '22:11:22:11:22:11'}, node_cache.active_macs())
def setUp(self): super(TestNodeCacheCleanUp, self).setUp() self.started_at = datetime.datetime.utcnow() session = db.get_session() with session.begin(): db.Node(uuid=self.uuid, state=istate.States.waiting, started_at=self.started_at).save(session) for v in self.macs: db.Attribute(uuid=uuidutils.generate_uuid(), name='mac', value=v, node_uuid=self.uuid).save(session) db.Option(uuid=self.uuid, name='foo', value='bar').save(session)
def test_locked(self): started_at = (datetime.datetime.utcnow() - datetime.timedelta(seconds=42)) session = db.get_session() with session.begin(): db.Node(uuid=self.uuid, state=istate.States.starting, started_at=started_at).save(session) info = node_cache.get_node(self.uuid, locked=True) self.assertEqual(self.uuid, info.uuid) self.assertEqual(started_at, info.started_at) self.assertIsNone(info.finished_at) self.assertIsNone(info.error) self.assertTrue(info._locked)
def test_with_name(self): started_at = time.time() - 42 session = db.get_session() with session.begin(): db.Node(uuid=self.uuid, started_at=started_at).save(session) ironic = mock.Mock() ironic.node.get.return_value = self.node info = node_cache.get_node('name', ironic=ironic) self.assertEqual(self.uuid, info.uuid) self.assertEqual(started_at, info.started_at) self.assertIsNone(info.finished_at) self.assertIsNone(info.error) self.assertFalse(info._locked) ironic.node.get.assert_called_once_with('name')
def test_add_attribute(self): session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid).save(session) node_info = node_cache.NodeInfo(uuid=self.uuid, started_at=42) node_info.add_attribute('key', 'value') res = db.model_query(db.Attribute.name, db.Attribute.value, db.Attribute.uuid, session=session) res = res.order_by(db.Attribute.name, db.Attribute.value).all() self.assertEqual([('key', 'value', self.uuid)], [tuple(row) for row in res]) self.assertRaises(utils.Error, node_info.add_attribute, 'key', 'value') # check that .attributes got invalidated and reloaded self.assertEqual({'key': ['value']}, node_info.attributes)
def test_add_attribute_same_value(self): session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid, state=istate.States.starting).save(session) node_info = node_cache.NodeInfo(uuid=self.uuid, started_at=42) node_info.add_attribute('key', 'value') node_info.add_attribute('key', 'value') res = db.model_query(db.Attribute.name, db.Attribute.value, db.Attribute.node_uuid, session=session) self.assertEqual([('key', 'value', self.uuid), ('key', 'value', self.uuid)], [tuple(row) for row in res])
def test_timeout(self, time_mock): # Add a finished node to confirm we don't try to timeout it time_mock.return_value = self.started_at session = db.get_session() with session.begin(): db.Node(uuid=self.uuid + '1', started_at=self.started_at, finished_at=self.started_at + 60).save(session) CONF.set_override('timeout', 99) time_mock.return_value = (self.started_at + 100) self.assertEqual([self.uuid], node_cache.clean_up()) res = [(row.finished_at, row.error) for row in db.model_query(db.Node).all()] self.assertEqual([(self.started_at + 100, 'Introspection timeout'), (self.started_at + 60, None)], res) self.assertEqual([], db.model_query(db.Attribute).all()) self.assertEqual([], db.model_query(db.Option).all())
def test__delete_node(self): session = db.get_session() with session.begin(): db.Node(uuid=self.node.uuid).save(session) db.Attribute(name='mac', value='11:22:11:22:11:22', uuid=self.uuid).save(session) data = {'s': 'value', 'b': True, 'i': 42} encoded = json.dumps(data) db.Option(uuid=self.uuid, name='name', value=encoded).save(session) node_cache._delete_node(self.uuid) session = db.get_session() row_node = db.model_query(db.Node).filter_by(uuid=self.uuid).first() self.assertIsNone(row_node) row_attribute = db.model_query( db.Attribute).filter_by(uuid=self.uuid).first() self.assertIsNone(row_attribute) row_option = db.model_query( db.Option).filter_by(uuid=self.uuid).first() self.assertIsNone(row_option)
def _create_node(self): session = db.get_writer_session() with session.begin(): db.Node(uuid=self.node_info.uuid, state=istate.States.starting).save(session)