diff --git a/compaction/compaction_manager.cc b/compaction/compaction_manager.cc index 65fb7ffa2c..b39628a12c 100644 --- a/compaction/compaction_manager.cc +++ b/compaction/compaction_manager.cc @@ -22,6 +22,7 @@ #include "sstables/exceptions.hh" #include "sstables/sstable_directory.hh" #include "locator/abstract_replication_strategy.hh" +#include "utils/error_injection.hh" #include "utils/fb_utilities.hh" #include "utils/UUID_gen.hh" #include "db/system_keyspace.hh" @@ -1188,6 +1189,9 @@ protected: } virtual future do_run() override { + co_await utils::get_local_injector().inject_with_handler("compaction_regular_compaction_task_executor_do_run", + [] (auto& handler) { return handler.wait_for_message(db::timeout_clock::now() + 10s); }); + co_await coroutine::switch_to(_cm.compaction_sg()); for (;;) { diff --git a/test/rest_api/test_compaction_task.py b/test/rest_api/test_compaction_task.py index cda9ecbd71..445bab311f 100644 --- a/test/rest_api/test_compaction_task.py +++ b/test/rest_api/test_compaction_task.py @@ -3,8 +3,8 @@ import sys # Use the util.py library from ../cql-pytest: sys.path.insert(1, sys.path[0] + '/../cql-pytest') from util import new_test_table, new_test_keyspace -from rest_util import set_tmp_task_ttl -from task_manager_utils import wait_for_task, list_tasks, check_child_parent_relationship, drain_module_tasks +from rest_util import set_tmp_task_ttl, scylla_inject_error +from task_manager_utils import wait_for_task, list_tasks, check_child_parent_relationship, drain_module_tasks, abort_task module_name = "compaction" long_time = 1000000000 @@ -88,3 +88,34 @@ def test_regular_compaction_task(cql, this_dc, rest_api): failed = [status["task_id"] for status in statuses if status["state"] != "done"] assert not failed, f"Regular compaction tasks with ids = {failed} failed" drain_module_tasks(rest_api, module_name) + +def test_running_compaction_task_abort(cql, this_dc, rest_api): + drain_module_tasks(rest_api, module_name) + with set_tmp_task_ttl(rest_api, long_time): + with new_test_keyspace(cql, f"WITH REPLICATION = {{ 'class' : 'NetworkTopologyStrategy', '{this_dc}' : 1 }}") as keyspace: + schema = 'p int, v text, primary key (p)' + with new_test_table(cql, keyspace, schema) as t0: + stmt = cql.prepare(f"INSERT INTO {t0} (p, v) VALUES (?, ?)") + cql.execute(stmt, [0, 'hello']) + cql.execute(stmt, [1, 'world']) + + injection = "compaction_regular_compaction_task_executor_do_run" + with scylla_inject_error(rest_api, injection, True): + [_, table] = t0.split(".") + resp = rest_api.send("POST", f"column_family/autocompaction/{keyspace}:{table}") + resp.raise_for_status() + + tasks = list_tasks(rest_api, module_name, False, keyspace, table) + assert tasks, "Compaction task was not created" + + for task in tasks: + abort_task(rest_api, task["task_id"]) + + resp = rest_api.send("POST", f"v2/error_injection/injection/{injection}/message") + resp.raise_for_status() + + for task in tasks: + status = wait_for_task(rest_api, task["task_id"]) + assert status["state"] == "failed", "Task finished successfully" + assert "abort requested" in status["error"], "Task wasn't aborted by user" + drain_module_tasks(rest_api, module_name)