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:
Vitalii Solodilov 2018-01-08 21:17:36 +04:00 committed by Dougal Matthews
parent 920ea89b4a
commit 13497ae3e1
6 changed files with 20 additions and 176 deletions

View File

@ -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()

View File

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

View File

@ -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())

View File

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

View File

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

View File

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