def test_communication(self): """Test the module's ability to be loaded into the DSE by checking its ability to communicate on the message bus. """ cage = congress.dse.d6cage.d6Cage() # so that we exit once test finishes; all other threads are forced # to be daemons cage.daemon = True cage.start() # Create modules. # Turn off polling so we don't need to deal with real data. args = helper.datasource_openstack_args() args['poll_time'] = 0 cage.loadModule("NovaDriver", helper.data_module_path("nova_driver.py")) cage.loadModule("PolicyDriver", helper.policy_module_path()) cage.createservice(name="policy", moduleName="PolicyDriver", args={'d6cage': cage, 'rootdir': helper.data_module_path('')}) cage.createservice(name="nova", moduleName="NovaDriver", args=args) # Check that data gets sent from nova to policy as expected nova = cage.service_object('nova') policy = cage.service_object('policy') policy.subscribe('nova', 'server', callback=policy.receive_data) # publishing is slightly convoluted b/c deltas are computed # automatically. (Not just convenient--useful so that DSE # properly handles the initial state problem.) # Need to set nova.state and nova.prior_state and then publish # anything. # publish server(1), server(2), server(3) helper.pause() nova.prior_state = {} nova.state['server'] = set([(1,), (2,), (3,)]) nova.publish('server', None) helper.pause() e = helper.db_equal( policy.select('nova:server(x)'), 'nova:server(1) nova:server(2) nova:server(3)') self.assertTrue(e, 'Nova insertion 1') # publish server(1), server(4), server(5) helper.pause() nova.prior_state['server'] = nova.state['server'] nova.state['server'] = set([(1,), (4,), (5,)]) nova.publish('server', None) helper.pause() e = helper.db_equal( policy.select('nova:server(x)'), 'nova:server(1) nova:server(4) nova:server(5)') self.assertTrue(e, 'Nova insertion 2')
def test_communication(self): """Test for communication. Test the module's ability to be loaded into the DSE by checking its ability to communicate on the message bus. """ cage = d6cage.d6Cage() # Create modules. # Turn off polling so we don't need to deal with real data. args = helper.datasource_openstack_args() args['poll_time'] = 0 cage.loadModule("NovaDriver", helper.data_module_path("nova_driver.py")) cage.loadModule("PolicyDriver", helper.policy_module_path()) cage.createservice(name="policy", moduleName="PolicyDriver", args={ 'd6cage': cage, 'rootdir': helper.data_module_path('') }) cage.createservice(name="nova", moduleName="NovaDriver", args=args) # Check that data gets sent from nova to policy as expected nova = cage.service_object('nova') policy = cage.service_object('policy') policy.debug_mode() policy.create_policy('nova') policy.set_schema('nova', compile.Schema({'server': (1, )})) policy.subscribe('nova', 'server', callback=policy.receive_data) # publishing is slightly convoluted b/c deltas are computed # automatically. (Not just convenient--useful so that DSE # properly handles the initial state problem.) # Need to set nova.state and nova.prior_state and then publish # anything. # publish server(1), server(2), server(3) helper.retry_check_subscribers(nova, [(policy.name, 'server')]) nova.prior_state = {} nova.state['server'] = set([(1, ), (2, ), (3, )]) nova.publish('server', None) helper.retry_check_db_equal( policy, 'nova:server(x)', 'nova:server(1) nova:server(2) nova:server(3)') # publish server(1), server(4), server(5) nova.prior_state['server'] = nova.state['server'] nova.state['server'] = set([(1, ), (4, ), (5, )]) nova.publish('server', None) helper.retry_check_db_equal( policy, 'nova:server(x)', 'nova:server(1) nova:server(4) nova:server(5)')
def test_communication(self): """Test for communication. Test the module's ability to be loaded into the DSE by checking its ability to communicate on the message bus. """ cage = d6cage.d6Cage() # Create modules. # Turn off polling so we don't need to deal with real data. args = helper.datasource_openstack_args() args['poll_time'] = 0 cage.loadModule("NovaDriver", helper.data_module_path("nova_driver.py")) cage.loadModule("PolicyDriver", helper.policy_module_path()) cage.createservice(name="policy", moduleName="PolicyDriver", args={'d6cage': cage, 'rootdir': helper.data_module_path(''), 'log_actions_only': True}) cage.createservice(name="nova", moduleName="NovaDriver", args=args) # Check that data gets sent from nova to policy as expected nova = cage.service_object('nova') policy = cage.service_object('policy') policy.debug_mode() policy.create_policy('nova') policy.set_schema('nova', compile.Schema({'server': (1,)})) policy.subscribe('nova', 'server', callback=policy.receive_data) # publishing is slightly convoluted b/c deltas are computed # automatically. (Not just convenient--useful so that DSE # properly handles the initial state problem.) # Need to set nova.state and nova.prior_state and then publish # anything. # publish server(1), server(2), server(3) helper.retry_check_subscribers(nova, [(policy.name, 'server')]) nova.prior_state = {} nova.state['server'] = set([(1,), (2,), (3,)]) nova.publish('server', None) helper.retry_check_db_equal( policy, 'nova:server(x)', 'nova:server(1) nova:server(2) nova:server(3)') # publish server(1), server(4), server(5) nova.prior_state['server'] = nova.state['server'] nova.state['server'] = set([(1,), (4,), (5,)]) nova.publish('server', None) helper.retry_check_db_equal( policy, 'nova:server(x)', 'nova:server(1) nova:server(4) nova:server(5)')
def test_cage(self): """Test basic DSE functionality.""" cage = congress.dse.d6cage.d6Cage() # so that we exit once test finishes; all other threads are forced # to be daemons cage.daemon = True cage.start() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) cage.createservice(name="test1", moduleName="TestDriver", args={'poll_time': 0}) cage.createservice(name="test2", moduleName="TestDriver", args={'poll_time': 0}) test1 = cage.service_object('test1') test2 = cage.service_object('test2') test1.subscribe('test2', 'p', callback=test1.receive_msg) test2.publish('p', 42) helper.pause() # give other threads chance to run # logging.debug("d6cage:: dataPath = {}; inbox = {}".format( # policy.runtime.iterstr(list(cage.dataPath.queue)), # policy.runtime.iterstr(list(cage.inbox.queue)))) # logging.debug("test1:: dataPath = {}; inbox = {}".format( # policy.runtime.iterstr(list(test1.dataPath.queue)), # policy.runtime.iterstr(list(test1.inbox.queue)))) # logging.debug("test2:: dataPath = {}; inbox = {}".format( # policy.runtime.iterstr(list(test2.dataPath.queue)), # policy.runtime.iterstr(list(test2.inbox.queue)))) self.assertTrue(test1.msg.body, 42)
def setUp(self): super(BenchmarkDatasource, self).setUp() config = {'benchmark': { 'module': helper.data_module_path('benchmark_driver.py'), 'poll_time': 0}} cage = harness.create(helper.root_path(), None, config) engine = cage.service_object('engine') api = {'policy': cage.service_object('api-policy'), 'rule': cage.service_object('api-rule'), 'table': cage.service_object('api-table'), 'row': cage.service_object('api-row'), 'datasource': cage.service_object('api-datasource'), 'status': cage.service_object('api-status'), 'schema': cage.service_object('api-schema')} helper.retry_check_subscriptions(engine, [(api['rule'].name, 'policy-update')]) helper.retry_check_subscribers(api['rule'], [(engine.name, 'policy-update')]) self.assertTrue('benchmark' in cage.services) datasource = cage.service_object('benchmark') table_name = datasource.BENCHTABLE self.assertEqual(datasource.state, {}) # add a subscriber to ensure the updates end up in datasource.dataPath pubdata = datasource.pubdata.setdefault(table_name, dataobj.pubData(table_name)) pubdata.addsubscriber(self.__class__.__name__, "push", "") self.assertTrue(datasource.pubdata[table_name]) self.cage = cage self.engine = engine self.api = api self.table_name = table_name self.datasource = datasource
def test_policy_data(self): """Test policy properly inserts data and processes it normally.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule( "TestDriver", helper.data_module_path("../tests/datasources/test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={ 'd6cage': cage, 'rootdir': '' }) data = cage.services['data']['object'] policy = cage.services['policy']['object'] # turn off module-schema syntax checking policy.create_policy('data') policy.set_schema('data', compile.Schema({'p': (1, )})) policy.subscribe('data', 'p', callback=policy.receive_data) formula = policy.parse1('p(1)') # sending a single Insert. (Default for Event is Insert.) data.publish('p', [runtime.Event(formula)]) helper.retry_check_db_equal(policy, 'data:p(x)', 'data:p(1)')
def test_initialize_tables_dse(self): """Test performance of initializing data with DSE and Engine. This test populates the tables exported by a datasource driver, and then invokes the poll() method to send that data to the policy engine. It tests the amount of time to send tables across the DSE and load them into the policy engine. """ MAX_TUPLES = 700 # install datasource driver we can control self.cage.loadModule( "TestDriver", helper.data_module_path("../tests/datasources/test_driver.py")) self.cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) driver = self.cage.service_object('data') driver.poll_time = 0 self.engine.create_policy('data') # set return value for datasource driver facts = [(1, 2.3, 'foo', 'bar', i, 'a' * 100 + str(i)) for i in range(MAX_TUPLES)] driver.state = {'p': facts} # Send formula to engine (so engine subscribes to data:p) policy = self.engine.DEFAULT_THEORY formula = compile.parse1( 'q(1) :- data:p(1, 2.3, "foo", "bar", 1, %s)' % ('a' * 100 + '1')) self.api['rule'].publish('policy-update', [agnostic.Event(formula, target=policy)]) # Poll data and wait til it arrives at engine driver.poll() self.wait_til_query_nonempty('q(1)', policy)
def test_initialize_tables_dse(self): """Test performance of initializing data with DSE and Engine. This test populates the tables exported by a datasource driver, and then invokes the poll() method to send that data to the policy engine. It tests the amount of time to send tables across the DSE and load them into the policy engine. """ MAX_TUPLES = 700 # install datasource driver we can control self.cage.loadModule("TestDriver", helper.data_module_path("../tests/datasources/test_driver.py")) self.cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) driver = self.cage.service_object("data") driver.poll_time = 0 self.engine.create_policy("data") # set return value for datasource driver facts = [(1, 2.3, "foo", "bar", i, "a" * 100 + str(i)) for i in range(MAX_TUPLES)] driver.state = {"p": facts} # Send formula to engine (so engine subscribes to data:p) policy = self.engine.DEFAULT_THEORY formula = compile.parse1('q(1) :- data:p(1, 2.3, "foo", "bar", 1, %s)' % ("a" * 100 + "1")) self.api["rule"].publish("policy-update", [compile.Event(formula, target=policy)]) # Poll data and wait til it arrives at engine driver.poll() self.wait_til_query_nonempty("q(1)", policy)
def test_policy_table_publish(self): """Policy table result publish Test basic DSE functionality with policy engine and table result publish. """ cage = congress.dse.d6cage.d6Cage() cage.loadModule("TestDriver", helper.data_module_path( "../tests/datasources/test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={'d6cage': cage, 'rootdir': '', 'log_actions_only': True}) data = cage.services['data']['object'] policy = cage.services['policy']['object'] policy.create_policy('data') policy.create_policy('classification') policy.set_schema('data', compile.Schema({'q': (1,)})) policy.insert('p(x):-data:q(x),gt(x,2)', target='classification') data.subscribe('policy', 'classification:p', callback=data.receive_msg) helper.retry_check_subscribers(policy, [('data', 'classification:p')]) self.assertEqual(policy.policySubData.keys(), [('p', 'classification', None)]) policy.insert('q(1)', target='data') # no entry here self.assertEqual(data.get_msg_data(), '{}') policy.insert('q(2)', target='data') policy.insert('q(3)', target='data') # get an update helper.retry_check_for_message_data(data, 'insert[p(3)]') self.assertEqual(data.get_msg_data(), 'insert[p(3)]') # subscribe again to get a full table data.subscribe('policy', 'classification:p', callback=data.receive_msg) helper.retry_check_for_message_data(data, 'p(3)') self.assertEqual(data.get_msg_data(), 'p(3)') # get another update policy.insert('q(4)', target='data') helper.retry_check_for_message_data(data, 'insert[p(4)]') self.assertEqual(data.get_msg_data(), 'insert[p(4)]') # get another update policy.delete('q(4)', target='data') helper.retry_check_for_message_data(data, 'delete[p(4)]') self.assertEqual(data.get_msg_data(), 'delete[p(4)]') data.unsubscribe('policy', 'classification:p') # trigger removed helper.retry_check_no_subscribers(policy, [('data', 'classification:p')]) self.assertEqual(policy.policySubData.keys(), [])
def test_cage(self): """Test basic DSE functionality.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) args = helper.datasource_openstack_args() args['poll_time'] = 0 cage.createservice(name="test1", moduleName="TestDriver", args=args) cage.createservice(name="test2", moduleName="TestDriver", args=args) test1 = cage.service_object('test1') test2 = cage.service_object('test2') test1.subscribe('test2', 'p', callback=test1.receive_msg) test2.publish('p', 42) helper.retry_check_for_message_to_arrive(test1) self.assertTrue(test1.msg.body, 42)
def test_cage(self): """Test basic DSE functionality.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule( "TestDriver", helper.data_module_path("../tests/datasources/test_driver.py")) args = helper.datasource_openstack_args() args['poll_time'] = 0 cage.createservice(name="test1", moduleName="TestDriver", args=args) cage.createservice(name="test2", moduleName="TestDriver", args=args) test1 = cage.service_object('test1') test2 = cage.service_object('test2') test1.subscribe('test2', 'p', callback=test1.receive_msg) test2.publish('p', 42) helper.retry_check_for_message_to_arrive(test1) self.assertTrue(test1.msg.body, 42)
def test_policy(self): """Test basic DSE functionality with policy engine.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={'d6cage': cage, 'rootdir': ''}) data = cage.services['data']['object'] policy = cage.services['policy']['object'] policy.subscribe('data', 'p', callback=policy.receive_msg) data.publish('p', 42) helper.retry_check_for_message_to_arrive(policy) self.assertTrue(policy.msg.body, 42)
def test_policy_tables(self): """Test basic DSE functionality with policy engine and the API.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule( "TestDriver", helper.data_module_path("../tests/datasources/test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) # using regular testdriver as API for now cage.createservice(name="api", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={ 'd6cage': cage, 'rootdir': '' }) data = cage.services['data']['object'] api = cage.services['api']['object'] policy = cage.services['policy']['object'] policy.create_policy('data') policy.set_schema('data', compile.Schema({'q': (1, )})) policy.subscribe('api', 'policy-update', callback=policy.receive_policy_update) # simulate API call for insertion of policy statements formula = policy.parse1('p(x) :- data:q(x)') api.publish('policy-update', [runtime.Event(formula)]) helper.retry_check_nonempty_last_policy_change(policy) # simulate data source publishing to q formula = policy.parse1('q(1)') data.publish('q', [runtime.Event(formula)]) helper.retry_check_db_equal(policy, 'data:q(x)', 'data:q(1)') # check that policy did the right thing with data e = helper.db_equal(policy.select('p(x)'), 'p(1)') self.assertTrue(e, 'Policy insert') # check that publishing into 'p' does not work formula = policy.parse1('p(3)') data.publish('p', [runtime.Event(formula)]) # can't actually check that the update for p does not arrive # so instead wait a bit and check helper.pause() e = helper.db_equal(policy.select('p(x)'), 'p(1)') self.assertTrue(e, 'Policy non-insert')
def test_initialize_tables_full(self): """Test performance of initializing data with Datasource, DSE, Engine. This test gives a datasource driver the Python data that would have resulted from making an API call and parsing it into Python and then polls that datasource, waiting until the data arrives in the policy engine. It tests the amount of time required to translate Python data into tables, send those tables over the DSE, and load them into the policy engine. """ MAX_TUPLES = 700 # install datasource driver we can control self.cage.loadModule( "PerformanceTestDriver", helper.data_module_path( "../tests/datasources/performance_datasource_driver.py")) self.cage.createservice(name="data", moduleName="PerformanceTestDriver", args=helper.datasource_openstack_args()) driver = self.cage.service_object('data') driver.poll_time = 0 self.engine.create_policy('data') # set return value for datasource driver facts = [{ 'field1': 1, 'field2': 2.3, 'field3': 'foo', 'field4': 'bar', 'field5': i, 'field6': 'a' * 100 + str(i) } for i in range(MAX_TUPLES)] driver.client_data = facts # Send formula to engine (so engine subscribes to data:p) policy = self.engine.DEFAULT_THEORY formula = compile.parse1( 'q(1) :- data:p(1, 2.3, "foo", "bar", 1, %s)' % ('a' * 100 + '1')) LOG.info("publishing rule") self.api['rule'].publish('policy-update', [agnostic.Event(formula, target=policy)]) # Poll data and wait til it arrives at engine driver.poll() self.wait_til_query_nonempty('q(1)', policy)
def test_initialize_tables_full(self): """Test performance of initializing data with Datasource, DSE, Engine. This test gives a datasource driver the Python data that would have resulted from making an API call and parsing it into Python and then polls that datasource, waiting until the data arrives in the policy engine. It tests the amount of time required to translate Python data into tables, send those tables over the DSE, and load them into the policy engine. """ MAX_TUPLES = 700 # install datasource driver we can control self.cage.loadModule( "PerformanceTestDriver", helper.data_module_path( "../tests/datasources/performance_datasource_driver.py")) self.cage.createservice( name="data", moduleName="PerformanceTestDriver", args=helper.datasource_openstack_args()) driver = self.cage.service_object('data') driver.poll_time = 0 self.engine.create_policy('data') # set return value for datasource driver facts = [{'field1': 1, 'field2': 2.3, 'field3': 'foo', 'field4': 'bar', 'field5': i, 'field6': 'a'*100 + str(i)} for i in range(MAX_TUPLES)] driver.client_data = facts # Send formula to engine (so engine subscribes to data:p) policy = self.engine.DEFAULT_THEORY formula = compile.parse1( 'q(1) :- data:p(1, 2.3, "foo", "bar", 1, %s)' % ('a'*100 + '1')) LOG.info("publishing rule") self.api['rule'].publish( 'policy-update', [agnostic.Event(formula, target=policy)]) # Poll data and wait til it arrives at engine driver.poll() self.wait_til_query_nonempty('q(1)', policy)
def test_policy(self): """Test basic DSE functionality with policy engine.""" cage = congress.dse.d6cage.d6Cage() # so that we exit once test finishes; all other threads are forced # to be daemons cage.daemon = True cage.start() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver") cage.createservice(name="policy", moduleName="TestPolicy") data = cage.services['data']['object'] policy = cage.services['policy']['object'] policy.subscribe('data', 'p', callback=policy.receive_msg) data.publish('p', 42) helper.pause() # give other threads chance to run self.assertTrue(policy.msg.body, 42)
def test_policy_data(self): """Test policy properly inserts data and processes it normally.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={'d6cage': cage, 'rootdir': ''}) data = cage.services['data']['object'] policy = cage.services['policy']['object'] # turn off module-schema syntax checking policy.set_schema('data', compile.Schema({'p': (1,)})) policy.subscribe('data', 'p', callback=policy.receive_data) formula = compile.parse1('p(1)') # sending a single Insert. (Default for Event is Insert.) data.publish('p', [runtime.Event(formula)]) helper.retry_check_db_equal(policy, 'data:p(x)', 'data:p(1)')
def test_policy_tables(self): """Test basic DSE functionality with policy engine and the API.""" cage = congress.dse.d6cage.d6Cage() # so that we exit once test finishes; all other threads are forced # to be daemons cage.daemon = True cage.start() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) # using regular testdriver as API for now cage.createservice(name="api", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={'d6cage': cage, 'rootdir': ''}) data = cage.services['data']['object'] api = cage.services['api']['object'] policy = cage.services['policy']['object'] policy.subscribe('api', 'policy-update', callback=policy.receive_policy_update) # simulate API call for insertion of policy statements formula = compile.parse1('p(x) :- data:q(x)') api.publish('policy-update', [runtime.Event(formula)]) helper.pause() # simulate data source publishing to q formula = compile.parse1('q(1)') data.publish('q', [runtime.Event(formula)]) helper.pause() # give other threads chance to run # check that policy did the right thing with data e = helper.db_equal(policy.select('data:q(x)'), 'data:q(1)') self.assertTrue(e, 'Policy insert 1') e = helper.db_equal(policy.select('p(x)'), 'p(1)') self.assertTrue(e, 'Policy insert 2') #check that publishing into 'p' does not work formula = compile.parse1('p(3)') data.publish('p', [runtime.Event(formula)]) helper.pause() e = helper.db_equal(policy.select('p(x)'), 'p(1)') self.assertTrue(e, 'Policy noninsert')
def setUp(self): super(BenchmarkDatasource, self).setUp() config = { 'benchmark': { 'module': helper.data_module_path('benchmark_driver.py'), 'poll_time': 0 } } cage = harness.create(helper.root_path(), helper.state_path(), None, config) engine = cage.service_object('engine') api = { 'policy': cage.service_object('api-policy'), 'rule': cage.service_object('api-rule'), 'table': cage.service_object('api-table'), 'row': cage.service_object('api-row'), 'datasource': cage.service_object('api-datasource'), 'status': cage.service_object('api-status'), 'schema': cage.service_object('api-schema') } helper.retry_check_subscriptions(engine, [(api['rule'].name, 'policy-update')]) helper.retry_check_subscribers(api['rule'], [(engine.name, 'policy-update')]) self.assertTrue('benchmark' in cage.services) datasource = cage.service_object('benchmark') table_name = datasource.BENCHTABLE self.assertEqual(datasource.state, {}) # add a subscriber to ensure the updates end up in datasource.dataPath pubdata = datasource.pubdata.setdefault(table_name, dataobj.pubData(table_name)) pubdata.addsubscriber(self.__class__.__name__, "push", "") self.assertTrue(datasource.pubdata[table_name]) self.cage = cage self.engine = engine self.api = api self.table_name = table_name self.datasource = datasource
def test_policy_tables(self): """Test basic DSE functionality with policy engine and the API.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule("TestDriver", helper.data_module_path( "../tests/datasources/test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) # using regular testdriver as API for now cage.createservice(name="api", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={'d6cage': cage, 'rootdir': '', 'log_actions_only': True}) data = cage.services['data']['object'] api = cage.services['api']['object'] policy = cage.services['policy']['object'] policy.create_policy('data') policy.set_schema('data', compile.Schema({'q': (1,)})) policy.subscribe('api', 'policy-update', callback=policy.receive_policy_update) # simulate API call for insertion of policy statements formula = policy.parse1('p(x) :- data:q(x)') api.publish('policy-update', [compile.Event(formula)]) helper.retry_check_nonempty_last_policy_change(policy) # simulate data source publishing to q formula = policy.parse1('q(1)') data.publish('q', [compile.Event(formula)]) helper.retry_check_db_equal(policy, 'data:q(x)', 'data:q(1)') # check that policy did the right thing with data e = helper.db_equal(policy.select('p(x)'), 'p(1)') self.assertTrue(e, 'Policy insert') # check that publishing into 'p' does not work formula = policy.parse1('p(3)') data.publish('p', [compile.Event(formula)]) # can't actually check that the update for p does not arrive # so instead wait a bit and check helper.pause() e = helper.db_equal(policy.select('p(x)'), 'p(1)') self.assertTrue(e, 'Policy non-insert')
def test_policy_data(self): """Test policy properly inserts data and processes it normally.""" cage = congress.dse.d6cage.d6Cage() # so that we exit once test finishes; all other threads are forced # to be daemons cage.daemon = True cage.start() cage.loadModule("TestDriver", helper.data_module_path("test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver") cage.createservice(name="policy", moduleName="TestPolicy") data = cage.services['data']['object'] policy = cage.services['policy']['object'] policy.subscribe('data', 'p', callback=policy.receive_data) formula = compile.parse1('p(1)') # sending a single Insert. (Default for Event is Insert.) data.publish('p', [runtime.Event(formula)]) helper.pause() # give other threads chance to run e = helper.db_equal(policy.select('data:p(x)'), 'data:p(1)') self.assertTrue(e, 'Single insert')
def test_policy(self): """Test basic DSE functionality with policy engine.""" cage = congress.dse.d6cage.d6Cage() cage.loadModule( "TestDriver", helper.data_module_path("../tests/datasources/test_driver.py")) cage.loadModule("TestPolicy", helper.policy_module_path()) cage.createservice(name="data", moduleName="TestDriver", args=helper.datasource_openstack_args()) cage.createservice(name="policy", moduleName="TestPolicy", args={ 'd6cage': cage, 'rootdir': '' }) data = cage.services['data']['object'] policy = cage.services['policy']['object'] policy.subscribe('data', 'p', callback=policy.receive_msg) data.publish('p', 42) helper.retry_check_for_message_to_arrive(policy) self.assertTrue(policy.msg.body, 42)
def setUp(self): """Setup polling tests.""" super(TestDataSourceDriver, self).setUp() cage = d6cage.d6Cage() # Create mock of Neutron client so we can control data mock_factory = mox.Mox() neutron_client = mock_factory.CreateMock( neutronclient.v2_0.client.Client) neutron_client.list_networks().InAnyOrder(1).AndReturn(network1) neutron_client.list_ports().InAnyOrder(1).AndReturn(port_response) neutron_client.list_routers().InAnyOrder(1).AndReturn(router_response) neutron_client.list_security_groups().InAnyOrder(1).AndReturn( security_group_response) neutron_client.list_networks().InAnyOrder(2).AndReturn(network2) neutron_client.list_ports().InAnyOrder(2).AndReturn(port_response) neutron_client.list_routers().InAnyOrder(2).AndReturn(router_response) neutron_client.list_security_groups().InAnyOrder(2).AndReturn( security_group_response) mock_factory.ReplayAll() # Create modules (without auto-polling) cage.loadModule("NeutronDriver", helper.data_module_path("neutron_driver.py")) cage.loadModule("PolicyDriver", helper.policy_module_path()) cage.createservice(name="policy", moduleName="PolicyDriver", args={'d6cage': cage, 'rootdir': helper.data_module_path(''), 'log_actions_only': True}) args = helper.datasource_openstack_args() args['poll_time'] = 0 args['client'] = neutron_client cage.createservice(name="neutron", moduleName="NeutronDriver", args=args) policy = cage.service_object('policy') policy.create_policy('neutron') policy.set_schema( 'neutron', cage.service_object('neutron').get_schema()) cage.service_object('neutron').neutron = neutron_client policy.debug_mode() # insert rule into policy to make testing easier. # (Some of the IDs are auto-generated each time we convert) policy.insert(create_network_group('p')) # create some garbage data args = helper.datasource_openstack_args() driver = neutron_driver.NeutronDriver(args=args) network_key_to_index = driver.get_column_map( neutron_driver.NeutronDriver.NETWORKS) network_max_index = max(network_key_to_index.values()) args1 = ['1'] * (network_max_index + 1) args2 = ['2'] * (network_max_index + 1) args1 = ",".join(args1) args2 = ",".join(args2) fake_networks = [ 'neutron:networks({})'.format(args1), 'neutron:networks({})'.format(args2)] # answer to query above for network1 datalog1 = ( 'p("240ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("340ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("440ff9df-df35-43ae-9df5-27fae87f2492")') # answer to query above for network2 datalog2 = ( 'p("240ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("640ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("540ff9df-df35-43ae-9df5-27fae87f2492")') # return value self.info = {} self.info['cage'] = cage self.info['datalog1'] = datalog1 self.info['datalog2'] = datalog2 self.info['fake_networks'] = fake_networks
def setUp(self): """Setup polling tests.""" super(TestDataSourceDriver, self).setUp() cage = d6cage.d6Cage() # Create mock of Neutron client so we can control data mock_factory = mox.Mox() neutron_client = mock_factory.CreateMock( neutronclient.v2_0.client.Client) neutron_client.list_networks().InAnyOrder(1).AndReturn(network1) neutron_client.list_ports().InAnyOrder(1).AndReturn(port_response) neutron_client.list_routers().InAnyOrder(1).AndReturn(router_response) neutron_client.list_security_groups().InAnyOrder(1).AndReturn( security_group_response) neutron_client.list_networks().InAnyOrder(2).AndReturn(network2) neutron_client.list_ports().InAnyOrder(2).AndReturn(port_response) neutron_client.list_routers().InAnyOrder(2).AndReturn(router_response) neutron_client.list_security_groups().InAnyOrder(2).AndReturn( security_group_response) mock_factory.ReplayAll() # Create modules (without auto-polling) cage.loadModule("NeutronDriver", helper.data_module_path("neutron_driver.py")) cage.loadModule("PolicyDriver", helper.policy_module_path()) cage.createservice(name="policy", moduleName="PolicyDriver", args={ 'd6cage': cage, 'rootdir': helper.data_module_path('') }) args = helper.datasource_openstack_args() args['poll_time'] = 0 args['client'] = neutron_client cage.createservice(name="neutron", moduleName="NeutronDriver", args=args) policy = cage.service_object('policy') policy.create_policy('neutron') policy.set_schema('neutron', cage.service_object('neutron').get_schema()) cage.service_object('neutron').neutron = neutron_client policy.debug_mode() # insert rule into policy to make testing easier. # (Some of the IDs are auto-generated each time we convert) policy.insert(create_network_group('p')) # create some garbage data args = helper.datasource_openstack_args() driver = neutron_driver.NeutronDriver(args=args) network_key_to_index = driver.get_column_map( neutron_driver.NeutronDriver.NETWORKS) network_max_index = max(network_key_to_index.values()) args1 = ['1'] * (network_max_index + 1) args2 = ['2'] * (network_max_index + 1) args1 = ",".join(args1) args2 = ",".join(args2) fake_networks = [ 'neutron:networks({})'.format(args1), 'neutron:networks({})'.format(args2) ] # answer to query above for network1 datalog1 = ('p("240ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("340ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("440ff9df-df35-43ae-9df5-27fae87f2492")') # answer to query above for network2 datalog2 = ('p("240ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("640ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("540ff9df-df35-43ae-9df5-27fae87f2492")') # return value self.info = {} self.info['cage'] = cage self.info['datalog1'] = datalog1 self.info['datalog2'] = datalog2 self.info['fake_networks'] = fake_networks
def setup_polling(self, debug_mode=False): """Setup polling tests.""" cage = congress.dse.d6cage.d6Cage() # so that we exit once test finishes; all other threads are forced # to be daemons cage.daemon = True cage.start() # Create mock of Neutron client so we can control data mock_factory = mox.Mox() neutron_client = mock_factory.CreateMock( neutronclient.v2_0.client.Client) neutron_client.list_networks().InAnyOrder(1).AndReturn(network1) neutron_client.list_ports().InAnyOrder(1).AndReturn(port_response) neutron_client.list_networks().InAnyOrder(2).AndReturn(network2) neutron_client.list_ports().InAnyOrder(2).AndReturn(port_response) mock_factory.ReplayAll() # Create modules (without auto-polling) cage.loadModule("NeutronDriver", helper.data_module_path("neutron_driver.py")) cage.loadModule("PolicyDriver", helper.policy_module_path()) cage.createservice(name="policy", moduleName="PolicyDriver") cage.createservice(name="neutron", moduleName="NeutronDriver", args={'poll_time': 0, 'client': neutron_client}) policy = cage.service_object('policy') # Make it so that we get detailed info from policy engine if debug_mode: policy.debug_mode() # insert rule into policy to make testing easier. # (Some of the IDs are auto-generated each time we convert) policy.insert(create_network_group('p')) # create some garbage data network_key_to_index = NeutronDriver.network_key_position_map() network_max_index = max(network_key_to_index.values()) args1 = ['1'] * (network_max_index + 1) args2 = ['2'] * (network_max_index + 1) args1 = ",".join(args1) args2 = ",".join(args2) fake_networks = [ 'neutron:networks({})'.format(args1), 'neutron:networks({})'.format(args2)] # answer to query above for network1 datalog1 = \ ('p("240ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("340ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("440ff9df-df35-43ae-9df5-27fae87f2492")') # answer to query above for network2 datalog2 = \ ('p("240ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("640ff9df-df35-43ae-9df5-27fae87f2492") ' 'p("540ff9df-df35-43ae-9df5-27fae87f2492")') # return value d = {} d['cage'] = cage d['datalog1'] = datalog1 d['datalog2'] = datalog2 d['fake_networks'] = fake_networks return d