Update and add haht rule test cases for locking
Conflicting* rules sent to different PE's immediately rejected without wait. Also allow unofficial support for sqlite /w replicated_policy_engine *duplicate, recursion, schema mismatch Change-Id: I9c634db3c2eddb374914f34dc53a2574f0880461
This commit is contained in:
parent
5f6e9ce316
commit
e66b38ea9a
|
@ -92,7 +92,7 @@ def commit_unlock_tables(session):
|
||||||
# unlock
|
# unlock
|
||||||
if is_mysql():
|
if is_mysql():
|
||||||
session.execute('UNLOCK TABLES')
|
session.execute('UNLOCK TABLES')
|
||||||
# postgres automatically releases lock at transaction
|
# postgres automatically releases lock at transaction end
|
||||||
|
|
||||||
|
|
||||||
def is_mysql():
|
def is_mysql():
|
||||||
|
|
|
@ -147,10 +147,16 @@ def main():
|
||||||
"the '--config-file' option!")
|
"the '--config-file' option!")
|
||||||
if cfg.CONF.replicated_policy_engine and not (
|
if cfg.CONF.replicated_policy_engine and not (
|
||||||
db_api.is_mysql() or db_api.is_postgres()):
|
db_api.is_mysql() or db_api.is_postgres()):
|
||||||
sys.exit("ERROR: replicated_policy_engine option can be used only with"
|
if db_api.is_sqlite():
|
||||||
" MySQL or PostgreSQL database backends. Please set the "
|
LOG.warning("Deploying replicated policy engine with SQLite "
|
||||||
"connection option in [database] section of congress.conf "
|
"backend is not officially supported. Unexpected "
|
||||||
"to use a supported backend.")
|
"behavior may occur. Officially supported backends "
|
||||||
|
"are MySQL and PostgresSQL.")
|
||||||
|
else:
|
||||||
|
sys.exit("ERROR: replicated_policy_engine option can be used only "
|
||||||
|
"with MySQL or PostgreSQL database backends. Please set "
|
||||||
|
"the connection option in [database] section of "
|
||||||
|
"congress.conf to use a supported backend.")
|
||||||
config.setup_logging()
|
config.setup_logging()
|
||||||
|
|
||||||
if not (cfg.CONF.api or cfg.CONF.policy_engine or cfg.CONF.datasources):
|
if not (cfg.CONF.api or cfg.CONF.policy_engine or cfg.CONF.datasources):
|
||||||
|
|
|
@ -3,6 +3,7 @@ bind_port = 4001
|
||||||
auth_strategy = noauth
|
auth_strategy = noauth
|
||||||
datasource_sync_period = 5
|
datasource_sync_period = 5
|
||||||
debug = True
|
debug = True
|
||||||
|
replicated_policy_engine = True
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
# connection = mysql+pymysql://root:password@127.0.0.1/congress?charset=utf8
|
# connection = mysql+pymysql://root:password@127.0.0.1/congress?charset=utf8
|
||||||
|
|
|
@ -3,6 +3,7 @@ bind_port = 4002
|
||||||
auth_strategy = noauth
|
auth_strategy = noauth
|
||||||
datasource_sync_period = 5
|
datasource_sync_period = 5
|
||||||
debug = True
|
debug = True
|
||||||
|
replicated_policy_engine = True
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
# connection = mysql+pymysql://root:password@127.0.0.1/congress?charset=utf8
|
# connection = mysql+pymysql://root:password@127.0.0.1/congress?charset=utf8
|
||||||
|
|
|
@ -24,36 +24,24 @@ from __future__ import print_function
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# Note: monkey patch to allow running this test standalone under 'nose'
|
|
||||||
import eventlet
|
|
||||||
eventlet.monkey_patch()
|
|
||||||
|
|
||||||
# import mock
|
|
||||||
|
|
||||||
# from oslo_config import cfg
|
|
||||||
# cfg.CONF.distributed_architecture = True
|
|
||||||
# import neutronclient.v2_0
|
|
||||||
from oslo_log import log as logging
|
|
||||||
|
|
||||||
# from congress.common import config
|
|
||||||
# from congress.datasources import neutronv2_driver
|
|
||||||
# from congress.datasources import nova_driver
|
|
||||||
from congress.db import api as db
|
|
||||||
from congress.db import db_policy_rules
|
|
||||||
# from congress import harness
|
|
||||||
# from congress.tests.api import base as api_base
|
|
||||||
from congress.tests import base
|
|
||||||
# from congress.tests.datasources import test_neutron_driver as test_neutron
|
|
||||||
from congress.tests import helper
|
|
||||||
|
|
||||||
import requests
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import tenacity
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
# Note: monkey patch to allow running this test standalone under 'nose'
|
||||||
|
import eventlet
|
||||||
|
eventlet.monkey_patch()
|
||||||
|
from oslo_log import log as logging
|
||||||
|
import requests
|
||||||
|
import tenacity
|
||||||
|
|
||||||
|
from congress.db import api as db
|
||||||
|
from congress.db import db_policy_rules
|
||||||
|
from congress.tests import base
|
||||||
|
from congress.tests import helper
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -362,10 +350,6 @@ class TestCongressHAHT(base.SqlTestCase):
|
||||||
self.assertEqual(self.pe1.delete(
|
self.assertEqual(self.pe1.delete(
|
||||||
suffix='policies/alice/rules/%s' % rule_id).status_code, 200)
|
suffix='policies/alice/rules/%s' % rule_id).status_code, 200)
|
||||||
|
|
||||||
# BUG: should be 201 right away not 409
|
|
||||||
self.assertEqual(self.pe2.post(
|
|
||||||
suffix='policies/alice/rules', json=j).status_code, 409)
|
|
||||||
time.sleep(10)
|
|
||||||
self.assertEqual(self.pe2.post(
|
self.assertEqual(self.pe2.post(
|
||||||
suffix='policies/alice/rules', json=j).status_code, 201)
|
suffix='policies/alice/rules', json=j).status_code, 201)
|
||||||
|
|
||||||
|
@ -380,22 +364,83 @@ class TestCongressHAHT(base.SqlTestCase):
|
||||||
suffix='policies', json={'name': 'alice'}).status_code, 201)
|
suffix='policies', json={'name': 'alice'}).status_code, 201)
|
||||||
j = {'rule': 'p(x) :- q(x)', 'name': 'rule1'}
|
j = {'rule': 'p(x) :- q(x)', 'name': 'rule1'}
|
||||||
|
|
||||||
# inconsistent behavior depending on whether duplicate request
|
|
||||||
# is processed on same or different PE node
|
|
||||||
self.assertEqual(self.pe2.post(
|
self.assertEqual(self.pe2.post(
|
||||||
suffix='policies/alice/rules', json=j).status_code, 201)
|
suffix='policies/alice/rules', json=j).status_code, 201)
|
||||||
|
|
||||||
|
self.assertEqual(self.pe1.post(
|
||||||
|
suffix='policies/alice/rules', json=j).status_code, 409)
|
||||||
|
|
||||||
self.assertEqual(self.pe2.post(
|
self.assertEqual(self.pe2.post(
|
||||||
suffix='policies/alice/rules', json=j).status_code, 409)
|
suffix='policies/alice/rules', json=j).status_code, 409)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.pe1.get('policies/alice/rules').status_code, 200)
|
||||||
|
self.assertTrue(
|
||||||
|
len(self.pe1.get('policies/alice/rules').
|
||||||
|
json()['results']) <= 1)
|
||||||
|
self.assertEqual(
|
||||||
|
len(self.pe2.get('policies/alice/rules').
|
||||||
|
json()['results']), 1)
|
||||||
|
except Exception:
|
||||||
|
self.dump_nodes_logs()
|
||||||
|
raise
|
||||||
|
|
||||||
|
def test_policy_rule_recursion(self):
|
||||||
|
try:
|
||||||
|
# create policy alice in PE1
|
||||||
self.assertEqual(self.pe1.post(
|
self.assertEqual(self.pe1.post(
|
||||||
suffix='policies/alice/rules', json=j).status_code, 201)
|
suffix='policies', json={'name': 'alice'}).status_code, 201)
|
||||||
|
r1 = {'rule': 'p(x) :- q(x)', 'name': 'rule1'}
|
||||||
|
r2 = {'rule': 'q(x) :- p(x)', 'name': 'rule2'}
|
||||||
|
|
||||||
|
self.assertEqual(self.pe2.post(
|
||||||
|
suffix='policies/alice/rules', json=r1).status_code, 201)
|
||||||
|
|
||||||
|
self.assertEqual(self.pe1.post(
|
||||||
|
suffix='policies/alice/rules', json=r2).status_code, 400)
|
||||||
|
|
||||||
|
self.assertEqual(self.pe2.post(
|
||||||
|
suffix='policies/alice/rules', json=r2).status_code, 400)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.pe1.get('policies/alice/rules').status_code, 200)
|
self.pe1.get('policies/alice/rules').status_code, 200)
|
||||||
self.assertEqual(
|
self.assertTrue(
|
||||||
len(self.pe1.get('policies/alice/rules').
|
len(self.pe1.get('policies/alice/rules').
|
||||||
json()['results']), 2)
|
json()['results']) <= 1)
|
||||||
|
self.assertEqual(
|
||||||
|
len(self.pe2.get('policies/alice/rules').
|
||||||
|
json()['results']), 1)
|
||||||
|
except Exception:
|
||||||
|
self.dump_nodes_logs()
|
||||||
|
raise
|
||||||
|
|
||||||
|
def test_policy_rule_schema_mismatch(self):
|
||||||
|
try:
|
||||||
|
# create policy alice in PE1
|
||||||
|
self.assertEqual(self.pe1.post(
|
||||||
|
suffix='policies', json={'name': 'alice'}).status_code, 201)
|
||||||
|
r1 = {'rule': 'p(x) :- q(x)', 'name': 'rule1'}
|
||||||
|
r2 = {'rule': 'p(x) :- q(x, x)', 'name': 'rule2'}
|
||||||
|
|
||||||
|
self.assertEqual(self.pe2.post(
|
||||||
|
suffix='policies/alice/rules', json=r1).status_code, 201)
|
||||||
|
|
||||||
|
self.assertEqual(self.pe1.post(
|
||||||
|
suffix='policies/alice/rules', json=r2).status_code, 400)
|
||||||
|
|
||||||
|
self.assertEqual(self.pe2.post(
|
||||||
|
suffix='policies/alice/rules', json=r2).status_code, 400)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.pe1.get('policies/alice/rules').status_code, 200)
|
||||||
|
self.assertTrue(
|
||||||
|
len(self.pe1.get('policies/alice/rules').
|
||||||
|
json()['results']) <= 1)
|
||||||
|
self.assertEqual(
|
||||||
|
self.pe2.get('policies/alice/rules').status_code, 200)
|
||||||
|
self.assertEqual(
|
||||||
|
len(self.pe2.get('policies/alice/rules').
|
||||||
|
json()['results']), 1)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.dump_nodes_logs()
|
self.dump_nodes_logs()
|
||||||
raise
|
raise
|
||||||
|
@ -424,22 +469,6 @@ class TestCongressHAHT(base.SqlTestCase):
|
||||||
self.assertEqual(self.pe2.post(
|
self.assertEqual(self.pe2.post(
|
||||||
suffix='policies/alice/rules', json=j).status_code, 201)
|
suffix='policies/alice/rules', json=j).status_code, 201)
|
||||||
|
|
||||||
# time.sleep(6)
|
|
||||||
# print(self.pe1.get('policies/alice/tables/p/rows').json())
|
|
||||||
# print(self.pe2.get('policies/alice/tables/p/rows').json())
|
|
||||||
#
|
|
||||||
# time.sleep(6)
|
|
||||||
# print(self.pe1.get('policies/alice/tables/p/rows').json())
|
|
||||||
# print(self.pe2.get('policies/alice/tables/p/rows').json())
|
|
||||||
#
|
|
||||||
# self.assertEqual(self.pe1.delete(
|
|
||||||
# suffix='policies/alice/rules/%s' % q1_id).status_code, 200)
|
|
||||||
#
|
|
||||||
# time.sleep(6)
|
|
||||||
# print(self.pe1.get('policies/alice/tables/p/rows').json())
|
|
||||||
# print(self.pe2.get('policies/alice/tables/p/rows').json())
|
|
||||||
# assert False
|
|
||||||
|
|
||||||
# eval on PE1
|
# eval on PE1
|
||||||
helper.retry_check_function_return_value_table(
|
helper.retry_check_function_return_value_table(
|
||||||
lambda: [x['data'] for x in
|
lambda: [x['data'] for x in
|
||||||
|
|
Loading…
Reference in New Issue