Пример #1
0
    def test_policy_data_update(self):
        """Test policy correctly processes initial data snapshot and update."""
        node = helper.make_dsenode_new_partition('testnode')
        node.always_snapshot = False
        data = fake_datasource.FakeDataSource('data')
        engine = agnostic.DseRuntime(api_base.ENGINE_SERVICE_ID)
        node.register_service(data)
        node.register_service(engine)

        engine.create_policy('policy1')
        engine.create_policy('data')
        self.insert_rule(engine, 'p(x) :- data:fake_table(x)', 'policy1')
        data.state = {'fake_table': set([(1, ), (2, )])}
        data.poll()
        helper.retry_check_db_equal(engine,
                                    'p(x)',
                                    'p(1) p(2)',
                                    target='policy1')
        data.state = {'fake_table': set([(1, ), (2, ), (3, )])}
        data.poll()
        helper.retry_check_db_equal(engine,
                                    'p(x)',
                                    'p(1) p(2) p(3)',
                                    target='policy1')
        self.assertFalse(hasattr(engine, "last_msg"))
        node.stop()
Пример #2
0
    def test_policy_data_late_sub(self):
        """Test policy correctly processes data on late subscribe."""
        node = helper.make_dsenode_new_partition('testnode')
        data = fake_datasource.FakeDataSource('data')
        engine = agnostic.DseRuntime(api_base.ENGINE_SERVICE_ID)
        node.register_service(data)
        node.register_service(engine)

        engine.create_policy('policy1')
        engine.create_policy('data', kind=datalog_base.DATASOURCE_POLICY_TYPE)
        data.state = {'fake_table': set([(1, ), (2, )])}
        data.poll()
        self.insert_rule(engine, 'p(x) :- data:fake_table(x)', 'policy1')
        helper.retry_check_db_equal(engine,
                                    'p(x)',
                                    'p(1) p(2)',
                                    target='policy1')
        data.state = {'fake_table': set([(1, ), (2, ), (3, )])}
        data.poll()
        helper.retry_check_db_equal(engine,
                                    'p(x)',
                                    'p(1) p(2) p(3)',
                                    target='policy1')
        self.assertFalse(hasattr(engine, "last_msg"))
        node.stop()
Пример #3
0
 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)')
Пример #4
0
 def test_set_policy(self):
     LOG.info("set_policy")
     self.vmplace.set_policy('p(x) :- fake:q(x)')
     self.fake.state = {'q': set([tuple([1]), tuple([2])])}
     self.fake.poll()
     ans = ('p(1) p(2)')
     helper.retry_check_db_equal(self.vmplace, 'p(x)', ans)
Пример #5
0
 def test_set_policy(self):
     LOG.info("set_policy")
     self.vmplace.set_policy('p(x) :- fake:q(x)')
     self.fake.state = {'q': set([tuple([1]), tuple([2])])}
     self.fake.poll()
     ans = ('p(1) p(2)')
     helper.retry_check_db_equal(self.vmplace, 'p(x)', ans)
Пример #6
0
 def test_set_policy(self):
     LOG.info("set_policy")
     self.vmplace.set_policy("p(x) :- fake:q(x)")
     self.fake.state = {"q": set([tuple([1]), tuple([2])])}
     self.fake.poll()
     ans = "p(1) p(2)"
     helper.retry_check_db_equal(self.vmplace, "p(x)", ans)
