From 9f840e0414b2e1ad70d147391ff48aca7ba3d011 Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 3 May 2025 12:25:28 +0800 Subject: [PATCH 1/3] refactor: enhance command output handling to differentiate between normal and log outputs --- .../ten_manager/src/designer/exec/cmd_run.rs | 67 +++++++++++++++-- core/src/ten_manager/src/designer/exec/mod.rs | 74 +++++++++++++++---- core/src/ten_manager/src/designer/exec/msg.rs | 30 ++++++-- .../ten_manager/src/fs/log_file_watcher.rs | 24 +----- core/src/ten_manager/src/log/mod.rs | 20 +++++ 5 files changed, 165 insertions(+), 50 deletions(-) diff --git a/core/src/ten_manager/src/designer/exec/cmd_run.rs b/core/src/ten_manager/src/designer/exec/cmd_run.rs index 4f81011ec6..31f77f0503 100644 --- a/core/src/ten_manager/src/designer/exec/cmd_run.rs +++ b/core/src/ten_manager/src/designer/exec/cmd_run.rs @@ -11,6 +11,7 @@ use actix_web_actors::ws::WebsocketContext; use crossbeam_channel::{bounded, Sender}; use crate::designer::exec::RunCmdOutput; +use crate::log::{process_log_line, GraphResourcesLog, LogLineInfo}; use super::{msg::OutboundMsg, WsRunCmd}; @@ -43,7 +44,15 @@ impl WsRunCmd { command .arg("-c") .arg(cmd) - .env("TEN_LOG_FORMATTER", "default") + // Set TEN_LOG_FORMATTER to default if any output is log content. + .env( + "TEN_LOG_FORMATTER", + if self.stdout_is_log || self.stderr_is_log { + "default" + } else { + "" + }, + ) // Capture stdout/stderr. .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()); @@ -82,11 +91,20 @@ impl WsRunCmd { if let Some(mut out) = stdout_child { let addr_stdout = addr.clone(); let shutdown_rx = stdout_shutdown_rx; + let is_log = self.stdout_is_log; thread::spawn(move || { use std::io::{BufRead, BufReader}; let reader = BufReader::new(&mut out); + // Create a graph resources log instance for log processing. + let mut graph_resources_log = GraphResourcesLog { + graph_id: String::new(), + graph_name: String::new(), + app_uri: None, + extension_threads: std::collections::HashMap::new(), + }; + for line_res in reader.lines() { // Check if we should terminate. if shutdown_rx.try_recv().is_ok() { @@ -95,11 +113,22 @@ impl WsRunCmd { match line_res { Ok(line) => { - // `do_send` is used to asynchronously send messages - // to an actor. This method does not wait for the - // message to be processed, making it suitable for - // messages that do not require a response. - addr_stdout.do_send(RunCmdOutput::StdOut(line)); + if is_log { + // Process line as log content. + let metadata = process_log_line( + &line, + &mut graph_resources_log, + ); + let log_line_info = + LogLineInfo { line, metadata }; + addr_stdout.do_send(RunCmdOutput::StdOutLog( + log_line_info, + )); + } else { + // Process as normal stdout. + addr_stdout + .do_send(RunCmdOutput::StdOutNormal(line)); + } } Err(_) => break, } @@ -112,11 +141,20 @@ impl WsRunCmd { if let Some(mut err) = stderr_child { let addr_stderr = addr.clone(); let shutdown_rx = stderr_shutdown_rx; + let is_log = self.stderr_is_log; thread::spawn(move || { use std::io::{BufRead, BufReader}; let reader = BufReader::new(&mut err); + // Create a graph resources log instance for log processing. + let mut graph_resources_log = GraphResourcesLog { + graph_id: String::new(), + graph_name: String::new(), + app_uri: None, + extension_threads: std::collections::HashMap::new(), + }; + for line_res in reader.lines() { // Check if we should terminate. if shutdown_rx.try_recv().is_ok() { @@ -125,7 +163,22 @@ impl WsRunCmd { match line_res { Ok(line) => { - addr_stderr.do_send(RunCmdOutput::StdErr(line)); + if is_log { + // Process line as log content. + let metadata = process_log_line( + &line, + &mut graph_resources_log, + ); + let log_line_info = + LogLineInfo { line, metadata }; + addr_stderr.do_send(RunCmdOutput::StdErrLog( + log_line_info, + )); + } else { + // Process as normal stderr. + addr_stderr + .do_send(RunCmdOutput::StdErrNormal(line)); + } } Err(_) => break, } diff --git a/core/src/ten_manager/src/designer/exec/mod.rs b/core/src/ten_manager/src/designer/exec/mod.rs index 0035637c0c..8c50ff437a 100644 --- a/core/src/ten_manager/src/designer/exec/mod.rs +++ b/core/src/ten_manager/src/designer/exec/mod.rs @@ -18,6 +18,7 @@ use anyhow::Context; use anyhow::Result; use crate::designer::DesignerState; +use crate::log::LogLineInfo; use cmd_run::ShutdownSenders; use msg::InboundMsg; use msg::OutboundMsg; @@ -27,20 +28,25 @@ use run_script::extract_command_from_manifest; #[derive(Message)] #[rtype(result = "()")] pub enum RunCmdOutput { - StdOut(String), - StdErr(String), + StdOutNormal(String), + StdOutLog(LogLineInfo), + + StdErrNormal(String), + StdErrLog(LogLineInfo), + Exit(i32), } -/// `CmdParser` returns a tuple: the 1st element is the command string, and -/// the 2nd is an optional working directory. +/// `CmdParser` returns a tuple: the 1st element is the command string, the 2nd +/// is an optional working directory, and the 3rd and 4th are booleans +/// indicating if stdout and stderr are log content. pub type CmdParser = Box< dyn Fn( &str, ) -> std::pin::Pin< Box< dyn std::future::Future< - Output = Result<(String, Option)>, + Output = Result<(String, Option, bool, bool)>, > + Send, >, > + Send @@ -52,6 +58,8 @@ pub struct WsRunCmd { cmd_parser: CmdParser, working_directory: Option, shutdown_senders: Option, + stdout_is_log: bool, + stderr_is_log: bool, } impl WsRunCmd { @@ -61,6 +69,8 @@ impl WsRunCmd { cmd_parser, working_directory: None, shutdown_senders: None, + stdout_is_log: false, + stderr_is_log: false, } } } @@ -93,16 +103,30 @@ impl Handler for WsRunCmd { ctx: &mut Self::Context, ) -> Self::Result { match msg { - RunCmdOutput::StdOut(line) => { + RunCmdOutput::StdOutNormal(line) => { // Send the line to the client. - let msg_out = OutboundMsg::StdOut { data: line }; + let msg_out = OutboundMsg::StdOutNormal { data: line }; + let out_str = serde_json::to_string(&msg_out).unwrap(); + + // Sends a text message to the WebSocket client. + ctx.text(out_str); + } + RunCmdOutput::StdOutLog(log_line) => { + let msg_out = OutboundMsg::StdOutLog { data: log_line }; let out_str = serde_json::to_string(&msg_out).unwrap(); // Sends a text message to the WebSocket client. ctx.text(out_str); } - RunCmdOutput::StdErr(line) => { - let msg_out = OutboundMsg::StdErr { data: line }; + RunCmdOutput::StdErrNormal(line) => { + let msg_out = OutboundMsg::StdErrNormal { data: line }; + let out_str = serde_json::to_string(&msg_out).unwrap(); + + // Sends a text message to the WebSocket client. + ctx.text(out_str); + } + RunCmdOutput::StdErrLog(log_line) => { + let msg_out = OutboundMsg::StdErrLog { data: log_line }; let out_str = serde_json::to_string(&msg_out).unwrap(); // Sends a text message to the WebSocket client. @@ -140,10 +164,17 @@ impl StreamHandler> for WsRunCmd { actix::spawn(async move { match fut.await { - Ok((cmd, working_directory)) => { + Ok(( + cmd, + working_directory, + stdout_is_log, + stderr_is_log, + )) => { actor_addr.do_send(ProcessCommand { cmd, working_directory, + stdout_is_log, + stderr_is_log, }); } Err(e) => { @@ -173,6 +204,8 @@ impl StreamHandler> for WsRunCmd { struct ProcessCommand { cmd: String, working_directory: Option, + stdout_is_log: bool, + stderr_is_log: bool, } #[derive(Message)] @@ -219,6 +252,9 @@ impl Handler for WsRunCmd { self.working_directory = Some(dir); } + self.stdout_is_log = msg.stdout_is_log; + self.stderr_is_log = msg.stderr_is_log; + self.cmd_run(&msg.cmd, ctx); } } @@ -245,17 +281,25 @@ pub async fn exec_endpoint( })?; match inbound { - InboundMsg::ExecCmd { base_dir, cmd } => { - Ok((cmd, Some(base_dir))) - } - InboundMsg::RunScript { base_dir, name } => { + InboundMsg::ExecCmd { + base_dir, + cmd, + stdout_is_log, + stderr_is_log, + } => Ok((cmd, Some(base_dir), stdout_is_log, stderr_is_log)), + InboundMsg::RunScript { + base_dir, + name, + stdout_is_log, + stderr_is_log, + } => { let cmd = extract_command_from_manifest( &base_dir, &name, state_clone_inner, ) .await?; - Ok((cmd, Some(base_dir))) + Ok((cmd, Some(base_dir), stdout_is_log, stderr_is_log)) } } }) diff --git a/core/src/ten_manager/src/designer/exec/msg.rs b/core/src/ten_manager/src/designer/exec/msg.rs index dc612c8fba..d88c8824ed 100644 --- a/core/src/ten_manager/src/designer/exec/msg.rs +++ b/core/src/ten_manager/src/designer/exec/msg.rs @@ -6,24 +6,42 @@ // use serde::{Deserialize, Serialize}; +use crate::log::LogLineInfo; + #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] pub enum InboundMsg { #[serde(rename = "exec_cmd")] - ExecCmd { base_dir: String, cmd: String }, + ExecCmd { + base_dir: String, + cmd: String, + stdout_is_log: bool, + stderr_is_log: bool, + }, #[serde(rename = "run_script")] - RunScript { base_dir: String, name: String }, + RunScript { + base_dir: String, + name: String, + stdout_is_log: bool, + stderr_is_log: bool, + }, } #[derive(Serialize, Deserialize, Debug)] #[serde(tag = "type")] pub enum OutboundMsg { - #[serde(rename = "stdout")] - StdOut { data: String }, + #[serde(rename = "stdout_normal")] + StdOutNormal { data: String }, + + #[serde(rename = "stdout_log")] + StdOutLog { data: LogLineInfo }, + + #[serde(rename = "stderr_normal")] + StdErrNormal { data: String }, - #[serde(rename = "stderr")] - StdErr { data: String }, + #[serde(rename = "stderr_log")] + StdErrLog { data: LogLineInfo }, #[serde(rename = "exit")] Exit { code: i32 }, diff --git a/core/src/ten_manager/src/fs/log_file_watcher.rs b/core/src/ten_manager/src/fs/log_file_watcher.rs index c4de5f62f1..1e862f3919 100644 --- a/core/src/ten_manager/src/fs/log_file_watcher.rs +++ b/core/src/ten_manager/src/fs/log_file_watcher.rs @@ -19,8 +19,8 @@ use anyhow::{anyhow, Result}; use tokio::sync::mpsc::{self, Receiver, Sender}; use tokio::sync::oneshot; -use crate::log::{extract_extension_from_log_line, parse_graph_resources_log}; -use crate::log::{GraphResourcesLog, LogLineInfo, LogLineMetadata}; +use crate::log::process_log_line; +use crate::log::{GraphResourcesLog, LogLineInfo}; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60); // 1 minute timeout. const DEFAULT_BUFFER_SIZE: usize = 4096; // Default read buffer size. @@ -284,23 +284,3 @@ async fn watch_log_file_task( } } } - -/// Process a log line: try to parse as graph resources log first, then try to -/// extract extension information. -fn process_log_line( - log_line: &str, - graph_resources_log: &mut GraphResourcesLog, -) -> Option { - // First try to parse as graph resources log. - match parse_graph_resources_log(log_line, graph_resources_log) { - Ok(_) => { - // Successfully parsed as graph resources log, but no metadata to - // return. - None - } - Err(_) => { - // Not a graph resources log, try to extract extension information. - extract_extension_from_log_line(log_line, graph_resources_log) - } - } -} diff --git a/core/src/ten_manager/src/log/mod.rs b/core/src/ten_manager/src/log/mod.rs index ba732add15..72063fdf3c 100644 --- a/core/src/ten_manager/src/log/mod.rs +++ b/core/src/ten_manager/src/log/mod.rs @@ -186,3 +186,23 @@ pub fn parse_graph_resources_log( Ok(()) } + +/// Process a log line: try to parse as graph resources log first, then try to +/// extract extension information. +pub fn process_log_line( + log_line: &str, + graph_resources_log: &mut GraphResourcesLog, +) -> Option { + // First try to parse as graph resources log. + match parse_graph_resources_log(log_line, graph_resources_log) { + Ok(_) => { + // Successfully parsed as graph resources log, but no metadata to + // return. + None + } + Err(_) => { + // Not a graph resources log, try to extract extension information. + extract_extension_from_log_line(log_line, graph_resources_log) + } + } +} From 8fe06e7f2094baf5bfac1c0a5be99bb6252718a3 Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 3 May 2025 13:50:09 +0800 Subject: [PATCH 2/3] fix: refine codes --- .../src/ten_manager/tests/test_case/fs/mod.rs | 12 ++ tests/ten_runtime/integration/cpp/BUILD.gn | 1 + .../cpp/manifest_with_comments/BUILD.gn | 86 ++++++++++ .../cpp/manifest_with_comments/__init__.py | 0 .../manifest_with_comments/client/client.cc | 43 +++++ .../manifest_with_comments_app/manifest.json | 29 ++++ .../manifest_with_comments_app/property.json | 20 +++ .../extension/default_extension_cpp/BUILD.gn | 20 +++ .../default_extension_cpp/manifest.json | 31 ++++ .../default_extension_cpp/property.json | 3 + .../default_extension_cpp/src/main.cc | 39 +++++ .../cpp/manifest_with_comments/test_case.py | 159 ++++++++++++++++++ 12 files changed, 443 insertions(+) create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/__init__.py create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc create mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py diff --git a/core/src/ten_manager/tests/test_case/fs/mod.rs b/core/src/ten_manager/tests/test_case/fs/mod.rs index 0d28577865..05d53bc738 100644 --- a/core/src/ten_manager/tests/test_case/fs/mod.rs +++ b/core/src/ten_manager/tests/test_case/fs/mod.rs @@ -42,6 +42,7 @@ mod tests { // Get the first chunk. let chunk = stream.next().await.expect("Should receive data")?; + println!("chunk: {:?}", chunk); assert_eq!(chunk.line, test_content); // Write more content to the file. @@ -51,6 +52,7 @@ mod tests { // Get the second chunk. let chunk = stream.next().await; + println!("chunk: {:?}", chunk); match chunk { Some(chunk) => match chunk { Ok(chunk) => assert_eq!(chunk.line, more_content), @@ -100,6 +102,7 @@ mod tests { // Get the first chunk let chunk = stream.next().await.expect("Should receive data")?; + println!("chunk: {:?}", chunk); assert_eq!(chunk.line, "Initial content"); // Simulate log rotation - delete and recreate file @@ -121,6 +124,7 @@ mod tests { // Get the content after rotation let chunk = stream.next().await.expect("Should receive rotated data")?; + println!("chunk: {:?}", chunk); assert_eq!(chunk.line, "Rotated content"); // Stop watching @@ -152,10 +156,12 @@ mod tests { // Get the first chunk. let chunk = stream.next().await.expect("Should receive data")?; + println!("chunk: {:?}", chunk); assert_eq!(chunk.line, "Test content"); // Wait for the timeout to occur (no new content being written). let next_result = stream.next().await; + println!("next_result: {:?}", next_result); assert!(next_result.is_none(), "Stream should end after timeout"); Ok(()) @@ -198,6 +204,7 @@ mod tests { // Get the graph resources line let chunk = stream.next().await.expect("Should receive graph resources")?; + println!("chunk: {:?}", chunk); assert!(chunk.line.contains("[graph resources]")); // Now write logs that contain extension metadata in format @@ -218,11 +225,13 @@ mod tests { .next() .await .expect("Should receive log with extension")?; + println!("chunk: {:?}", chunk); assert!(chunk.line.contains("on_start()")); // The metadata should include the extension name assert!(chunk.metadata.is_some(), "Should have metadata"); let metadata = chunk.metadata.unwrap(); + println!("metadata: {:?}", metadata); assert_eq!(metadata.extension, Some("test_extension".to_string())); // Get second log with extension metadata @@ -230,11 +239,13 @@ mod tests { .next() .await .expect("Should receive log with extension")?; + println!("chunk: {:?}", chunk); assert!(chunk.line.contains("on_start() done")); // The metadata should include the extension name assert!(chunk.metadata.is_some(), "Should have metadata"); let metadata = chunk.metadata.unwrap(); + println!("metadata: {:?}", metadata); assert_eq!(metadata.extension, Some("test_extension".to_string())); // Stop watching @@ -394,6 +405,7 @@ mod tests { // Verify that the metadata includes the extension name assert!(chunk.metadata.is_some(), "Should have metadata"); let metadata = chunk.metadata.unwrap(); + println!("metadata: {:?}", metadata); assert_eq!( metadata.extension, Some("test_extension".to_string()) diff --git a/tests/ten_runtime/integration/cpp/BUILD.gn b/tests/ten_runtime/integration/cpp/BUILD.gn index b78c38f44a..8e5e113117 100644 --- a/tests/ten_runtime/integration/cpp/BUILD.gn +++ b/tests/ten_runtime/integration/cpp/BUILD.gn @@ -15,6 +15,7 @@ group("cpp") { "hello_world", "large_result", "long_running", + "manifest_with_comments", "restful", ] diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn b/tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn new file mode 100644 index 0000000000..5d10358d09 --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn @@ -0,0 +1,86 @@ +# +# 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. +# +import("//build/ten_runtime/feature/test.gni") +import("//build/ten_runtime/ten.gni") + +ten_package_test_prepare_app("manifest_with_comments_app") { + src_app = "default_app_cpp" + src_app_language = "cpp" + generated_app_src_root_dir_name = "manifest_with_comments_app" + + replace_paths_after_install_app = [ + "manifest_with_comments_app/manifest.json", + "manifest_with_comments_app/property.json", + ] + + replace_paths_after_install_all = [ + "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json", + "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json", + "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc", + "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn", + ] + + if (ten_enable_ten_manager) { + deps = [ + "//core/src/ten_manager", + "//core/src/ten_runtime:upload_ten_runtime_system_package_to_server", + "//packages/core_apps/default_app_cpp:upload_default_app_cpp_to_server", + "//packages/core_extensions/default_extension_cpp:upload_default_extension_cpp_to_server", + "//packages/core_protocols/msgpack:upload_protocol_msgpack_to_server", + ] + } +} + +ten_package_test_prepare_client("manifest_with_comments_app_client") { + sources = [ "client/client.cc" ] + include_dirs = [ + "//core/src", + "//core", + "//packages", + "//tests", + ] + deps = [ + "//core/src/ten_runtime", + "//packages/core_protocols/msgpack:msgpack_files", + "//tests/common/client:msgpack_client", + "//third_party/msgpack:msgpackc", + "//third_party/nlohmann_json", + ] +} + +ten_package_test_prepare_auxiliary_resources( + "manifest_with_comments_app_test_files") { + resources = [ + "__init__.py", + "test_case.py", + ] + + utils_files = exec_script("//.gnfiles/build/scripts/glob_file.py", + [ + "--dir", + rebase_path("//tests/utils/**/*"), + "--dir-base", + rebase_path("//tests/utils"), + "--recursive", + "--only-output-file", + ], + "json") + + foreach(utils_file, utils_files) { + utils_file_rel_path = utils_file.relative_path + resources += + [ "//tests/utils/${utils_file_rel_path}=>utils/${utils_file_rel_path}" ] + } +} + +group("manifest_with_comments") { + deps = [ + ":manifest_with_comments_app", + ":manifest_with_comments_app_client", + ":manifest_with_comments_app_test_files", + ] +} diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/__init__.py b/tests/ten_runtime/integration/cpp/manifest_with_comments/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc b/tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc new file mode 100644 index 0000000000..cb862417d2 --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc @@ -0,0 +1,43 @@ +// +// 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 + +#include "tests/common/client/cpp/msgpack_tcp.h" + +int main(int argc, char **argv) { + // Create a client and connect to the app. + auto *client = new ten::msgpack_tcp_client_t("msgpack://127.0.0.1:8001/"); + + // Send graph. + auto start_graph_cmd = ten::cmd_start_graph_t::create(); + start_graph_cmd->set_graph_from_json(R"({ + "nodes": [{ + "type": "extension", + "name": "test_extension", + "addon": "default_extension_cpp", + "app": "msgpack://127.0.0.1:8001/", + "extension_group": "test_extension_group" + }] + })"); + auto cmd_result = + client->send_cmd_and_recv_result(std::move(start_graph_cmd)); + TEN_ASSERT(TEN_STATUS_CODE_OK == cmd_result->get_status_code(), + "Should not happen."); + + // Send a user-defined 'hello world' command. + auto hello_world_cmd = ten::cmd_t::create("hello_world"); + hello_world_cmd->set_dest("msgpack://127.0.0.1:8001/", nullptr, + "test_extension"); + cmd_result = client->send_cmd_and_recv_result(std::move(hello_world_cmd)); + TEN_ASSERT(TEN_STATUS_CODE_OK == cmd_result->get_status_code(), + "Should not happen."); + TEN_ASSERT(static_cast("hello world, too") == + cmd_result->get_property_string("detail"), + "Should not happen."); + + delete client; +} diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json new file mode 100644 index 0000000000..841126bc1e --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json @@ -0,0 +1,29 @@ +{ + "type": "app", + "name": "default_app_cpp", + "version": "0.10.2", + "dependencies": [ + { + "type": "system", + "name": "ten_runtime", + "version": "0.10.2" + }, + { + "type": "extension", + "name": "default_extension_cpp", + "version": "0.10.2" + }, + { + "type": "protocol", + "name": "msgpack", + "version": "0.10.2" + } + ], + "api": { + "property": { + "hello": { + "type": "string" + } + } + } +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json new file mode 100644 index 0000000000..61494e733d --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json @@ -0,0 +1,20 @@ +{ + "ten": { + "uri": "msgpack://127.0.0.1:8001/", + "predefined_graphs": [ + { + "name": "default", + "auto_start": false, + "nodes": [ + { + "type": "extension", + "name": "default_extension_cpp", + "addon": "default_extension_cpp", + "extension_group": "default_extension_group" + } + ] + } + ] + }, + "hello": "world" +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn new file mode 100644 index 0000000000..9e148e2c64 --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn @@ -0,0 +1,20 @@ +# +# 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. +# +import("//build/feature/ten_package.gni") + +ten_package("default_extension_cpp") { + package_kind = "extension" + enable_build = true + + resources = [ + "manifest.json", + "property.json", + ] + + sources = [ "src/main.cc" ] + include_dirs = [ "//core/include" ] +} diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json new file mode 100644 index 0000000000..e442ebdc6a --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json @@ -0,0 +1,31 @@ +{ + "type": "extension", + "name": "default_extension_cpp", + "version": "0.10.2", + "dependencies": [ + { + "type": "system", + "name": "ten_runtime", + "version": "0.10.2" + } + ], + "package": { + "include": [ + "**" + ] + }, + "api": { + "cmd_in": [ + { + "name": "hello_world" + } + ], + "cmd_out": [], + "data_in": [], + "data_out": [], + "video_frame_in": [], + "video_frame_out": [], + "audio_frame_in": [], + "audio_frame_out": [] + } +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json new file mode 100644 index 0000000000..eeedd40076 --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json @@ -0,0 +1,3 @@ +{ + "hello": "world" +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc new file mode 100644 index 0000000000..3d6bdcbade --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc @@ -0,0 +1,39 @@ +// +// 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 +#include + +#include "ten_runtime/binding/cpp/ten.h" + +class test_extension : public ten::extension_t { + public: + explicit test_extension(const char *name) : ten::extension_t(name) {} + + void on_init(ten::ten_env_t &ten_env) override { ten_env.on_init_done(); } + + void on_start(ten::ten_env_t &ten_env) override { + // The property.json will be loaded by default during `on_init` phase, so + // the property `hello` should be available here. + auto prop = ten_env.get_property_string("hello"); + if (prop != "world") { + assert(0 && "Should not happen."); + } + + ten_env.on_start_done(); + } + + void on_cmd(ten::ten_env_t &ten_env, + std::unique_ptr cmd) override { + if (cmd->get_name() == "hello_world") { + auto cmd_result = ten::cmd_result_t::create(TEN_STATUS_CODE_OK, *cmd); + cmd_result->set_property("detail", "hello world, too"); + ten_env.return_result(std::move(cmd_result)); + } + } +}; + +TEN_CPP_REGISTER_ADDON_AS_EXTENSION(default_extension_cpp, test_extension); diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py b/tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py new file mode 100644 index 0000000000..cbbafad73d --- /dev/null +++ b/tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py @@ -0,0 +1,159 @@ +""" +Test manifest_with_comments_app. +""" + +import subprocess +import os +import sys +from sys import stdout +from .utils import msgpack, build_config, build_pkg, fs_utils + + +def test_manifest_with_comments_app(): + """Test client and app server.""" + base_path = os.path.dirname(os.path.abspath(__file__)) + root_dir = os.path.join(base_path, "../../../../../") + + my_env = os.environ.copy() + + app_dir_name = "manifest_with_comments_app" + app_root_path = os.path.join(base_path, app_dir_name) + app_language = "cpp" + + build_config_args = build_config.parse_build_config( + os.path.join(root_dir, "tgn_args.txt"), + ) + + if build_config_args.ten_enable_integration_tests_prebuilt is False: + # Before starting, cleanup the old app package. + fs_utils.remove_tree(app_root_path) + + print(f'Assembling and building package "{app_dir_name}".') + + rc = build_pkg.prepare_and_build_app( + build_config_args, + root_dir, + base_path, + app_dir_name, + app_language, + ) + if rc != 0: + assert False, "Failed to build package." + + tman_install_cmd = [ + os.path.join(root_dir, "ten_manager/bin/tman"), + "--config-file", + os.path.join(root_dir, "tests/local_registry/config.json"), + "--yes", + "install", + ] + + tman_install_process = subprocess.Popen( + tman_install_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + tman_install_process.wait() + return_code = tman_install_process.returncode + if return_code != 0: + assert False, "Failed to install package." + + if sys.platform == "win32": + my_env["PATH"] = ( + os.path.join( + base_path, + "manifest_with_comments_app/ten_packages/system/ten_runtime/lib", + ) + + ";" + + my_env["PATH"] + ) + server_cmd = os.path.join( + base_path, "manifest_with_comments_app/bin/manifest_with_comments_app.exe" + ) + client_cmd = os.path.join(base_path, "manifest_with_comments_app_client.exe") + elif sys.platform == "darwin": + # client depends on some libraries in the TEN app. + my_env["DYLD_LIBRARY_PATH"] = os.path.join( + base_path, + "manifest_with_comments_app/ten_packages/system/ten_runtime/lib", + ) + server_cmd = os.path.join( + base_path, "manifest_with_comments_app/bin/manifest_with_comments_app" + ) + client_cmd = os.path.join(base_path, "manifest_with_comments_app_client") + else: + # client depends on some libraries in the TEN app. + my_env["LD_LIBRARY_PATH"] = os.path.join( + base_path, + "manifest_with_comments_app/ten_packages/system/ten_runtime/lib", + ) + server_cmd = os.path.join( + base_path, "manifest_with_comments_app/bin/manifest_with_comments_app" + ) + client_cmd = os.path.join(base_path, "manifest_with_comments_app_client") + + if ( + build_config_args.enable_sanitizer + and not build_config_args.is_clang + ): + libasan_path = os.path.join( + base_path, + ( + "manifest_with_comments_app/ten_packages/system/" + "ten_runtime/lib/libasan.so" + ), + ) + if os.path.exists(libasan_path): + print("Using AddressSanitizer library.") + my_env["LD_PRELOAD"] = libasan_path + + if not os.path.isfile(server_cmd): + print(f"Server command '{server_cmd}' does not exist.") + assert False + + server = subprocess.Popen( + server_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + + is_started, sock = msgpack.is_app_started("127.0.0.1", 8001, 10) + if not is_started: + print("The manifest_with_comments_app is not started after 10 seconds.") + + server.kill() + exit_code = server.wait() + print("The exit code of manifest_with_comments_app: ", exit_code) + + assert exit_code == 0 + assert False + + return + + client = subprocess.Popen( + client_cmd, stdout=stdout, stderr=subprocess.STDOUT, env=my_env + ) + + # The client will quit after the test is completed. + client_rc = client.wait() + if client_rc != 0: + server.kill() + + # We cannot shutdown the socket before the client is closed, due to it will + # trigger the GC of the app server. + sock.close() + + server_rc = server.wait() + print("server: ", server_rc) + print("client: ", client_rc) + assert server_rc == 0 + assert client_rc == 0 + + if build_config_args.ten_enable_tests_cleanup is True: + # Testing complete. If builds are only created during the testing phase, + # we can clear the build results to save disk space. + fs_utils.remove_tree(app_root_path) From 20d29d512deddd501b8e5a60853216ed458f25ea Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 3 May 2025 14:17:16 +0800 Subject: [PATCH 3/3] fix: refine codes --- tests/ten_runtime/integration/cpp/BUILD.gn | 1 - .../cpp/manifest_with_comments/BUILD.gn | 86 ---------- .../cpp/manifest_with_comments/__init__.py | 0 .../manifest_with_comments/client/client.cc | 43 ----- .../manifest_with_comments_app/manifest.json | 29 ---- .../manifest_with_comments_app/property.json | 20 --- .../extension/default_extension_cpp/BUILD.gn | 20 --- .../default_extension_cpp/manifest.json | 31 ---- .../default_extension_cpp/property.json | 3 - .../default_extension_cpp/src/main.cc | 39 ----- .../cpp/manifest_with_comments/test_case.py | 159 ------------------ 11 files changed, 431 deletions(-) delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/__init__.py delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc delete mode 100644 tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py diff --git a/tests/ten_runtime/integration/cpp/BUILD.gn b/tests/ten_runtime/integration/cpp/BUILD.gn index 8e5e113117..b78c38f44a 100644 --- a/tests/ten_runtime/integration/cpp/BUILD.gn +++ b/tests/ten_runtime/integration/cpp/BUILD.gn @@ -15,7 +15,6 @@ group("cpp") { "hello_world", "large_result", "long_running", - "manifest_with_comments", "restful", ] diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn b/tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn deleted file mode 100644 index 5d10358d09..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/BUILD.gn +++ /dev/null @@ -1,86 +0,0 @@ -# -# 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. -# -import("//build/ten_runtime/feature/test.gni") -import("//build/ten_runtime/ten.gni") - -ten_package_test_prepare_app("manifest_with_comments_app") { - src_app = "default_app_cpp" - src_app_language = "cpp" - generated_app_src_root_dir_name = "manifest_with_comments_app" - - replace_paths_after_install_app = [ - "manifest_with_comments_app/manifest.json", - "manifest_with_comments_app/property.json", - ] - - replace_paths_after_install_all = [ - "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json", - "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json", - "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc", - "manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn", - ] - - if (ten_enable_ten_manager) { - deps = [ - "//core/src/ten_manager", - "//core/src/ten_runtime:upload_ten_runtime_system_package_to_server", - "//packages/core_apps/default_app_cpp:upload_default_app_cpp_to_server", - "//packages/core_extensions/default_extension_cpp:upload_default_extension_cpp_to_server", - "//packages/core_protocols/msgpack:upload_protocol_msgpack_to_server", - ] - } -} - -ten_package_test_prepare_client("manifest_with_comments_app_client") { - sources = [ "client/client.cc" ] - include_dirs = [ - "//core/src", - "//core", - "//packages", - "//tests", - ] - deps = [ - "//core/src/ten_runtime", - "//packages/core_protocols/msgpack:msgpack_files", - "//tests/common/client:msgpack_client", - "//third_party/msgpack:msgpackc", - "//third_party/nlohmann_json", - ] -} - -ten_package_test_prepare_auxiliary_resources( - "manifest_with_comments_app_test_files") { - resources = [ - "__init__.py", - "test_case.py", - ] - - utils_files = exec_script("//.gnfiles/build/scripts/glob_file.py", - [ - "--dir", - rebase_path("//tests/utils/**/*"), - "--dir-base", - rebase_path("//tests/utils"), - "--recursive", - "--only-output-file", - ], - "json") - - foreach(utils_file, utils_files) { - utils_file_rel_path = utils_file.relative_path - resources += - [ "//tests/utils/${utils_file_rel_path}=>utils/${utils_file_rel_path}" ] - } -} - -group("manifest_with_comments") { - deps = [ - ":manifest_with_comments_app", - ":manifest_with_comments_app_client", - ":manifest_with_comments_app_test_files", - ] -} diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/__init__.py b/tests/ten_runtime/integration/cpp/manifest_with_comments/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc b/tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc deleted file mode 100644 index cb862417d2..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/client/client.cc +++ /dev/null @@ -1,43 +0,0 @@ -// -// 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 - -#include "tests/common/client/cpp/msgpack_tcp.h" - -int main(int argc, char **argv) { - // Create a client and connect to the app. - auto *client = new ten::msgpack_tcp_client_t("msgpack://127.0.0.1:8001/"); - - // Send graph. - auto start_graph_cmd = ten::cmd_start_graph_t::create(); - start_graph_cmd->set_graph_from_json(R"({ - "nodes": [{ - "type": "extension", - "name": "test_extension", - "addon": "default_extension_cpp", - "app": "msgpack://127.0.0.1:8001/", - "extension_group": "test_extension_group" - }] - })"); - auto cmd_result = - client->send_cmd_and_recv_result(std::move(start_graph_cmd)); - TEN_ASSERT(TEN_STATUS_CODE_OK == cmd_result->get_status_code(), - "Should not happen."); - - // Send a user-defined 'hello world' command. - auto hello_world_cmd = ten::cmd_t::create("hello_world"); - hello_world_cmd->set_dest("msgpack://127.0.0.1:8001/", nullptr, - "test_extension"); - cmd_result = client->send_cmd_and_recv_result(std::move(hello_world_cmd)); - TEN_ASSERT(TEN_STATUS_CODE_OK == cmd_result->get_status_code(), - "Should not happen."); - TEN_ASSERT(static_cast("hello world, too") == - cmd_result->get_property_string("detail"), - "Should not happen."); - - delete client; -} diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json deleted file mode 100644 index 841126bc1e..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/manifest.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "app", - "name": "default_app_cpp", - "version": "0.10.2", - "dependencies": [ - { - "type": "system", - "name": "ten_runtime", - "version": "0.10.2" - }, - { - "type": "extension", - "name": "default_extension_cpp", - "version": "0.10.2" - }, - { - "type": "protocol", - "name": "msgpack", - "version": "0.10.2" - } - ], - "api": { - "property": { - "hello": { - "type": "string" - } - } - } -} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json deleted file mode 100644 index 61494e733d..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/property.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "ten": { - "uri": "msgpack://127.0.0.1:8001/", - "predefined_graphs": [ - { - "name": "default", - "auto_start": false, - "nodes": [ - { - "type": "extension", - "name": "default_extension_cpp", - "addon": "default_extension_cpp", - "extension_group": "default_extension_group" - } - ] - } - ] - }, - "hello": "world" -} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn deleted file mode 100644 index 9e148e2c64..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/BUILD.gn +++ /dev/null @@ -1,20 +0,0 @@ -# -# 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. -# -import("//build/feature/ten_package.gni") - -ten_package("default_extension_cpp") { - package_kind = "extension" - enable_build = true - - resources = [ - "manifest.json", - "property.json", - ] - - sources = [ "src/main.cc" ] - include_dirs = [ "//core/include" ] -} diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json deleted file mode 100644 index e442ebdc6a..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/manifest.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "type": "extension", - "name": "default_extension_cpp", - "version": "0.10.2", - "dependencies": [ - { - "type": "system", - "name": "ten_runtime", - "version": "0.10.2" - } - ], - "package": { - "include": [ - "**" - ] - }, - "api": { - "cmd_in": [ - { - "name": "hello_world" - } - ], - "cmd_out": [], - "data_in": [], - "data_out": [], - "video_frame_in": [], - "video_frame_out": [], - "audio_frame_in": [], - "audio_frame_out": [] - } -} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json deleted file mode 100644 index eeedd40076..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/property.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "hello": "world" -} \ No newline at end of file diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc b/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc deleted file mode 100644 index 3d6bdcbade..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/manifest_with_comments_app/ten_packages/extension/default_extension_cpp/src/main.cc +++ /dev/null @@ -1,39 +0,0 @@ -// -// 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 -#include - -#include "ten_runtime/binding/cpp/ten.h" - -class test_extension : public ten::extension_t { - public: - explicit test_extension(const char *name) : ten::extension_t(name) {} - - void on_init(ten::ten_env_t &ten_env) override { ten_env.on_init_done(); } - - void on_start(ten::ten_env_t &ten_env) override { - // The property.json will be loaded by default during `on_init` phase, so - // the property `hello` should be available here. - auto prop = ten_env.get_property_string("hello"); - if (prop != "world") { - assert(0 && "Should not happen."); - } - - ten_env.on_start_done(); - } - - void on_cmd(ten::ten_env_t &ten_env, - std::unique_ptr cmd) override { - if (cmd->get_name() == "hello_world") { - auto cmd_result = ten::cmd_result_t::create(TEN_STATUS_CODE_OK, *cmd); - cmd_result->set_property("detail", "hello world, too"); - ten_env.return_result(std::move(cmd_result)); - } - } -}; - -TEN_CPP_REGISTER_ADDON_AS_EXTENSION(default_extension_cpp, test_extension); diff --git a/tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py b/tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py deleted file mode 100644 index cbbafad73d..0000000000 --- a/tests/ten_runtime/integration/cpp/manifest_with_comments/test_case.py +++ /dev/null @@ -1,159 +0,0 @@ -""" -Test manifest_with_comments_app. -""" - -import subprocess -import os -import sys -from sys import stdout -from .utils import msgpack, build_config, build_pkg, fs_utils - - -def test_manifest_with_comments_app(): - """Test client and app server.""" - base_path = os.path.dirname(os.path.abspath(__file__)) - root_dir = os.path.join(base_path, "../../../../../") - - my_env = os.environ.copy() - - app_dir_name = "manifest_with_comments_app" - app_root_path = os.path.join(base_path, app_dir_name) - app_language = "cpp" - - build_config_args = build_config.parse_build_config( - os.path.join(root_dir, "tgn_args.txt"), - ) - - if build_config_args.ten_enable_integration_tests_prebuilt is False: - # Before starting, cleanup the old app package. - fs_utils.remove_tree(app_root_path) - - print(f'Assembling and building package "{app_dir_name}".') - - rc = build_pkg.prepare_and_build_app( - build_config_args, - root_dir, - base_path, - app_dir_name, - app_language, - ) - if rc != 0: - assert False, "Failed to build package." - - tman_install_cmd = [ - os.path.join(root_dir, "ten_manager/bin/tman"), - "--config-file", - os.path.join(root_dir, "tests/local_registry/config.json"), - "--yes", - "install", - ] - - tman_install_process = subprocess.Popen( - tman_install_cmd, - stdout=stdout, - stderr=subprocess.STDOUT, - env=my_env, - cwd=app_root_path, - ) - tman_install_process.wait() - return_code = tman_install_process.returncode - if return_code != 0: - assert False, "Failed to install package." - - if sys.platform == "win32": - my_env["PATH"] = ( - os.path.join( - base_path, - "manifest_with_comments_app/ten_packages/system/ten_runtime/lib", - ) - + ";" - + my_env["PATH"] - ) - server_cmd = os.path.join( - base_path, "manifest_with_comments_app/bin/manifest_with_comments_app.exe" - ) - client_cmd = os.path.join(base_path, "manifest_with_comments_app_client.exe") - elif sys.platform == "darwin": - # client depends on some libraries in the TEN app. - my_env["DYLD_LIBRARY_PATH"] = os.path.join( - base_path, - "manifest_with_comments_app/ten_packages/system/ten_runtime/lib", - ) - server_cmd = os.path.join( - base_path, "manifest_with_comments_app/bin/manifest_with_comments_app" - ) - client_cmd = os.path.join(base_path, "manifest_with_comments_app_client") - else: - # client depends on some libraries in the TEN app. - my_env["LD_LIBRARY_PATH"] = os.path.join( - base_path, - "manifest_with_comments_app/ten_packages/system/ten_runtime/lib", - ) - server_cmd = os.path.join( - base_path, "manifest_with_comments_app/bin/manifest_with_comments_app" - ) - client_cmd = os.path.join(base_path, "manifest_with_comments_app_client") - - if ( - build_config_args.enable_sanitizer - and not build_config_args.is_clang - ): - libasan_path = os.path.join( - base_path, - ( - "manifest_with_comments_app/ten_packages/system/" - "ten_runtime/lib/libasan.so" - ), - ) - if os.path.exists(libasan_path): - print("Using AddressSanitizer library.") - my_env["LD_PRELOAD"] = libasan_path - - if not os.path.isfile(server_cmd): - print(f"Server command '{server_cmd}' does not exist.") - assert False - - server = subprocess.Popen( - server_cmd, - stdout=stdout, - stderr=subprocess.STDOUT, - env=my_env, - cwd=app_root_path, - ) - - is_started, sock = msgpack.is_app_started("127.0.0.1", 8001, 10) - if not is_started: - print("The manifest_with_comments_app is not started after 10 seconds.") - - server.kill() - exit_code = server.wait() - print("The exit code of manifest_with_comments_app: ", exit_code) - - assert exit_code == 0 - assert False - - return - - client = subprocess.Popen( - client_cmd, stdout=stdout, stderr=subprocess.STDOUT, env=my_env - ) - - # The client will quit after the test is completed. - client_rc = client.wait() - if client_rc != 0: - server.kill() - - # We cannot shutdown the socket before the client is closed, due to it will - # trigger the GC of the app server. - sock.close() - - server_rc = server.wait() - print("server: ", server_rc) - print("client: ", client_rc) - assert server_rc == 0 - assert client_rc == 0 - - if build_config_args.ten_enable_tests_cleanup is True: - # Testing complete. If builds are only created during the testing phase, - # we can clear the build results to save disk space. - fs_utils.remove_tree(app_root_path)