def test_agents_to_trees_association(self): # N, M association with self.ctx.store.begin(subtransactions=True): data = tree.StructuredHashTree().include([{ 'key': ('keyA', 'keyB') }, { 'key': ('keyA', 'keyC') }, { 'key': ('keyA', 'keyC', 'keyD') }]) data2 = tree.StructuredHashTree().include([{ 'key': ('keyA1', 'keyB') }, { 'key': ('keyA1', 'keyC') }, { 'key': ('keyA1', 'keyC', 'keyD') }]) data3 = tree.StructuredHashTree().include([{ 'key': ('keyA2', 'keyB') }, { 'key': ('keyA2', 'keyC') }, { 'key': ('keyA2', 'keyC', 'keyD') }]) self.mgr.update_bulk(self.ctx, [data, data2, data3]) agent1 = resource.Agent(agent_type='aid', host='host', binary_file='binary', hash_trees=['keyA', 'keyA1', 'keyA2'], version='1.0') agent2 = resource.Agent(agent_type='aid', host='host2', binary_file='binary', hash_trees=['keyA', 'keyA2'], version='1.0') agent1 = aim_manager.AimManager().create(self.ctx, agent1) agent2 = aim_manager.AimManager().create(self.ctx, agent2) self.assertEqual(set(['keyA', 'keyA1', 'keyA2']), set(agent1.hash_trees)) self.assertEqual(set(['keyA', 'keyA2']), set(agent2.hash_trees)) # Empty agent2 agent2 = aim_manager.AimManager().update(self.ctx, agent2, hash_trees=[]) # Delete a tree self.mgr.delete(self.ctx, data) if self.ctx.store.supports_foreign_keys: agent1 = aim_manager.AimManager().get(self.ctx, agent1) self.assertEqual(set(['keyA1', 'keyA2']), set(agent1.hash_trees)) self.assertEqual(set(), set(agent2.hash_trees)) # Add rogue key self.assertRaises(exc.HashTreeNotFound, aim_manager.AimManager().update, self.ctx, agent1, hash_trees=['notakey']) # Verify agent1 was rolled back properly agent1 = aim_manager.AimManager().get(self.get_new_context(), agent1) self.assertEqual(set(['keyA1', 'keyA2']), set(agent1.hash_trees))
def __init__(self, conf): self.run_daemon_loop = True self.host = conf.aim.aim_service_identifier aim_ctx = context.AimContext(store=api.get_store()) # This config manager is shared between multiple threads. Therefore # all DB activity through this config manager will use the same # DB session which can result in conflicts. # TODO(amitbose) Fix ConfigManager to not use cached AimContext self.conf_manager = aim_cfg.ConfigManager(aim_ctx, self.host) self.k8s_watcher = None self.single_aid = False if conf.aim.aim_store == 'k8s': self.single_aid = True self.k8s_watcher = k8s_watcher.K8sWatcher() self.k8s_watcher.run() self.multiverse = [] # Define multiverse pairs, First position is desired state self.multiverse += [ # Configuration Universe (AIM to ACI) {DESIRED: aim_universe.AimDbUniverse().initialize( self.conf_manager, self.multiverse), CURRENT: aci_universe.AciUniverse().initialize( self.conf_manager, self.multiverse)}, # Operational Universe (ACI to AIM) {DESIRED: aci_universe.AciOperationalUniverse().initialize( self.conf_manager, self.multiverse), CURRENT: aim_universe.AimDbOperationalUniverse().initialize( self.conf_manager, self.multiverse)}, # Monitored Universe (ACI to AIM) {DESIRED: aci_universe.AciMonitoredUniverse().initialize( self.conf_manager, self.multiverse), CURRENT: aim_universe.AimDbMonitoredUniverse().initialize( self.conf_manager, self.multiverse)}, ] # Operational Universes. ACI operational info will be synchronized into # AIM's self.manager = aim_manager.AimManager() self.tree_manager = tree_manager.HashTreeManager() self.agent_id = 'aid-%s' % self.host self.agent = resource.Agent(id=self.agent_id, agent_type=AGENT_TYPE, host=self.host, binary_file=AGENT_BINARY, description=AGENT_DESCRIPTION, version=AGENT_VERSION) # Register agent self.agent = self.manager.create(aim_ctx, self.agent, overwrite=True) # Report procedure should happen asynchronously self.polling_interval = self.conf_manager.get_option_and_subscribe( self._change_polling_interval, 'agent_polling_interval', group='aim') self.report_interval = self.conf_manager.get_option_and_subscribe( self._change_report_interval, 'agent_report_interval', group='aim') self.squash_time = self.conf_manager.get_option_and_subscribe( self._change_squash_time, 'agent_event_squash_time', group='aim') self._spawn_heartbeat_loop() self.events = event_handler.EventHandler().initialize( self.conf_manager) self.max_down_time = 4 * self.report_interval
def test_single_session_multi_objects(self): with self.ctx.store.begin(subtransactions=True): data = tree.StructuredHashTree().include([{ 'key': ('keyA', 'keyB') }, { 'key': ('keyA', 'keyC') }, { 'key': ('keyA', 'keyC', 'keyD') }]) self.mgr.update(self.ctx, data) agent = resource.Agent(id='test', agent_type='aid', host='host3', binary_file='binary', hash_trees=['keyA'], version='1.0') agent = aim_manager.AimManager().create(self.ctx, agent) # Creation worked self.assertEqual('test', agent.id) data2 = self.mgr.find(self.ctx, root_rn=['keyA'])[0] self.assertEqual(['keyA'], agent.hash_trees) self.assertEqual(data, data2)