Пример #7
0
    def test_rule_api_model(self):
        """Test the rule api model.

        Same as test_multiple except we use the api interface
        instead of the DSE interface.
        """
        api = self.api
        cage = self.cage
        engine = self.engine
        policy = engine.DEFAULT_THEORY

        # Insert formula
        net_formula = test_neutron.create_networkXnetwork_group('p')
        LOG.debug("Sending formula: %s", net_formula)
        engine.debug_mode()
        context = {'policy_id': engine.DEFAULT_THEORY}
        (id1, _) = api['rule'].add_item(
            {'rule': str(net_formula)}, {}, context=context)
        # Poll
        neutron = cage.service_object('neutron')
        neutron2 = cage.service_object('neutron2')
        neutron.poll()
        neutron2.poll()
        # Insert a second formula
        other_formula = engine.parse1('q(x,y) :- p(x,y)')
        (id2, _) = api['rule'].add_item(
            {'rule': str(other_formula)}, {}, context=context)
        ans1 = ('p("240ff9df-df35-43ae-9df5-27fae87f2492",  '
                '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
        ans2 = ('q("240ff9df-df35-43ae-9df5-27fae87f2492",  '
                '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
        # Wait for first query so messages can be delivered.
        #    But once the p table has its data, no need to wait anymore.
        helper.retry_check_db_equal(engine, 'p(x,y)', ans1, target=policy)
        e = helper.db_equal(engine.select('q(x,y)', target=policy), ans2)
        self.assertTrue(e, "Insert rule-api 2")
        # Get formula
        ruleobj = api['rule'].get_item(id1, {}, context=context)
        self.assertTrue(e, net_formula == engine.parse1(ruleobj['rule']))
        # Get all formulas
        ds = api['rule'].get_items({}, context=context)['results']
        self.assertEqual(len(ds), 2)
        ids = set([x['id'] for x in ds])
        rules = set([engine.parse1(x['rule']) for x in ds])
        self.assertEqual(ids, set([id1, id2]))
        self.assertEqual(rules, set([net_formula, other_formula]))
        # Delete formula
        api['rule'].delete_item(id1, {}, context=context)
        # Get all formulas
        ds = api['rule'].get_items({}, context=context)['results']
        self.assertEqual(len(ds), 1)
        ids = sorted([x['id'] for x in ds])
        self.assertEqual(ids, sorted([id2]))
Пример #8
0
    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)')
Пример #9
0
    def test_rule_api_model(self):
        """Test the rule api model.

        Same as test_multiple except we use the api interface
        instead of the DSE interface.
        """
        api = self.api
        cage = self.cage
        engine = self.engine
        policy = engine.DEFAULT_THEORY

        # Insert formula
        net_formula = test_neutron.create_networkXnetwork_group('p')
        LOG.debug("Sending formula: %s", net_formula)
        engine.debug_mode()
        context = {'policy_id': engine.DEFAULT_THEORY}
        (id1, rule) = api['rule'].add_item({'rule': str(net_formula)}, {},
                                           context=context)
        # Poll
        neutron = cage.service_object('neutron')
        neutron2 = cage.service_object('neutron2')
        neutron.poll()
        neutron2.poll()
        # Insert a second formula
        other_formula = engine.parse1('q(x,y) :- p(x,y)')
        (id2, rule) = api['rule'].add_item({'rule': str(other_formula)}, {},
                                           context=context)
        ans1 = ('p("240ff9df-df35-43ae-9df5-27fae87f2492",  '
                '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
        ans2 = ('q("240ff9df-df35-43ae-9df5-27fae87f2492",  '
                '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
        # Wait for first query so messages can be delivered.
        #    But once the p table has its data, no need to wait anymore.
        helper.retry_check_db_equal(engine, 'p(x,y)', ans1, target=policy)
        e = helper.db_equal(engine.select('q(x,y)', target=policy), ans2)
        self.assertTrue(e, "Insert rule-api 2")
        # Get formula
        ruleobj = api['rule'].get_item(id1, {}, context=context)
        self.assertTrue(e, net_formula == engine.parse1(ruleobj['rule']))
        # Get all formulas
        ds = api['rule'].get_items({}, context=context)['results']
        self.assertEqual(len(ds), 2)
        ids = set([x['id'] for x in ds])
        rules = set([engine.parse1(x['rule']) for x in ds])
        self.assertEqual(ids, set([id1, id2]))
        self.assertEqual(rules, set([net_formula, other_formula]))
        # Delete formula
        api['rule'].delete_item(id1, {}, context=context)
        # Get all formulas
        ds = api['rule'].get_items({}, context=context)['results']
        self.assertEqual(len(ds), 1)
        ids = sorted([x['id'] for x in ds])
        self.assertEqual(ids, sorted([id2]))
Пример #10
0
    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_double_poll_subscribe(self):
        """Test double polling before subscribing."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog2 = self.info['datalog2']

        # poll twice and then subscribe: should see 2nd result
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 1)
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 2)
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_db_equal(policy, 'p(x)', datalog2)
Пример #12
0
    def test_double_poll_subscribe(self):
        """Test double polling before subscribing."""
        cage = self.info["cage"]
        policy = cage.service_object("policy")
        neutron = cage.service_object("neutron")
        datalog2 = self.info["datalog2"]

        # poll twice and then subscribe: should see 2nd result
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 1)
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 2)
        policy.subscribe("neutron", "networks", callback=policy.receive_data)
        helper.retry_check_db_equal(policy, "p(x)", datalog2)
Пример #13
0
    def test_double_poll_subscribe(self):
        """Test double polling before subscribing."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog2 = self.info['datalog2']

        # poll twice and then subscribe: should see 2nd result
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 1)
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 2)
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_db_equal(policy, 'p(x)', datalog2)
Пример #14
0
    def test_policy(self):
        node = helper.make_dsenode_new_partition('testnode')
        data = FakeDataSource('data')
        engine = Dse2Runtime('engine')
        node.register_service(data)
        node.register_service(engine)

        engine.create_policy('alpha')
        engine.create_policy('data')
        self.insert_rule(engine, 'p(x) :- data:fake_table(x)', 'alpha')
        data.state = {'fake_table': set([(1,), (2,)])}
        data.poll()
        helper.retry_check_db_equal(
            engine, 'p(x)', 'p(1) p(2)', target='alpha')
        self.assertFalse(hasattr(engine, "last_msg"))
Пример #15
0
 def test_neutron(self):
     """Test polling and publishing of neutron updates."""
     engine = self.engine
     api = self.api
     cage = self.cage
     # Send formula
     formula = test_neutron.create_network_group('p')
     LOG.debug("Sending formula: %s", formula)
     api['rule'].publish('policy-update', [runtime.Event(formula)])
     helper.retry_check_nonempty_last_policy_change(engine)
     LOG.debug("All services: %s", cage.services.keys())
     neutron = cage.service_object('neutron')
     neutron.poll()
     ans = ('p("240ff9df-df35-43ae-9df5-27fae87f2492") ')
     helper.retry_check_db_equal(engine, 'p(x)', ans)
Пример #16
0
 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')
Пример #17
0
    def test_policy_data(self):
        """Test policy correctly processes initial data snapshot."""
        node = helper.make_dsenode_new_partition('testnode')
        node.always_snapshot = False
        data = fake_datasource.FakeDataSource('data')
        engine = agnostic.DseRuntime(api_base.ENGINE_SERVICE_ID)
        node.register_service(data)
        node.register_service(engine)

        engine.create_policy('policy1')
        engine.create_policy('data')
        self.insert_rule(engine, 'p(x) :- data:fake_table(x)', 'policy1')
        data.state = {'fake_table': set([(1,), (2,)])}
        data.poll()
        helper.retry_check_db_equal(
            engine, 'p(x)', 'p(1) p(2)', target='policy1')
        self.assertFalse(hasattr(engine, "last_msg"))
Пример #18
0
    def test_policy_recovery(self):
        """Test policy crashing and recovering (sort of)."""
        cage = self.info["cage"]
        policy = cage.service_object("policy")
        neutron = cage.service_object("neutron")
        datalog1 = self.info["datalog1"]

        # get initial data
        policy.subscribe("neutron", "networks", callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, "networks")])
        neutron.poll()
        helper.retry_check_db_equal(policy, "p(x)", datalog1)

        # clear out policy's neutron:networks data (to simulate crashing)
        policy.initialize_tables(["neutron:networks"], [])
        # subscribe again (without unsubscribing)
        policy.subscribe("neutron", "networks", callback=policy.receive_data)
        helper.retry_check_db_equal(policy, "p(x)", datalog1)
    def test_policy_recovery(self):
        """Test policy crashing and recovering (sort of)."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']

        # get initial data
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, 'networks')])
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)

        # clear out policy's neutron:networks data (to simulate crashing)
        policy.initialize_tables(['neutron:networks'], [])
        # subscribe again (without unsubscribing)
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)
Пример #20
0
    def test_policy_recovery(self):
        """Test policy crashing and recovering (sort of)."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']

        # get initial data
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, 'networks')])
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)

        # clear out policy's neutron:networks data (to simulate crashing)
        policy.initialize_tables(['neutron:networks'], [])
        # subscribe again (without unsubscribing)
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)
Пример #21
0
    def test_neutron(self):
        """Test polling and publishing of neutron updates."""
        engine = self.engine
        api = self.api
        cage = self.cage
        policy = engine.DEFAULT_THEORY

        # Send formula
        formula = test_neutron.create_network_group('p')
        LOG.debug("Sending formula: %s", formula)
        api['rule'].publish('policy-update',
                            [agnostic.Event(formula, target=policy)])
        helper.retry_check_nonempty_last_policy_change(engine)
        LOG.debug("All services: %s", cage.services.keys())
        neutron = cage.service_object('neutron')
        neutron.poll()
        ans = ('p("240ff9df-df35-43ae-9df5-27fae87f2492") ')
        helper.retry_check_db_equal(engine, 'p(x)', ans, target=policy)
