diff --git a/core/src/ten_runtime/extension_group/builtin/builtin_extension_group.c b/core/src/ten_runtime/extension_group/builtin/builtin_extension_group.c index 457e735c3..9229d0b59 100644 --- a/core/src/ten_runtime/extension_group/builtin/builtin_extension_group.c +++ b/core/src/ten_runtime/extension_group/builtin/builtin_extension_group.c @@ -99,7 +99,7 @@ static void on_addon_create_extension_done(ten_env_t *ten_env, } else { // Failed to create the specified extension. - TEN_LOGI( + TEN_LOGE( "Failed to create extension %s", ten_string_get_raw_str(&create_extension_done_ctx->extension_name)); diff --git a/core/src/ten_runtime/extension_thread/extension_thread.c b/core/src/ten_runtime/extension_thread/extension_thread.c index 954e0fffb..db65b4d8a 100644 --- a/core/src/ten_runtime/extension_thread/extension_thread.c +++ b/core/src/ten_runtime/extension_thread/extension_thread.c @@ -507,6 +507,9 @@ static void ten_engine_on_all_extension_threads_are_ready( ten_shared_ptr_t *cmd_result = NULL; if (error_occurred) { + TEN_LOGE("[%s] Failed to start the graph successfully, shutting it down.", + ten_engine_get_id(self, true)); + cmd_result = ten_cmd_result_create_from_cmd(TEN_STATUS_CODE_ERROR, state_requester_cmd); } else { diff --git a/tests/ten_runtime/smoke/start_graph/start_incorrect_graph.cc b/tests/ten_runtime/smoke/start_graph/start_incorrect_graph_1.cc similarity index 91% rename from tests/ten_runtime/smoke/start_graph/start_incorrect_graph.cc rename to tests/ten_runtime/smoke/start_graph/start_incorrect_graph_1.cc index 68961edcf..4e355dcde 100644 --- a/tests/ten_runtime/smoke/start_graph/start_incorrect_graph.cc +++ b/tests/ten_runtime/smoke/start_graph/start_incorrect_graph_1.cc @@ -30,7 +30,7 @@ class test_predefined_graph : public ten::extension_t { "name": "normal_extension", "addon": "not_existed_extension_addon", "app": "msgpack://127.0.0.1:8001/", - "extension_group": "start_incorrect_graph__normal_extension_group" + "extension_group": "start_incorrect_graph_1__normal_extension_group" }] })"_json.dump() .c_str()); @@ -111,8 +111,8 @@ class test_app : public ten::app_t { "nodes": [{ "type": "extension", "name": "predefined_graph", - "addon": "start_incorrect_graph__predefined_graph_extension", - "extension_group": "start_incorrect_graph__predefined_graph_group" + "addon": "start_incorrect_graph_1__predefined_graph_extension", + "extension_group": "start_incorrect_graph_1__predefined_graph_group" }] }] } @@ -134,13 +134,13 @@ void *app_thread_main(TEN_UNUSED void *args) { } TEN_CPP_REGISTER_ADDON_AS_EXTENSION( - start_incorrect_graph__predefined_graph_extension, test_predefined_graph); -TEN_CPP_REGISTER_ADDON_AS_EXTENSION(start_incorrect_graph__normal_extension, + start_incorrect_graph_1__predefined_graph_extension, test_predefined_graph); +TEN_CPP_REGISTER_ADDON_AS_EXTENSION(start_incorrect_graph_1__normal_extension, test_normal_extension); } // namespace -TEST(ExtensionTest, StartIncorrectGraph) { // NOLINT +TEST(ExtensionTest, StartIncorrectGraph1) { // NOLINT auto *app_thread = ten_thread_create("app thread", app_thread_main, nullptr); // Create a client and connect to the app. @@ -151,7 +151,7 @@ TEST(ExtensionTest, StartIncorrectGraph) { // NOLINT // request to predefined graph. auto test_cmd = ten::cmd_t::create("test"); test_cmd->set_dest("msgpack://127.0.0.1:8001/", "default", - "start_incorrect_graph__predefined_graph_group", + "start_incorrect_graph_1__predefined_graph_group", "predefined_graph"); auto cmd_result = client->send_cmd_and_recv_result(std::move(test_cmd)); ten_test::check_status_code(cmd_result, TEN_STATUS_CODE_OK); diff --git a/tests/ten_runtime/smoke/start_graph/start_incorrect_graph_2.cc b/tests/ten_runtime/smoke/start_graph/start_incorrect_graph_2.cc new file mode 100644 index 000000000..0461d8216 --- /dev/null +++ b/tests/ten_runtime/smoke/start_graph/start_incorrect_graph_2.cc @@ -0,0 +1,169 @@ +// +// Copyright © 2025 Agora +// This file is part of TEN Framework, an open source project. +// Licensed under the Apache License, Version 2.0, with certain conditions. +// Refer to the "LICENSE" file in the root directory for more information. +// +#include "gtest/gtest.h" +#include "include_internal/ten_runtime/binding/cpp/ten.h" +#include "ten_runtime/common/status_code.h" +#include "tests/common/client/cpp/msgpack_tcp.h" +#include "tests/ten_runtime/smoke/util/binding/cpp/check.h" + +namespace { + +class test_normal_extension : public ten::extension_t { + public: + explicit test_normal_extension(const char *name) : ten::extension_t(name) {} +}; + +class test_predefined_graph : public ten::extension_t { + public: + explicit test_predefined_graph(const char *name) : ten::extension_t(name) {} + + void on_start(ten::ten_env_t &ten_env) override { + auto start_graph_cmd = ten::cmd_start_graph_t::create(); + start_graph_cmd->set_dest("localhost", nullptr, nullptr, nullptr); + start_graph_cmd->set_graph_from_json(R"({ + "nodes": [{ + "type": "extension", + "name": "non_existed_extension", + "addon": "not_existed_extension_addon", + "app": "msgpack://127.0.0.1:8001/", + "extension_group": "start_incorrect_graph_2__normal_extension_group" + },{ + "type": "extension", + "name": "normal_extension", + "addon": "start_incorrect_graph_2__normal_extension", + "app": "msgpack://127.0.0.1:8001/", + "extension_group": "start_incorrect_graph_2__normal_extension_group" + }] + })"_json.dump() + .c_str()); + + ten_env.send_cmd( + std::move(start_graph_cmd), + [this](ten::ten_env_t &ten_env, std::unique_ptr cmd, + ten::error_t *err) { + // result for the 'start_graph' command + auto status_code = cmd->get_status_code(); + EXPECT_EQ(status_code, TEN_STATUS_CODE_ERROR); + + auto graph_id = cmd->get_property_string("detail"); + EXPECT_EQ(graph_id, ""); + + start_graph_cmd_is_done = true; + + if (test_cmd != nullptr) { + nlohmann::json detail = {{"id", 1}, {"name", "a"}}; + + auto cmd_result = ten::cmd_result_t::create(TEN_STATUS_CODE_OK); + cmd_result->set_property_from_json("detail", detail.dump().c_str()); + ten_env.return_result(std::move(cmd_result), std::move(test_cmd)); + } + }); + + ten_env.on_start_done(); + } + + void on_cmd(ten::ten_env_t &ten_env, + std::unique_ptr cmd) override { + if (cmd->get_name() == "test") { + if (start_graph_cmd_is_done) { + nlohmann::json detail = {{"id", 1}, {"name", "a"}}; + + auto cmd_result = ten::cmd_result_t::create(TEN_STATUS_CODE_OK); + cmd_result->set_property_from_json("detail", detail.dump().c_str()); + ten_env.return_result(std::move(cmd_result), std::move(cmd)); + } else { + test_cmd = std::move(cmd); + return; + } + } else { + TEN_ASSERT(0, "Should not happen."); + } + } + + private: + bool start_graph_cmd_is_done{}; + std::unique_ptr test_cmd; +}; + +class test_app : public ten::app_t { + public: + void on_configure(ten::ten_env_t &ten_env) override { + bool rc = ten::ten_env_internal_accessor_t::init_manifest_from_json( + ten_env, + // clang-format off + R"({ + "type": "app", + "name": "test_app", + "version": "0.1.0" + })" + // clang-format on + ); + ASSERT_EQ(rc, true); + + rc = ten_env.init_property_from_json( + // clang-format off + R"({ + "_ten": { + "uri": "msgpack://127.0.0.1:8001/", + "log_level": 2, + "predefined_graphs": [{ + "name": "default", + "auto_start": false, + "singleton": true, + "nodes": [{ + "type": "extension", + "name": "predefined_graph", + "addon": "start_incorrect_graph_2__predefined_graph_extension", + "extension_group": "start_incorrect_graph_2__predefined_graph_group" + }] + }] + } + })" + // clang-format on + ); + ASSERT_EQ(rc, true); + + ten_env.on_configure_done(); + } +}; + +void *app_thread_main(TEN_UNUSED void *args) { + auto *app = new test_app(); + app->run(); + delete app; + + return nullptr; +} + +TEN_CPP_REGISTER_ADDON_AS_EXTENSION( + start_incorrect_graph_2__predefined_graph_extension, test_predefined_graph); +TEN_CPP_REGISTER_ADDON_AS_EXTENSION(start_incorrect_graph_2__normal_extension, + test_normal_extension); + +} // namespace + +TEST(ExtensionTest, StartIncorrectGraph2) { // NOLINT + auto *app_thread = ten_thread_create("app thread", app_thread_main, nullptr); + + // Create a client and connect to the app. + auto *client = new ten::msgpack_tcp_client_t("msgpack://127.0.0.1:8001/"); + + // Do not need to send 'start_graph' command first. + // The 'graph_id' MUST be "default" (a special string) if we want to send the + // request to predefined graph. + auto test_cmd = ten::cmd_t::create("test"); + test_cmd->set_dest("msgpack://127.0.0.1:8001/", "default", + "start_incorrect_graph_2__predefined_graph_group", + "predefined_graph"); + auto cmd_result = client->send_cmd_and_recv_result(std::move(test_cmd)); + ten_test::check_status_code(cmd_result, TEN_STATUS_CODE_OK); + ten_test::check_detail_with_json(cmd_result, R"({"id": 1, "name": "a"})"); + + delete client; + + ten_thread_join(app_thread, -1); +}