def task_delete(session, uuid, status=None): (session.query(models.WorkloadData).filter_by(task_uuid=uuid).delete( synchronize_session=False)) (session.query(models.Workload).filter_by(task_uuid=uuid).delete( synchronize_session=False)) (session.query(models.Subtask).filter_by(task_uuid=uuid).delete( synchronize_session=False)) (session.query(models.Tag).filter_by( uuid=uuid, type=consts.TagType.TASK).delete(synchronize_session=False)) query = session.query(models.Task).filter_by(uuid=uuid) if status: count = query.filter_by(status=status).delete( synchronize_session="fetch") else: count = query.delete(synchronize_session="fetch") if not count: if status is not None: task = query.first() if task: raise exceptions.DBConflict( "Task `%(uuid)s` in `%(actual)s` status but " "`%(require)s` is required." % { "uuid": uuid, "require": status, "actual": task.status }) raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="tasks")
def env_get_status(self, uuid): resp = (self.model_query(models.Env).filter_by(uuid=uuid).options( sa.orm.load_only("status")).first()) if not resp: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="envs") return resp["status"]
def _verification_get(session, verification_uuid): verification = session.query(models.Verification).filter_by( uuid=verification_uuid).first() if not verification: raise exceptions.DBRecordNotFound( criteria="uuid: %s" % verification_uuid, table="verifications") return verification
def task_update(session, uuid, values): values.pop("uuid", None) tags = values.pop("tags", None) task = session.query(models.Task).filter_by(uuid=uuid).first() if not task: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="tasks") task.update(values) task = task.as_dict() if tags is not None: # TODO(boris-42): create separate method for tags editing tags_in_db = session.query(models.Tag.tag).filter_by( uuid=uuid, type=consts.TagType.TASK).distinct() new_tags = set(tags) - set(tags_in_db) removed_tags = set(tags_in_db) - set(tags) (session.query(models.Tag).filter_by( uuid=uuid, type=consts.TagType.TASK).filter( models.Tag.tag.in_(removed_tags)).delete( synchronize_session=False)) if new_tags: session.bulk_save_objects( models.Tag(uuid=uuid, tag=t, type=consts.TagType.TASK) for t in set(new_tags)) task["tags"] = tags else: task["tags"] = [] return task
def verifier_delete(session, verifier_id): count = (session.query(models.Verifier) .filter(sa.or_(models.Verifier.name == verifier_id, models.Verifier.uuid == verifier_id)) .delete(synchronize_session=False)) if not count: raise exceptions.DBRecordNotFound( criteria="name or uuid is %s" % verifier_id, table="verifiers")
def test_use_not_found(self, mock__print, mock_env_manager_get): mock_env_manager_get.side_effect = exceptions.DBRecordNotFound( criteria="", table="") env_ = str(uuid.uuid4()) self.assertEqual(1, self.env.use(self.api, env_)) mock_env_manager_get.assert_called_once_with(env_) mock__print.assert_called_once_with( "Can't use non existing environment %s." % env_, False)
def task_get_status(session, uuid=None): task = (session.query(models.Task).options( sa.orm.load_only("status")).filter_by(uuid=uuid).first()) if not task: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="tasks") return task.status
def _verifier_get(self, verifier_id, session=None): verifier = self.model_query(models.Verifier, session=session).filter( sa.or_(models.Verifier.name == verifier_id, models.Verifier.uuid == verifier_id)).first() if not verifier: raise exceptions.DBRecordNotFound(criteria="name or uuid is %s" % verifier_id, table="verifiers") return verifier
def env_get(self, uuid_or_name): env = (self.model_query(models.Env).filter( sa.or_(models.Env.uuid == uuid_or_name, models.Env.name == uuid_or_name)).first()) if not env: raise exceptions.DBRecordNotFound(criteria="uuid or name is %s" % uuid_or_name, table="envs") return env
def verification_delete(self, verification_uuid): session = get_session() with session.begin(): count = self.model_query( models.Verification, session=session).filter_by( uuid=verification_uuid).delete(synchronize_session=False) if not count: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % verification_uuid, table="verifications")
def _task_get(self, uuid, load_only=None, session=None): pre_query = self.model_query(models.Task, session=session) if load_only: pre_query = pre_query.options(sa.orm.load_only(load_only)) task = pre_query.filter_by(uuid=uuid).first() if not task: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="tasks") task.tags = sorted(self._tags_get(uuid, consts.TagType.TASK, session)) return task
def task_update_status(session, uuid, status, allowed_statuses): result = (session.query(models.Task) .filter(models.Task.uuid == uuid, models.Task.status.in_(allowed_statuses)) .update({"status": status}, synchronize_session=False)) if not result: raise exceptions.DBRecordNotFound( criteria="uuid=%(uuid)s and status in [%(statuses)s]" % {"uuid": uuid, "statuses": ", ".join(allowed_statuses)}, table="tasks") return result
def verifier_delete(self, verifier_id): session = get_session() with session.begin(): query = self.model_query(models.Verifier, session=session).filter( sa.or_(models.Verifier.name == verifier_id, models.Verifier.uuid == verifier_id)) count = query.delete(synchronize_session=False) if not count: raise exceptions.DBRecordNotFound( criteria="name or uuid is %s" % verifier_id, table="verifiers")
def task_get(session, uuid=None, detailed=False): task = session.query(models.Task).filter_by(uuid=uuid).first() if not task: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="tasks") task = task.as_dict() task["tags"] = sorted(tags_get(uuid, consts.TagType.TASK)) if detailed: task["subtasks"] = _subtasks_get_all_by_task_uuid(session, uuid) return task
def _deployment_get(self, deployment, session=None): stored_deployment = self.model_query( models.Deployment, session=session).filter_by(name=deployment).first() if not stored_deployment: stored_deployment = self.model_query( models.Deployment, session=session).filter_by(uuid=deployment).first() if not stored_deployment: raise exceptions.DBRecordNotFound(criteria="name or uuid is %s" % deployment, table="deployments") return stored_deployment
def deployment_delete(self, uuid): session = get_session() with session.begin(): count = (self.model_query( models.Resource, session=session).filter_by(deployment_uuid=uuid).count()) if count: raise exceptions.DBConflict( "There are allocated resources for the deployment %s" % uuid) count = (self.model_query( models.Deployment, session=session).filter_by( uuid=uuid).delete(synchronize_session=False)) if not count: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="deployments")
class CliUtilsTestCase(test.TestCase): def setUp(self): super(CliUtilsTestCase, self).setUp() self.categories = { "deployment": deployment.DeploymentCommands, "task": task.TaskCommands, "verify": verify.VerifyCommands } def tearDown(self): self._unregister_opts() super(CliUtilsTestCase, self).tearDown() def test_print_dict(self): out = six.StringIO() dict = {"key": "value"} cliutils.print_dict(dict, out=out) self.assertEqual( "+----------+-------+\n" "| Property | Value |\n" "+----------+-------+\n" "| key | value |\n" "+----------+-------+\n", out.getvalue()) def test_print_dict_wrap(self): out = six.StringIO() dict = {"key1": "not wrapped", "key2": "this will be wrapped"} cliutils.print_dict(dict, wrap=16, out=out) self.assertEqual( "+----------+--------------+\n" "| Property | Value |\n" "+----------+--------------+\n" "| key1 | not wrapped |\n" "| key2 | this will be |\n" "| | wrapped |\n" "+----------+--------------+\n", out.getvalue()) def test_print_dict_formatters_and_fields(self): out = six.StringIO() dict = {"key1": "value", "key2": "Value", "key3": "vvv"} formatters = {"foo": lambda x: x["key1"], "bar": lambda x: x["key2"]} fields = ["foo", "bar"] cliutils.print_dict(dict, formatters=formatters, fields=fields, out=out) self.assertEqual( "+----------+-------+\n" "| Property | Value |\n" "+----------+-------+\n" "| foo | value |\n" "| bar | Value |\n" "+----------+-------+\n", out.getvalue()) def test_print_dict_header(self): out = six.StringIO() dict = {"key": "value"} cliutils.print_dict(dict, table_label="Some Table", print_header=False, out=out) self.assertEqual( "+-------------+\n" "| Some Table |\n" "+-----+-------+\n" "| key | value |\n" "+-----+-------+\n", out.getvalue()) def test_print_dict_objects(self): class SomeStruct(object): def __init__(self, a, b): self.a = a self.b = b @property def c(self): return self.a + self.b def foo(self): pass @classmethod def bar(cls): pass @staticmethod def foobar(): pass out = six.StringIO() formatters = {"c": lambda x: "a + b = %s" % x.c} cliutils.print_dict(SomeStruct(1, 2), formatters=formatters, out=out) self.assertEqual( "+----------+-----------+\n" "| Property | Value |\n" "+----------+-----------+\n" "| a | 1 |\n" "| b | 2 |\n" "| c | a + b = 3 |\n" "+----------+-----------+\n", out.getvalue()) def test_print_dict_with_spec_chars(self): out = six.StringIO() dict = {"key": "line1\r\nline2"} cliutils.print_dict(dict, out=out) self.assertEqual( "+----------+-------+\n" "| Property | Value |\n" "+----------+-------+\n" "| key | line1 |\n" "| | line2 |\n" "+----------+-------+\n", out.getvalue()) def test_make_header(self): h1 = cliutils.make_header("msg", size=4, symbol="=") self.assertEqual("====\nmsg\n====\n", h1) def test_make_table_header(self): actual = cliutils.make_table_header("Response Times (sec)", 40) expected = "\n".join(( "+--------------------------------------+", "| Response Times (sec) |", )) self.assertEqual(expected, actual) actual = cliutils.make_table_header("Response Times (sec)", 39) expected = "\n".join(( "+-------------------------------------+", "| Response Times (sec) |", )) self.assertEqual(expected, actual) self.assertRaises(ValueError, cliutils.make_table_header, "Response Times (sec)", len("Response Times (sec)")) @ddt.data( { "obj": mock.Mock(foo=6.56565), "args": ["foo", 3], "expected": 6.566 }, { "obj": mock.Mock(foo=6.56565), "args": ["foo"], "expected": 6.56565 }, { "obj": mock.Mock(foo=None), "args": ["foo"], "expected": "n/a" }, { "obj": mock.Mock(foo="n/a"), "args": ["foo"], "expected": "n/a" }, { "obj": mock.Mock(foo="n/a"), "args": ["foo", 3], "expected": "n/a" }, { "obj": { "foo": 6.56565 }, "args": ["foo", 3], "expected": 6.566 }, { "obj": { "foo": 6.56565 }, "args": ["foo"], "expected": 6.56565 }, { "obj": { "foo": None }, "args": ["foo"], "expected": "n/a" }, { "obj": { "foo": "n/a" }, "args": ["foo"], "expected": "n/a" }, { "obj": { "foo": "n/a" }, "args": ["foo", 3], "expected": "n/a" }, { "obj": object, "args": ["unexpected_field", 3], "expected": AttributeError }, { "obj": { "foo": 42 }, "args": ["unexpected_field", 3], "expected": KeyError }) @ddt.unpack def test_pretty_float_formatter(self, obj, args, expected=None): formatter = cliutils.pretty_float_formatter(*args) if type(expected) == type and issubclass(expected, Exception): self.assertRaises(expected, formatter, obj) else: self.assertEqual(expected, formatter(obj)) def test__methods_of_with_class(self): class fake_class(object): def public(self): pass def _private(self): pass result = cliutils._methods_of(fake_class) self.assertEqual(1, len(result)) self.assertEqual("public", result[0][0]) def test__methods_of_with_object(self): class fake_class(object): def public(self): pass def _private(self): pass mock_obj = fake_class() result = cliutils._methods_of(mock_obj) self.assertEqual(1, len(result)) self.assertEqual("public", result[0][0]) def test__methods_of_empty_result(self): class fake_class(object): def _private(self): pass def _private2(self): pass mock_obj = fake_class() result = cliutils._methods_of(mock_obj) self.assertEqual([], result) def _unregister_opts(self): CONF.reset() category_opt = cfg.SubCommandOpt("category", title="Command categories", help="Available categories") CONF.unregister_opt(category_opt) @mock.patch("rally.api.API", side_effect=exceptions.RallyException("config_file")) def test_run_fails(self, mock_rally_api_api): ret = cliutils.run(["rally", "task list"], self.categories) self.assertEqual(2, ret) mock_rally_api_api.assert_called_once_with(config_args=["task list"], skip_db_check=True) @mock.patch("rally.api.API.check_db_revision") def test_run_version(self, mock_api_check_db_revision): ret = cliutils.run(["rally", "version"], self.categories) self.assertEqual(0, ret) @mock.patch("rally.api.API.check_db_revision") def test_run_bash_completion(self, mock_api_check_db_revision): ret = cliutils.run(["rally", "bash-completion"], self.categories) self.assertEqual(0, ret) @mock.patch("rally.api.API.check_db_revision") @mock.patch("rally.common.db.api.task_get", side_effect=exceptions.DBRecordNotFound(criteria="uuid: %s" % FAKE_TASK_UUID, table="tasks")) def test_run_task_not_found(self, mock_task_get, mock_api_check_db_revision): ret = cliutils.run(["rally", "task", "status", "%s" % FAKE_TASK_UUID], self.categories) self.assertTrue(mock_task_get.called) self.assertEqual(203, ret) @mock.patch("rally.api.API.check_db_revision") @mock.patch("rally.cli.cliutils.validate_args", side_effect=cliutils.MissingArgs("missing")) def test_run_task_failed(self, mock_validate_args, mock_api_check_db_revision): ret = cliutils.run(["rally", "task", "status", "%s" % FAKE_TASK_UUID], self.categories) self.assertTrue(mock_validate_args.called) self.assertEqual(1, ret) @mock.patch("rally.api.API.check_db_revision") def test_run_failed_to_open_file(self, mock_api_check_db_revision): class FailuresCommands(object): def failed_to_open_file(self): raise IOError("No such file") ret = cliutils.run(["rally", "failure", "failed-to-open-file"], {"failure": FailuresCommands}) self.assertEqual(1, ret) @mock.patch("rally.api.API.check_db_revision") def test_run_sqlalchmey_operational_failure(self, mock_api_check_db_revision): class SQLAlchemyCommands(object): def operational_failure(self): raise sqlalchemy.exc.OperationalError("Can't open DB file") ret = cliutils.run(["rally", "failure", "operational-failure"], {"failure": SQLAlchemyCommands}) self.assertEqual(1, ret) class TestObj(object): x = 1 y = 2 z = 3.142857142857143 aOrB = 3 # mixed case field @ddt.data( { "args": [[TestObj()], ["x", "y"]], "kwargs": { "print_header": True, "print_border": True, "sortby_index": None }, "expected": ("+---+---+\n" "| x | y |\n" "+---+---+\n" "| 1 | 2 |\n" "+---+---+") }, { "args": [[TestObj()], ["z"]], "kwargs": { "print_header": True, "print_border": True, "sortby_index": None, "formatters": { "z": cliutils.pretty_float_formatter("z", 5) } }, "expected": ("+---------+\n" "| z |\n" "+---------+\n" "| 3.14286 |\n" "+---------+") }, { "args": [[TestObj()], ["x"]], "kwargs": { "print_header": True, "print_border": True }, "expected": ("+---+\n" "| x |\n" "+---+\n" "| 1 |\n" "+---+") }, { "args": [[TestObj()], ["x", "y"]], "kwargs": { "print_header": True, "print_border": True }, "expected": ("+---+---+\n" "| x | y |\n" "+---+---+\n" "| 1 | 2 |\n" "+---+---+") }, { "args": [[TestObj()], ["x"]], "kwargs": { "print_header": False, "print_border": False }, "expected": "1" }, { "args": [[TestObj()], ["x", "y"]], "kwargs": { "print_header": False, "print_border": False }, "expected": "1 2" }, { "args": [[TestObj()], ["x"]], "kwargs": { "print_header": True, "print_border": False }, "expected": "x \n1" }, { "args": [[TestObj()], ["x", "y"]], "kwargs": { "print_header": True, "print_border": False }, "expected": "x y \n1 2" }, { "args": [[TestObj()], ["x"]], "kwargs": { "print_header": False, "print_border": True }, "expected": ("+--+\n" "|1 |\n" "+--+") }, { "args": [[TestObj()], ["x", "y"]], "kwargs": { "print_header": False, "print_border": True }, "expected": ("+--+--+\n" "|1 |2 |\n" "+--+--+") }, { "args": [[TestObj()], ["aOrB"]], "kwargs": { "print_header": True, "print_border": True, "mixed_case_fields": ["aOrB"] }, "expected": ("+------+\n" "| aOrB |\n" "+------+\n" "| 3 |\n" "+------+") }, { "args": [[TestObj()], ["aOrB"]], "kwargs": { "print_header": False, "print_border": True, "mixed_case_fields": ["aOrB"] }, "expected": ("+--+\n" "|3 |\n" "+--+") }, { "args": [[TestObj()], ["aOrB"]], "kwargs": { "print_header": True, "print_border": False, "mixed_case_fields": ["aOrB"] }, "expected": "aOrB \n3" }, { "args": [[TestObj()], ["aOrB"]], "kwargs": { "print_header": False, "print_border": False, "mixed_case_fields": ["aOrB"] }, "expected": "3" }, { "args": [[{ "x": 1, "y": 2 }], ["x", "y"]], "kwargs": { "print_header": True, "print_border": True, "sortby_index": None }, "expected": ("+---+---+\n" "| x | y |\n" "+---+---+\n" "| 1 | 2 |\n" "+---+---+") }, { "args": [[{ "z": 3.142857142857143 }], ["z"]], "kwargs": { "print_header": True, "print_border": True, "sortby_index": None, "formatters": { "z": cliutils.pretty_float_formatter("z", 5) } }, "expected": ("+---------+\n" "| z |\n" "+---------+\n" "| 3.14286 |\n" "+---------+") }, { "args": [[{ "x": 1 }], ["x"]], "kwargs": { "print_header": True, "print_border": True }, "expected": ("+---+\n" "| x |\n" "+---+\n" "| 1 |\n" "+---+") }, { "args": [[{ "x": 1, "y": 2 }], ["x", "y"]], "kwargs": { "print_header": True, "print_border": True }, "expected": ("+---+---+\n" "| x | y |\n" "+---+---+\n" "| 1 | 2 |\n" "+---+---+") }) @ddt.unpack def test_print_list(self, args, kwargs, expected): out = six.moves.StringIO() kwargs["out"] = out cliutils.print_list(*args, **kwargs) self.assertEqual(expected, out.getvalue().strip()) def test_print_list_raises(self): out = six.moves.StringIO() self.assertRaisesRegex(ValueError, "Field labels list.*has different number " "of elements than fields list", cliutils.print_list, [self.TestObj()], ["x"], field_labels=["x", "y"], sortby_index=None, out=out) def test_help_for_grouped_methods(self): class SomeCommand(object): @cliutils.help_group("1_manage") def install(self): pass @cliutils.help_group("1_manage") def uninstall(self): pass @cliutils.help_group("1_manage") def reinstall(self): pass @cliutils.help_group("2_launch") def run(self): pass @cliutils.help_group("2_launch") def rerun(self): pass @cliutils.help_group("3_results") def show(self): pass @cliutils.help_group("3_results") def list(self): pass def do_do_has_do_has_mesh(self): pass self.assertEqual( "\n\nCommands:\n" " do-do-has-do-has-mesh \n" "\n" " install \n" " reinstall \n" " uninstall \n" "\n" " rerun \n" " run \n" "\n" " list \n" " show \n", cliutils._compose_category_description(SomeCommand))
def test_deployment_not_found(self): deployment_id = "e87e4dca-b515-4477-888d-5f6103f13b42" exc = exceptions.DBRecordNotFound(criteria="uuid: %s" % deployment_id, table="deployments") self.fake_api.deployment.get.side_effect = exc self.assertEqual(1, self.deployment.use(self.fake_api, deployment_id))
def resource_delete(self, id): count = (self.model_query(models.Resource).filter_by(id=id).delete( synchronize_session=False)) if not count: raise exceptions.DBRecordNotFound(criteria="id: %s" % id, table="resources")
def platform_get(self, uuid): p = self.model_query(models.Platform).filter_by(uuid=uuid).first() if not p: raise exceptions.DBRecordNotFound(criteria="uuid = %s" % uuid, table="platforms") return p
def verification_delete(session, uuid): count = session.query(models.Verification).filter_by(uuid=uuid).delete() if not count: raise exceptions.DBRecordNotFound(criteria="uuid: %s" % uuid, table="verifications")