Пример #22
0
    def test_policy_initialization(self):
        """Test subscribing before polling.  The common case."""
        cage = self.info["cage"]
        policy = cage.service_object("policy")
        neutron = cage.service_object("neutron")
        datalog1 = self.info["datalog1"]
        fake_networks = self.info["fake_networks"]

        # add garbage to policy
        for formula in fake_networks:
            policy.insert(formula)

        # subscribe
        policy.subscribe("neutron", "networks", callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, "networks")])

        # poll 1
        neutron.poll()
        helper.retry_check_db_equal(policy, "p(x)", datalog1)
Пример #23
0
    def test_policy_initialization(self):
        """Test subscribing before polling.  The common case."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']
        fake_networks = self.info['fake_networks']

        # add garbage to policy
        for formula in fake_networks:
            policy.insert(formula)

        # subscribe
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, 'networks')])

        # poll 1
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)
Пример #24
0
    def test_subscribe_poll(self):
        """Test subscribing before polling.  The common case."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']
        datalog2 = self.info['datalog2']

        # subscribe
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, 'networks')])

        # poll 1
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)

        # poll 2
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog2)
    def test_subscribe_poll(self):
        """Test subscribing before polling.  The common case."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']
        datalog2 = self.info['datalog2']

        # subscribe
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, 'networks')])

        # poll 1
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)

        # poll 2
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog2)
    def test_policy_initialization(self):
        """Test subscribing before polling.  The common case."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']
        fake_networks = self.info['fake_networks']

        # add garbage to policy
        for formula in fake_networks:
            policy.insert(formula)

        # subscribe
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, 'networks')])

        # poll 1
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)
Пример #27
0
    def test_subscribe_poll(self):
        """Test subscribing before polling.  The common case."""
        cage = self.info["cage"]
        policy = cage.service_object("policy")
        neutron = cage.service_object("neutron")
        datalog1 = self.info["datalog1"]
        datalog2 = self.info["datalog2"]

        # subscribe
        policy.subscribe("neutron", "networks", callback=policy.receive_data)
        helper.retry_check_subscribers(neutron, [(policy.name, "networks")])

        # poll 1
        neutron.poll()
        helper.retry_check_db_equal(policy, "p(x)", datalog1)

        # poll 2
        neutron.poll()
        helper.retry_check_db_equal(policy, "p(x)", datalog2)
