Fixed integration of the unit tests with PosrgeSQL
* Corrected the path to the mistral config file in a unit test
* Minor improvement in the run_tests.sh script
* Fixed unstable the `test_rerun_join_with_branch_errors` and
test_rerun_on_join_task test. task3 id is properly passed now
* Removed unused `insert_or_ignore` api and tests. This api
broke the test in PostgreSQL case
* Passed correct value to the filter in
`test_filter_action_definitions_by_has_filter` test
Closes-Bug: #1736821
Change-Id: I2ce3d2e1be001d9c0c76ebe5293b2bf578a7160b
Signed-off-by: Vitalii Solodilov <mcdkr@yandex.ru>
(cherry picked from commit cf0484ad2e
)
This commit is contained in:
parent
920ea89b4a
commit
13497ae3e1
|
@ -373,61 +373,6 @@ def append_string(insert, compiler, **kw):
|
|||
return s
|
||||
|
||||
|
||||
@b.session_aware()
|
||||
def insert_or_ignore(model_cls, values, session=None):
|
||||
"""Insert a new object into DB or ignore if it already exists.
|
||||
|
||||
This method is based on ability of MySQL, PostgreSQL and SQLite
|
||||
to check unique constraint violations and allow user to take a
|
||||
conflict mitigation action. Hence, uniqueness of the object that's
|
||||
being inserted should be considered only from this perspective.
|
||||
|
||||
Note: This method hasn't been tested on databases other than MySQL,
|
||||
PostgreSQL 9.5 or later, and SQLite. Therefore there's no guarantee
|
||||
that it will work with them.
|
||||
|
||||
:param model_cls: Model class.
|
||||
:param values: Values of the new object.
|
||||
"""
|
||||
|
||||
model = model_cls()
|
||||
|
||||
model.update(values)
|
||||
|
||||
append = None
|
||||
replace = None
|
||||
|
||||
dialect = b.get_dialect_name()
|
||||
|
||||
if dialect == 'sqlite':
|
||||
replace = ('INSERT INTO', 'INSERT OR IGNORE INTO')
|
||||
elif dialect == 'mysql':
|
||||
append = 'ON DUPLICATE KEY UPDATE id=id'
|
||||
elif dialect == 'postgres':
|
||||
append = 'ON CONFLICT DO NOTHING'
|
||||
else:
|
||||
raise RuntimeError(
|
||||
'"Insert or ignore" is supported only for dialects: sqlite,'
|
||||
' mysql and postgres. Actual dialect: %s' % dialect
|
||||
)
|
||||
|
||||
insert = model.__table__.insert(
|
||||
append_string=append,
|
||||
replace_string=replace
|
||||
)
|
||||
|
||||
# NOTE(rakhmerov): As it turned out the result proxy object
|
||||
# returned by insert expression does not provide a valid
|
||||
# count of updated rows in for all supported databases.
|
||||
# For this reason we shouldn't return anything from this
|
||||
# method. In order to check whether a new object was really
|
||||
# inserted users should rely on different approaches. The
|
||||
# simplest is just to insert an object with an explicitly
|
||||
# set id and then check if object with such id exists in DB.
|
||||
# Generated id must be unique to make it work.
|
||||
session.execute(insert, model.to_dict())
|
||||
|
||||
|
||||
# Workbook definitions.
|
||||
|
||||
@b.session_aware()
|
||||
|
|
|
@ -19,7 +19,7 @@ from oslo_config import cfg
|
|||
|
||||
def parse_args():
|
||||
# Look for .mistral.conf in the project directory by default.
|
||||
project_dir = '%s/../..' % os.path.dirname(__file__)
|
||||
project_dir = '%s/../../..' % os.path.dirname(__file__)
|
||||
config_file = '%s/.mistral.conf' % os.path.realpath(project_dir)
|
||||
config_files = [config_file] if os.path.isfile(config_file) else None
|
||||
cfg.CONF(args=[], default_config_files=config_files)
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
# Copyright 2015 - Mirantis, Inc.
|
||||
# Copyright 2015 - StackStorm, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from mistral.db.v2.sqlalchemy import api as db_api
|
||||
from mistral.db.v2.sqlalchemy import models as db_models
|
||||
from mistral.tests.unit import base as test_base
|
||||
|
||||
WF_EX = {
|
||||
'id': '1',
|
||||
'spec': {},
|
||||
'start_params': {'task': 'my_task1'},
|
||||
'state': 'IDLE',
|
||||
'state_info': "Running...",
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'context': None,
|
||||
'task_id': None,
|
||||
'trust_id': None,
|
||||
'description': None,
|
||||
'output': None
|
||||
}
|
||||
|
||||
|
||||
TASK_EX = {
|
||||
'workflow_execution_id': '1',
|
||||
'workflow_name': 'my_wf',
|
||||
'name': 'my_task1',
|
||||
'spec': None,
|
||||
'action_spec': None,
|
||||
'state': 'IDLE',
|
||||
'tags': ['deployment'],
|
||||
'in_context': None,
|
||||
'runtime_context': None,
|
||||
'created_at': None,
|
||||
'updated_at': None
|
||||
}
|
||||
|
||||
|
||||
class InsertOrIgnoreTest(test_base.DbTestCase):
|
||||
def setUp(self):
|
||||
super(InsertOrIgnoreTest, self).setUp()
|
||||
|
||||
cfg.CONF.set_default('auth_enable', True, group='pecan')
|
||||
|
||||
db_api.create_workflow_execution(WF_EX)
|
||||
|
||||
self.addCleanup(
|
||||
cfg.CONF.set_default,
|
||||
'auth_enable',
|
||||
False,
|
||||
group='pecan'
|
||||
)
|
||||
|
||||
def test_insert_or_ignore_without_conflicts(self):
|
||||
db_api.insert_or_ignore(
|
||||
db_models.TaskExecution,
|
||||
TASK_EX.copy()
|
||||
)
|
||||
|
||||
task_execs = db_api.get_task_executions()
|
||||
|
||||
self.assertEqual(1, len(task_execs))
|
||||
|
||||
task_ex = task_execs[0]
|
||||
|
||||
self._assert_dict_contains_subset(TASK_EX, task_ex.to_dict())
|
||||
|
||||
def test_insert_or_ignore_with_conflicts(self):
|
||||
# Insert the first object.
|
||||
values = TASK_EX.copy()
|
||||
|
||||
values['unique_key'] = 'key'
|
||||
|
||||
db_api.insert_or_ignore(db_models.TaskExecution, values)
|
||||
|
||||
task_execs = db_api.get_task_executions()
|
||||
|
||||
self.assertEqual(1, len(task_execs))
|
||||
|
||||
task_ex = task_execs[0]
|
||||
|
||||
self._assert_dict_contains_subset(TASK_EX, task_ex.to_dict())
|
||||
|
||||
# Insert the second object with the same unique key.
|
||||
# We must not get exceptions and new object must not be saved.
|
||||
values = TASK_EX.copy()
|
||||
|
||||
values['unique_key'] = 'key'
|
||||
|
||||
db_api.insert_or_ignore(db_models.TaskExecution, values)
|
||||
|
||||
task_execs = db_api.get_task_executions()
|
||||
|
||||
self.assertEqual(1, len(task_execs))
|
||||
|
||||
task_ex = task_execs[0]
|
||||
|
||||
self._assert_dict_contains_subset(TASK_EX, task_ex.to_dict())
|
|
@ -1130,7 +1130,7 @@ class ActionDefinitionTest(SQLAlchemyTest):
|
|||
self.assertEqual(1, len(fetched))
|
||||
self.assertEqual(created3, fetched[0])
|
||||
|
||||
f = filter_utils.create_or_update_filter('name', "Action", 'has')
|
||||
f = filter_utils.create_or_update_filter('name', "action", 'has')
|
||||
|
||||
fetched = db_api.get_action_definitions(**f)
|
||||
|
||||
|
|
|
@ -879,7 +879,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase):
|
|||
self.assertIsNone(task_3_ex.state_info)
|
||||
|
||||
task_3_action_exs = db_api.get_action_executions(
|
||||
task_execution_id=task_execs[2].id
|
||||
task_execution_id=task_3_ex.id
|
||||
)
|
||||
|
||||
self.assertEqual(2, len(task_3_action_exs))
|
||||
|
@ -1026,7 +1026,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase):
|
|||
self.assertEqual(states.SUCCESS, task_3_ex.state)
|
||||
|
||||
task_3_action_exs = db_api.get_action_executions(
|
||||
task_execution_id=task_execs[2].id
|
||||
task_execution_id=task_3_ex.id
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(task_3_action_exs))
|
||||
|
|
20
run_tests.sh
20
run_tests.sh
|
@ -140,15 +140,27 @@ function setup_db {
|
|||
dbname="mistral"
|
||||
username="mistral"
|
||||
password="m1stral"
|
||||
sudo -u postgres psql -c "DROP DATABASE IF EXISTS $dbname;"
|
||||
sudo -u postgres psql -c "DROP USER IF EXISTS $username;"
|
||||
sudo -u postgres psql -c "CREATE USER $username WITH ENCRYPTED PASSWORD '$password';"
|
||||
sudo -u postgres psql -c "CREATE DATABASE $dbname OWNER $username;"
|
||||
|
||||
pg_command "SELECT pg_terminate_backend(pg_stat_activity.pid)
|
||||
FROM pg_stat_activity
|
||||
WHERE pg_stat_activity.datname = '$dbname'
|
||||
AND pid <> pg_backend_pid();"
|
||||
pg_command "DROP DATABASE IF EXISTS $dbname;"
|
||||
pg_command "DROP USER IF EXISTS $username;"
|
||||
pg_command "CREATE USER $username
|
||||
WITH ENCRYPTED PASSWORD '$password';"
|
||||
pg_command "CREATE DATABASE $dbname OWNER $username;"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function pg_command {
|
||||
command=$1
|
||||
|
||||
sudo -u postgres psql -h localhost -c "${command}"
|
||||
}
|
||||
|
||||
function setup_db_pylib {
|
||||
case ${db_type} in
|
||||
postgresql )
|
||||
|
|
Loading…
Reference in New Issue