diff --git a/src/meta/server_state.cpp b/src/meta/server_state.cpp index 0ce40e9658..28a1d4b96c 100644 --- a/src/meta/server_state.cpp +++ b/src/meta/server_state.cpp @@ -3069,6 +3069,13 @@ void server_state::set_app_envs(const app_env_rpc &env_rpc) zauto_write_lock l(_lock); std::shared_ptr app = get_app(app_name); + FAIL_POINT_INJECT_NOT_RETURN_F("set_app_envs_failed", [&app](std::string_view s) { + if (s == "dropped_after_update_remote_storage") { + app.reset(); + return; + } + }); + // The table might be removed just before the callback function is invoked, thus we must // check if this table still exists. // @@ -3078,9 +3085,7 @@ void server_state::set_app_envs(const app_env_rpc &env_rpc) // dropped state. Once it is applied by remote storage after another update dropping // the table, the state of the table would always be non-dropped on remote storage. if (!app) { - LOG_ERROR("set app envs failed since app(name={}, id={}) has just been dropped", - app_name, - app->app_id); + LOG_ERROR("set app envs failed since app({}) has just been dropped", app_name); env_rpc.response().err = ERR_APP_DROPPED; env_rpc.response().hint_message = "app has just been dropped"; return; diff --git a/src/meta/test/server_state_test.cpp b/src/meta/test/server_state_test.cpp index 55295ceb3a..b7ea6262fd 100644 --- a/src/meta/test/server_state_test.cpp +++ b/src/meta/test/server_state_test.cpp @@ -212,24 +212,36 @@ class server_state_test void meta_service_test_app::app_envs_basic_test() { server_state_test test; - test.load_apps({"test_app1", "test_set_app_envs_not_found"}); - - std::cout << "test server_state::set_app_envs(not_found)..." << std::endl; - { - configuration_update_app_env_request request; - request.__set_app_name("test_set_app_envs_not_found"); - request.__set_op(app_env_operation::type::APP_ENV_OP_SET); - request.__set_keys({replica_envs::ROCKSDB_WRITE_BUFFER_SIZE}); - request.__set_values({"67108864"}); - - fail::setup(); - fail::cfg("set_app_envs_failed", "void(not_found)"); - - auto rpc = test.set_app_envs(request); - ASSERT_EQ(ERR_APP_NOT_EXIST, rpc.response().err); - - fail::teardown(); - } + test.load_apps({"test_app1", + "test_set_app_envs_not_found", + "test_set_app_envs_dropping", + "test_set_app_envs_dropped_after_update_remote_storage"}); + +#define TEST_SET_APP_ENVS_FAILED(action, err_code) \ + std::cout << "test server_state::set_app_envs(" #action ")..." << std::endl; \ + do { \ + configuration_update_app_env_request request; \ + request.__set_app_name("test_set_app_envs_" #action); \ + request.__set_op(app_env_operation::type::APP_ENV_OP_SET); \ + request.__set_keys({replica_envs::ROCKSDB_WRITE_BUFFER_SIZE}); \ + request.__set_values({"67108864"}); \ + \ + fail::setup(); \ + fail::cfg("set_app_envs_failed", "void(" #action ")"); \ + \ + auto rpc = test.set_app_envs(request); \ + ASSERT_EQ(err_code, rpc.response().err); \ + \ + fail::teardown(); \ + } while (0) + + TEST_SET_APP_ENVS_FAILED(not_found, ERR_APP_NOT_EXIST); + + TEST_SET_APP_ENVS_FAILED(dropping, ERR_BUSY_DROPPING); + + TEST_SET_APP_ENVS_FAILED(dropped_after_update_remote_storage, ERR_APP_DROPPED); + +#undef TEST_SET_APP_ENVS_FAILED std::cout << "test server_state::set_app_envs()..." << std::endl; {