Пример #28
0
    def test_multiple(self):
        """Test polling and publishing of multiple neutron instances."""
        api = self.api
        cage = self.cage
        engine = self.engine

        # Send formula
        formula = create_networkXnetwork_group('p')
        api['rule'].publish('policy-update', [runtime.Event(formula)])
        helper.retry_check_nonempty_last_policy_change(engine)
        # poll datasources
        neutron = cage.service_object('neutron')
        neutron2 = cage.service_object('neutron2')
        neutron.poll()
        neutron2.poll()
        # check answer
        ans = ('p("240ff9df-df35-43ae-9df5-27fae87f2492",  '
               '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
        helper.retry_check_db_equal(engine, 'p(x,y)', ans)
Пример #29
0
 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)')
Пример #30
0
 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')
Пример #31
0
    def test_policy_data_late_sub(self):
        """Test policy correctly processes data on late subscribe."""
        node = helper.make_dsenode_new_partition('testnode')
        data = fake_datasource.FakeDataSource('data')
        engine = agnostic.DseRuntime(api_base.ENGINE_SERVICE_ID)
        node.register_service(data)
        node.register_service(engine)

        engine.create_policy('policy1')
        engine.create_policy('data', kind=datalog_base.DATASOURCE_POLICY_TYPE)
        data.state = {'fake_table': set([(1,), (2,)])}
        data.poll()
        self.insert_rule(engine, 'p(x) :- data:fake_table(x)', 'policy1')
        helper.retry_check_db_equal(
            engine, 'p(x)', 'p(1) p(2)', target='policy1')
        data.state = {'fake_table': set([(1,), (2,), (3,)])}
        data.poll()
        helper.retry_check_db_equal(
            engine, 'p(x)', 'p(1) p(2) p(3)', target='policy1')
        self.assertFalse(hasattr(engine, "last_msg"))
        node.stop()
