Fix creating objects with the same names
* Fixed unit-tests * Added new unit-tests * default project_id = <default_project> Closes-bug #1385275 Change-Id: I65e239fe471117f5b11cfb56fec92e90083fe50b
This commit is contained in:
parent
39a6b0c725
commit
5966eee08b
@ -28,6 +28,7 @@ LOG = logging.getLogger(__name__)
|
||||
options.set_defaults(cfg.CONF, sqlite_db="mistral.sqlite")
|
||||
|
||||
_DB_SESSION_THREAD_LOCAL_NAME = "db_sql_alchemy_session"
|
||||
DEFAULT_PROJECT_ID = "<default-project>"
|
||||
|
||||
_facade = None
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
import contextlib
|
||||
import sys
|
||||
|
||||
from oslo.config import cfg
|
||||
from oslo.db import exception as db_exc
|
||||
import sqlalchemy as sa
|
||||
|
||||
@ -27,6 +28,7 @@ from mistral import exceptions as exc
|
||||
from mistral.openstack.common import log as logging
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -84,6 +86,13 @@ def transaction():
|
||||
end_tx()
|
||||
|
||||
|
||||
def _get_project_id():
|
||||
if CONF.pecan.auth_enable and context.has_ctx():
|
||||
return context.ctx().project_id
|
||||
else:
|
||||
return b.DEFAULT_PROJECT_ID
|
||||
|
||||
|
||||
def _delete_all(model, session=None, **kwargs):
|
||||
query = b.model_query(model).filter_by(**kwargs)
|
||||
query.delete()
|
||||
@ -92,7 +101,7 @@ def _delete_all(model, session=None, **kwargs):
|
||||
def _get_collection_sorted_by_name(model, **kwargs):
|
||||
query = b.model_query(model)
|
||||
|
||||
proj = query.filter_by(project_id=context.ctx().project_id, **kwargs)
|
||||
proj = query.filter_by(project_id=_get_project_id(), **kwargs)
|
||||
public = query.filter_by(scope='public', **kwargs)
|
||||
|
||||
return proj.union(public).order_by(model.name).all()
|
||||
@ -172,9 +181,7 @@ def delete_workbook(name, session=None):
|
||||
def _get_workbook(name):
|
||||
query = b.model_query(models.Workbook)
|
||||
|
||||
project_id = context.ctx().project_id if context.has_ctx() else None
|
||||
|
||||
proj = query.filter_by(name=name, project_id=project_id)
|
||||
proj = query.filter_by(name=name, project_id=_get_project_id())
|
||||
public = query.filter_by(name=name, scope='public')
|
||||
|
||||
return proj.union(public).first()
|
||||
@ -210,7 +217,7 @@ def create_workflow(values, session=None):
|
||||
wf = models.Workflow()
|
||||
|
||||
wf.update(values.copy())
|
||||
wf['project_id'] = context.ctx().project_id if context.has_ctx() else None
|
||||
wf['project_id'] = _get_project_id()
|
||||
|
||||
try:
|
||||
wf.save(session=session)
|
||||
@ -230,7 +237,7 @@ def update_workflow(name, values, session=None):
|
||||
"Workflow not found [workflow_name=%s]" % name)
|
||||
|
||||
wf.update(values.copy())
|
||||
wf['project_id'] = context.ctx().project_id if context.has_ctx() else None
|
||||
wf['project_id'] = _get_project_id()
|
||||
|
||||
return wf
|
||||
|
||||
@ -264,9 +271,7 @@ def delete_workflows(**kwargs):
|
||||
def _get_workflow(name):
|
||||
query = b.model_query(models.Workflow)
|
||||
|
||||
project_id = context.ctx().project_id if context.has_ctx() else None
|
||||
|
||||
proj = query.filter_by(name=name, project_id=project_id)
|
||||
proj = query.filter_by(name=name, project_id=_get_project_id())
|
||||
public = query.filter_by(name=name, scope='public')
|
||||
|
||||
return proj.union(public).first()
|
||||
@ -568,13 +573,10 @@ def delete_actions(**kwargs):
|
||||
def _get_action(name):
|
||||
query = b.model_query(models.Action)
|
||||
|
||||
return query.filter_by(name=name).first()
|
||||
proj = query.filter_by(name=name, project_id=_get_project_id())
|
||||
public = query.filter_by(name=name, scope='public')
|
||||
|
||||
|
||||
def _get_actions(**kwargs):
|
||||
query = b.model_query(models.Action)
|
||||
|
||||
return query.filter_by(**kwargs).all()
|
||||
return proj.union(public).first()
|
||||
|
||||
|
||||
# Cron triggers.
|
||||
@ -664,7 +666,10 @@ def delete_cron_triggers(**kwargs):
|
||||
def _get_cron_trigger(name):
|
||||
query = b.model_query(models.CronTrigger)
|
||||
|
||||
return query.filter_by(name=name).first()
|
||||
proj = query.filter_by(name=name, project_id=_get_project_id())
|
||||
public = query.filter_by(name=name, scope='public')
|
||||
|
||||
return proj.union(public).first()
|
||||
|
||||
|
||||
def _get_cron_triggers(**kwargs):
|
||||
|
@ -18,6 +18,7 @@ import json
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from mistral.db.sqlalchemy import base
|
||||
from mistral.db.sqlalchemy import model_base as mb
|
||||
from mistral.db.sqlalchemy import types as st
|
||||
|
||||
@ -39,7 +40,7 @@ class Workbook(mb.MistralModelBase):
|
||||
|
||||
# Security properties.
|
||||
scope = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80), default=base.DEFAULT_PROJECT_ID)
|
||||
trust_id = sa.Column(sa.String(80))
|
||||
|
||||
|
||||
@ -60,7 +61,7 @@ class Workflow(mb.MistralModelBase):
|
||||
|
||||
# Security properties.
|
||||
scope = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80), default=base.DEFAULT_PROJECT_ID)
|
||||
trust_id = sa.Column(sa.String(80))
|
||||
|
||||
|
||||
@ -162,7 +163,7 @@ class Action(mb.MistralModelBase):
|
||||
|
||||
# Security properties.
|
||||
scope = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80), default=base.DEFAULT_PROJECT_ID)
|
||||
trust_id = sa.Column(sa.String(80))
|
||||
|
||||
|
||||
@ -188,7 +189,7 @@ class CronTrigger(mb.MistralModelBase):
|
||||
|
||||
# Security properties.
|
||||
scope = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80))
|
||||
project_id = sa.Column(sa.String(80), default=base.DEFAULT_PROJECT_ID)
|
||||
trust_id = sa.Column(sa.String(80))
|
||||
|
||||
def to_dict(self):
|
||||
|
@ -221,7 +221,7 @@ class DbTestCase(BaseTest):
|
||||
|
||||
self.ctx = auth_context.MistralContext(
|
||||
user_id='1-2-3-4',
|
||||
project_id='5-6-7-8',
|
||||
project_id='<default-project>',
|
||||
user_name='test-user',
|
||||
project_name='test-project',
|
||||
is_admin=False
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
import copy
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from mistral import context as auth_context
|
||||
from mistral.db.v2.sqlalchemy import api as db_api
|
||||
from mistral import exceptions as exc
|
||||
@ -50,7 +52,16 @@ WORKBOOKS = [
|
||||
]
|
||||
|
||||
|
||||
class WorkbookTest(test_base.DbTestCase):
|
||||
class SQLAlchemyTest(test_base.DbTestCase):
|
||||
def setUp(self):
|
||||
super(SQLAlchemyTest, self).setUp()
|
||||
|
||||
cfg.CONF.set_default('auth_enable', True, group='pecan')
|
||||
self.addCleanup(cfg.CONF.set_default, 'auth_enable', False,
|
||||
group='pecan')
|
||||
|
||||
|
||||
class WorkbookTest(SQLAlchemyTest):
|
||||
def test_create_and_get_and_load_workbook(self):
|
||||
created = db_api.create_workbook(WORKBOOKS[0])
|
||||
|
||||
@ -64,6 +75,16 @@ class WorkbookTest(test_base.DbTestCase):
|
||||
|
||||
self.assertIsNone(db_api.load_workbook("not-existing-wb"))
|
||||
|
||||
def test_create_workbook_duplicate_without_auth(self):
|
||||
cfg.CONF.set_default('auth_enable', False, group='pecan')
|
||||
db_api.create_workbook(WORKBOOKS[0])
|
||||
|
||||
self.assertRaises(
|
||||
exc.DBDuplicateEntry,
|
||||
db_api.create_workbook,
|
||||
WORKBOOKS[0]
|
||||
)
|
||||
|
||||
def test_update_workbook(self):
|
||||
created = db_api.create_workbook(WORKBOOKS[0])
|
||||
|
||||
@ -238,7 +259,7 @@ WORKFLOWS = [
|
||||
]
|
||||
|
||||
|
||||
class WorkflowTest(test_base.DbTestCase):
|
||||
class WorkflowTest(SQLAlchemyTest):
|
||||
def test_create_and_get_and_load_workflow(self):
|
||||
created = db_api.create_workflow(WORKFLOWS[0])
|
||||
|
||||
@ -252,6 +273,16 @@ class WorkflowTest(test_base.DbTestCase):
|
||||
|
||||
self.assertIsNone(db_api.load_workflow("not-existing-wf"))
|
||||
|
||||
def test_create_workflow_duplicate_without_auth(self):
|
||||
cfg.CONF.set_default('auth_enable', False, group='pecan')
|
||||
db_api.create_workflow(WORKFLOWS[0])
|
||||
|
||||
self.assertRaises(
|
||||
exc.DBDuplicateEntry,
|
||||
db_api.create_workflow,
|
||||
WORKFLOWS[0]
|
||||
)
|
||||
|
||||
def test_update_workflow(self):
|
||||
created = db_api.create_workflow(WORKFLOWS[0])
|
||||
|
||||
@ -403,7 +434,7 @@ EXECUTIONS = [
|
||||
]
|
||||
|
||||
|
||||
class ExecutionTest(test_base.DbTestCase):
|
||||
class ExecutionTest(SQLAlchemyTest):
|
||||
def test_create_and_get_and_load_execution(self):
|
||||
created = db_api.create_execution(EXECUTIONS[0])
|
||||
|
||||
@ -527,7 +558,7 @@ TASKS = [
|
||||
]
|
||||
|
||||
|
||||
class TaskTest(test_base.DbTestCase):
|
||||
class TaskTest(SQLAlchemyTest):
|
||||
def test_create_and_get_and_load_task(self):
|
||||
ex = db_api.create_execution(EXECUTIONS[0])
|
||||
|
||||
@ -654,7 +685,7 @@ ACTIONS = [
|
||||
'is_system': True,
|
||||
'action_class': 'mypackage.my_module.Action1',
|
||||
'attributes': None,
|
||||
'project_id': '5-6-7-8'
|
||||
'project_id': '<default-project>'
|
||||
},
|
||||
{
|
||||
'name': 'action2',
|
||||
@ -662,12 +693,12 @@ ACTIONS = [
|
||||
'is_system': True,
|
||||
'action_class': 'mypackage.my_module.Action2',
|
||||
'attributes': None,
|
||||
'project_id': '5-6-7-8'
|
||||
'project_id': '<default-project>'
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class ActionTest(test_base.DbTestCase):
|
||||
class ActionTest(SQLAlchemyTest):
|
||||
def setUp(self):
|
||||
super(ActionTest, self).setUp()
|
||||
|
||||
@ -686,6 +717,16 @@ class ActionTest(test_base.DbTestCase):
|
||||
|
||||
self.assertIsNone(db_api.load_action("not-existing-id"))
|
||||
|
||||
def test_create_action_duplicate_without_auth(self):
|
||||
cfg.CONF.set_default('auth_enable', False, group='pecan')
|
||||
db_api.create_action(ACTIONS[0])
|
||||
|
||||
self.assertRaises(
|
||||
exc.DBDuplicateEntry,
|
||||
db_api.create_action,
|
||||
ACTIONS[0]
|
||||
)
|
||||
|
||||
def test_update_action(self):
|
||||
created = db_api.create_action(ACTIONS[0])
|
||||
|
||||
@ -767,7 +808,7 @@ CRON_TRIGGERS = [
|
||||
'workflow_input': {},
|
||||
'next_execution_time': timeutils.utcnow(),
|
||||
'scope': 'private',
|
||||
'project_id': '5-6-7-8'
|
||||
'project_id': '<default-project>'
|
||||
},
|
||||
{
|
||||
'name': 'trigger2',
|
||||
@ -777,12 +818,12 @@ CRON_TRIGGERS = [
|
||||
'workflow_input': {},
|
||||
'next_execution_time': timeutils.utcnow(),
|
||||
'scope': 'private',
|
||||
'project_id': '5-6-7-8'
|
||||
'project_id': '<default-project>'
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class CronTriggerTest(test_base.DbTestCase):
|
||||
class CronTriggerTest(SQLAlchemyTest):
|
||||
def setUp(self):
|
||||
super(CronTriggerTest, self).setUp()
|
||||
|
||||
@ -804,6 +845,16 @@ class CronTriggerTest(test_base.DbTestCase):
|
||||
|
||||
self.assertIsNone(db_api.load_cron_trigger("not-existing-trigger"))
|
||||
|
||||
def test_create_cron_trigger_duplicate_without_auth(self):
|
||||
cfg.CONF.set_default('auth_enable', False, group='pecan')
|
||||
db_api.create_cron_trigger(CRON_TRIGGERS[0])
|
||||
|
||||
self.assertRaises(
|
||||
exc.DBDuplicateEntry,
|
||||
db_api.create_cron_trigger,
|
||||
CRON_TRIGGERS[0]
|
||||
)
|
||||
|
||||
def test_update_cron_trigger(self):
|
||||
created = db_api.create_cron_trigger(CRON_TRIGGERS[0])
|
||||
|
||||
@ -872,7 +923,7 @@ class CronTriggerTest(test_base.DbTestCase):
|
||||
self.assertIn("'name': 'trigger1'", s)
|
||||
|
||||
|
||||
class TXTest(test_base.DbTestCase):
|
||||
class TXTest(SQLAlchemyTest):
|
||||
def test_rollback(self):
|
||||
db_api.start_tx()
|
||||
|
||||
|
@ -17,7 +17,7 @@ from oslo.config import cfg
|
||||
from mistral.db.v2 import api as db_api
|
||||
from mistral.openstack.common import log as logging
|
||||
from mistral.services import workbooks as wb_service
|
||||
from mistral.tests.unit.engine1 import base
|
||||
from mistral.tests import base
|
||||
from mistral.workbook import parser as spec_parser
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -106,7 +106,7 @@ workflows:
|
||||
"""
|
||||
|
||||
|
||||
class WorkbookServiceTest(base.EngineTestCase):
|
||||
class WorkbookServiceTest(base.DbTestCase):
|
||||
def test_create_workbook(self):
|
||||
wb_db = wb_service.create_workbook_v2({'definition': WORKBOOK})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user