Пример #32
0
    def test_multiple(self):
        """Test polling and publishing of multiple neutron instances."""
        api = self.api
        cage = self.cage
        engine = self.engine
        policy = engine.DEFAULT_THEORY

        # Send formula
        formula = test_neutron.create_networkXnetwork_group('p')
        api['rule'].publish('policy-update',
                            [agnostic.Event(formula, target=policy)])
        helper.retry_check_nonempty_last_policy_change(engine)
        # poll datasources
        neutron = cage.service_object('neutron')
        neutron2 = cage.service_object('neutron2')
        neutron.poll()
        neutron2.poll()
        # check answer
        ans = ('p("240ff9df-df35-43ae-9df5-27fae87f2492",  '
               '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
        helper.retry_check_db_equal(engine, 'p(x,y)', ans, target=policy)
Пример #33
0
    def test_policy_data_late_sub(self):
        """Test policy correctly processes data on late subscribe."""
        node = helper.make_dsenode_new_partition('testnode')
        node.always_snapshot = False
        data = FakeDataSource('data')
        engine = Dse2Runtime('engine')
        node.register_service(data)
        node.register_service(engine)

        engine.create_policy('policy1')
        engine.create_policy('data')
        data.state = {'fake_table': set([(1,), (2,)])}
        data.poll()
        self.insert_rule(engine, 'p(x) :- data:fake_table(x)', 'policy1')
        helper.retry_check_db_equal(
            engine, 'p(x)', 'p(1) p(2)', target='policy1')
        data.state = {'fake_table': set([(1,), (2,), (3,)])}
        data.poll()
        helper.retry_check_db_equal(
            engine, 'p(x)', 'p(1) p(2) p(3)', target='policy1')
        self.assertFalse(hasattr(engine, "last_msg"))
Пример #34
0
 def test_neutron_policy_poll_and_subscriptions(self):
     """Test polling and publishing of neutron updates."""
     policy = self.engine.DEFAULT_THEORY
     neutron2 = self._create_neutron_mock('neutron2')
     self.engine.initialize_datasource('neutron',
                                       self.neutronv2.get_schema())
     self.engine.initialize_datasource('neutron2',
                                       self.neutronv2.get_schema())
     str_rule = ('p(x0, y0) :- neutron:networks(x0, x1, x2, x3, x4, x5), '
                 'neutron2:networks(y0, y1, y2, y3, y4, y5)')
     rule = {'rule': str_rule, 'name': 'testrule1', 'comment': 'test'}
     self.api['api-rule'].add_item(rule, {}, context={'policy_id': policy})
     # Test policy subscriptions
     subscriptions = self.engine.subscription_list()
     self.assertEqual(sorted([('neutron', 'networks'),
                      ('neutron2', 'networks')]), sorted(subscriptions))
     # Test multiple instances
     self.neutronv2.poll()
     neutron2.poll()
     ans = ('p("240ff9df-df35-43ae-9df5-27fae87f2492", '
            '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
     helper.retry_check_db_equal(self.engine, 'p(x, y)', ans, target=policy)
    def test_poll_subscribe(self):
        """Test polling before subscribing."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']
        datalog2 = self.info['datalog2']
        fake_networks = self.info['fake_networks']

        # add garbage to policy
        for formula in fake_networks:
            policy.insert(formula)

        # poll 1 and then subscribe; should still see first result
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 1)
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)

        # poll 2
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog2)
Пример #36
0
    def test_poll_subscribe(self):
        """Test polling before subscribing."""
        cage = self.info['cage']
        policy = cage.service_object('policy')
        neutron = cage.service_object('neutron')
        datalog1 = self.info['datalog1']
        datalog2 = self.info['datalog2']
        fake_networks = self.info['fake_networks']

        # add garbage to policy
        for formula in fake_networks:
            policy.insert(formula)

        # poll 1 and then subscribe; should still see first result
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 1)
        policy.subscribe('neutron', 'networks', callback=policy.receive_data)
        helper.retry_check_db_equal(policy, 'p(x)', datalog1)

        # poll 2
        neutron.poll()
        helper.retry_check_db_equal(policy, 'p(x)', datalog2)
Пример #37
0
    def test_poll_subscribe(self):
        """Test polling before subscribing."""
        cage = self.info["cage"]
        policy = cage.service_object("policy")
        neutron = cage.service_object("neutron")
        datalog1 = self.info["datalog1"]
        datalog2 = self.info["datalog2"]
        fake_networks = self.info["fake_networks"]

        # add garbage to policy
        for formula in fake_networks:
            policy.insert(formula)

        # poll 1 and then subscribe; should still see first result
        neutron.poll()
        helper.retry_check_number_of_updates(neutron, 1)
        policy.subscribe("neutron", "networks", callback=policy.receive_data)
        helper.retry_check_db_equal(policy, "p(x)", datalog1)

        # poll 2
        neutron.poll()
        helper.retry_check_db_equal(policy, "p(x)", datalog2)
Пример #38
0
 def test_neutron_policy_poll_and_subscriptions(self):
     """Test polling and publishing of neutron updates."""
     policy = self.engine.DEFAULT_THEORY
     neutron2 = self._create_neutron_mock('neutron2')
     self.engine.initialize_datasource('neutron',
                                       self.neutronv2.get_schema())
     self.engine.initialize_datasource('neutron2',
                                       self.neutronv2.get_schema())
     str_rule = ('p(x0, y0) :- neutron:networks(x0, x1, x2, x3, x4, x5), '
                 'neutron2:networks(y0, y1, y2, y3, y4, y5)')
     rule = {'rule': str_rule, 'name': 'testrule1', 'comment': 'test'}
     self.api['api-rule'].add_item(rule, {}, context={'policy_id': policy})
     # Test policy subscriptions
     subscriptions = self.engine.subscription_list()
     self.assertEqual(sorted([('neutron', 'networks'),
                      ('neutron2', 'networks')]), sorted(subscriptions))
     # Test multiple instances
     self.neutronv2.poll()
     neutron2.poll()
     ans = ('p("240ff9df-df35-43ae-9df5-27fae87f2492", '
            '  "240ff9df-df35-43ae-9df5-27fae87f2492") ')
     helper.retry_check_db_equal(self.engine, 'p(x, y)', ans, target=policy)
Пример #39
0
    def test_policy_table_publish(self):
        """Policy table result publish

        Test basic DSE functionality with policy engine and table result
        publish.
        """
        node = helper.make_dsenode_new_partition('testnode')
        data = fake_datasource.FakeDataSource('data')
        policy = agnostic.DseRuntime('policy')
        policy2 = agnostic.DseRuntime('policy2')
        node.register_service(data)
        node.register_service(policy)
        node.register_service(policy2)
        policy.synchronizer = mock.MagicMock()
        policy2.synchronizer = mock.MagicMock()

        policy.create_policy('data', kind=datalog_base.DATASOURCE_POLICY_TYPE)
        policy.create_policy('classification')
        policy.set_schema('data', compile.Schema({'q': (1, )}))
        policy.insert('p(x):-data:q(x),gt(x,2)', target='classification')

        policy.insert('q(3)', target='data')
        # TODO(ekcs): test that no publish triggered (because no subscribers)

        policy2.create_policy('policy')
        policy2.subscribe('policy', 'classification:p')
        helper.retry_check_function_return_value(
            lambda: 'classification:p' in policy.
            _published_tables_with_subscriber, True)
        self.assertEqual(list(policy.policySubData.keys()),
                         [('p', 'classification', None)])

        helper.retry_check_db_equal(policy2, 'policy:classification:p(x)',
                                    'policy:classification:p(3)')

        policy.insert('q(4)', target='data')
        helper.retry_check_db_equal(policy2, 'policy:classification:p(x)',
                                    ('policy:classification:p(3)'
                                     ' policy:classification:p(4)'))

        # test that no change to p means no publish triggered
        policy.insert('q(2)', target='data')
        # TODO(ekcs): test no publish triggered

        policy.delete('q(4)', target='data')
        helper.retry_check_db_equal(policy2, 'policy:classification:p(x)',
                                    'policy:classification:p(3)')

        policy2.unsubscribe('policy', 'classification:p')
        # trigger removed
        helper.retry_check_function_return_value(
            lambda: len(policy._published_tables_with_subscriber) == 0, True)
        self.assertEqual(list(policy.policySubData.keys()), [])

        policy.insert('q(4)', target='data')
        # TODO(ekcs): test that no publish triggered (because no subscribers)
        node.stop()
Пример #40
0
    def test_policy_table_publish(self):
        """Policy table result publish

        Test basic DSE functionality with policy engine and table result
        publish.
        """
        node = helper.make_dsenode_new_partition('testnode')
        data = fake_datasource.FakeDataSource('data')
        policy = agnostic.DseRuntime('policy')
        policy2 = agnostic.DseRuntime('policy2')
        node.register_service(data)
        node.register_service(policy)
        node.register_service(policy2)

        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')

        policy.insert('q(3)', target='data')
        # TODO(ekcs): test that no publish triggered (because no subscribers)

        policy2.create_policy('policy')
        policy2.subscribe('policy', 'classification:p')
        helper.retry_check_function_return_value(
            lambda: 'classification:p' in
            policy._published_tables_with_subscriber, True)
        self.assertEqual(list(policy.policySubData.keys()),
                         [('p', 'classification', None)])

        helper.retry_check_db_equal(
            policy2, 'policy:classification:p(x)',
            'policy:classification:p(3)')

        policy.insert('q(4)', target='data')
        helper.retry_check_db_equal(
            policy2, 'policy:classification:p(x)',
            ('policy:classification:p(3)'
             ' policy:classification:p(4)'))

        # test that no change to p means no publish triggered
        policy.insert('q(2)', target='data')
        # TODO(ekcs): test no publish triggered

        policy.delete('q(4)', target='data')
        helper.retry_check_db_equal(
            policy2, 'policy:classification:p(x)',
            'policy:classification:p(3)')

        policy2.unsubscribe('policy', 'classification:p')
        # trigger removed
        helper.retry_check_function_return_value(
            lambda: len(policy._published_tables_with_subscriber) == 0, True)
        self.assertEqual(list(policy.policySubData.keys()), [])

        policy.insert('q(4)', target='data')