From ccd4a5e89552e5a065e233f75922d59babc09aa9 Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 20:32:22 +0800 Subject: [PATCH 1/8] feat: add graph UI metadata management endpoints and structures --- core/src/ten_manager/src/config/metadata.rs | 59 +++ .../src/designer/metadata/graph_ui/get.rs | 53 +++ .../src/designer/metadata/graph_ui/mod.rs | 8 + .../src/designer/metadata/graph_ui/set.rs | 53 +++ .../ten_manager/src/designer/metadata/mod.rs | 7 + .../tests/test_case/designer/metadata/mod.rs | 377 ++++++++++++++++++ 6 files changed, 557 insertions(+) create mode 100644 core/src/ten_manager/src/config/metadata.rs create mode 100644 core/src/ten_manager/src/designer/metadata/graph_ui/get.rs create mode 100644 core/src/ten_manager/src/designer/metadata/graph_ui/mod.rs create mode 100644 core/src/ten_manager/src/designer/metadata/graph_ui/set.rs create mode 100644 core/src/ten_manager/src/designer/metadata/mod.rs create mode 100644 core/src/ten_manager/tests/test_case/designer/metadata/mod.rs diff --git a/core/src/ten_manager/src/config/metadata.rs b/core/src/ten_manager/src/config/metadata.rs new file mode 100644 index 000000000..28ca91a10 --- /dev/null +++ b/core/src/ten_manager/src/config/metadata.rs @@ -0,0 +1,59 @@ +// +// 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. +// +use std::collections::HashMap; +use std::{fs, path::PathBuf}; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use crate::constants::METADATA_FILE; + +use super::get_default_home_dir; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct NodeGeometry { + pub app: Option, + pub extension: String, + + pub x: i64, + pub y: i64, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct GraphGeometry { + pub nodes_geometry: Vec, +} + +#[derive(Debug, Serialize, Deserialize, Default, Clone)] +pub struct GraphUiMetadata { + pub graphs_geometry: HashMap, +} + +#[derive(Serialize, Deserialize, Debug, Default, Clone)] +pub struct TmanMetadata { + pub graph_ui: GraphUiMetadata, +} + +fn get_default_metadata_path() -> PathBuf { + let mut config_path = get_default_home_dir(); + config_path.push(METADATA_FILE); + config_path +} + +// Read the internal configuration from the specified path. +pub fn read_metadata() -> Result> { + let config_path = get_default_metadata_path(); + if !config_path.exists() { + return Ok(None); + } + + let config_data = fs::read_to_string(config_path.clone())?; + let config: TmanMetadata = serde_json::from_str(&config_data)?; + + Ok(Some(config)) +} diff --git a/core/src/ten_manager/src/designer/metadata/graph_ui/get.rs b/core/src/ten_manager/src/designer/metadata/graph_ui/get.rs new file mode 100644 index 000000000..c8b76b779 --- /dev/null +++ b/core/src/ten_manager/src/designer/metadata/graph_ui/get.rs @@ -0,0 +1,53 @@ +// +// 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. +// +use std::sync::Arc; + +use actix_web::{web, HttpResponse, Responder}; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use crate::config::metadata::GraphGeometry; +use crate::designer::response::{ApiResponse, Status}; +use crate::designer::DesignerState; + +#[derive(Debug, Serialize, Deserialize)] +pub struct GetGraphUiRequestPayload { + pub graph_id: Uuid, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct GetGraphUiResponseData { + #[serde(skip_serializing_if = "Option::is_none")] + pub graph_geometry: Option, +} + +pub async fn get_graph_ui_endpoint( + request_payload: web::Json, + state: web::Data>, +) -> Result { + let graph_id = request_payload.graph_id; + + // Look for the graph geometry with the given graph_id. + let graph_geometry = state + .tman_metadata + .read() + .await + .graph_ui + .graphs_geometry + .get(&graph_id) + .cloned(); + + let response_data = GetGraphUiResponseData { graph_geometry }; + + let response = ApiResponse { + status: Status::Ok, + data: response_data, + meta: None, + }; + + Ok(HttpResponse::Ok().json(response)) +} diff --git a/core/src/ten_manager/src/designer/metadata/graph_ui/mod.rs b/core/src/ten_manager/src/designer/metadata/graph_ui/mod.rs new file mode 100644 index 000000000..6866b1741 --- /dev/null +++ b/core/src/ten_manager/src/designer/metadata/graph_ui/mod.rs @@ -0,0 +1,8 @@ +// +// 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. +// +pub mod get; +pub mod set; diff --git a/core/src/ten_manager/src/designer/metadata/graph_ui/set.rs b/core/src/ten_manager/src/designer/metadata/graph_ui/set.rs new file mode 100644 index 000000000..0060baf90 --- /dev/null +++ b/core/src/ten_manager/src/designer/metadata/graph_ui/set.rs @@ -0,0 +1,53 @@ +// +// 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. +// +use std::sync::Arc; + +use actix_web::{web, HttpResponse, Responder}; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use crate::config::metadata::GraphGeometry; +use crate::designer::response::{ApiResponse, Status}; +use crate::designer::DesignerState; + +#[derive(Debug, Serialize, Deserialize)] +pub struct SetGraphUiRequestPayload { + pub graph_id: Uuid, + pub graph_geometry: GraphGeometry, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SetGraphUiResponseData { + pub success: bool, +} + +pub async fn set_graph_ui_endpoint( + request_payload: web::Json, + state: web::Data>, +) -> Result { + // Extract the payload data. + let payload = request_payload.into_inner(); + let graph_id = payload.graph_id; + let graph_geometry = payload.graph_geometry; + + state + .tman_metadata + .write() + .await + .graph_ui + .graphs_geometry + .insert(graph_id, graph_geometry); + + let response_data = SetGraphUiResponseData { success: true }; + let response = ApiResponse { + status: Status::Ok, + data: response_data, + meta: None, + }; + + Ok(HttpResponse::Ok().json(response)) +} diff --git a/core/src/ten_manager/src/designer/metadata/mod.rs b/core/src/ten_manager/src/designer/metadata/mod.rs new file mode 100644 index 000000000..ac396131c --- /dev/null +++ b/core/src/ten_manager/src/designer/metadata/mod.rs @@ -0,0 +1,7 @@ +// +// 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. +// +pub mod graph_ui; diff --git a/core/src/ten_manager/tests/test_case/designer/metadata/mod.rs b/core/src/ten_manager/tests/test_case/designer/metadata/mod.rs new file mode 100644 index 000000000..6dbaecb6e --- /dev/null +++ b/core/src/ten_manager/tests/test_case/designer/metadata/mod.rs @@ -0,0 +1,377 @@ +// +// 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. +// +use std::{collections::HashMap, sync::Arc}; + +use actix_web::{http::StatusCode, test, web}; +use uuid::Uuid; + +use ten_manager::{ + config::{ + metadata::{ + GraphGeometry, GraphUiMetadata, NodeGeometry, TmanMetadata, + }, + TmanConfig, + }, + designer::{ + metadata::graph_ui::{ + get::{ + get_graph_ui_endpoint, GetGraphUiRequestPayload, + GetGraphUiResponseData, + }, + set::{ + set_graph_ui_endpoint, SetGraphUiRequestPayload, + SetGraphUiResponseData, + }, + }, + response::ApiResponse, + DesignerState, + }, + output::TmanOutputCli, +}; + +#[actix_web::test] +async fn test_get_graph_ui_empty() { + // Generate a random graph_id for testing. + let graph_id = Uuid::new_v4(); + + // Create the request payload. + let payload = GetGraphUiRequestPayload { graph_id }; + + // Create a clean state with empty config. + let designer_state = DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), + out: Arc::new(Box::new(TmanOutputCli)), + pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), + graphs_cache: tokio::sync::RwLock::new(HashMap::new()), + }; + let state = web::Data::new(Arc::new(designer_state)); + + // Create app with the endpoint. + let app = test::init_service( + actix_web::App::new() + .app_data(state.clone()) + .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), + ) + .await; + + // Make the request. + let req = test::TestRequest::post() + .uri("/graph-ui/get") + .set_json(&payload) + .to_request(); + + let resp = test::call_service(&app, req).await; + + // Assert status code is OK. + assert_eq!(resp.status(), StatusCode::OK); + + // Extract and check the response body. + let body = test::read_body(resp).await; + let result: ApiResponse = + serde_json::from_slice(&body).unwrap(); + + // Assert that graph_geometry is None since we haven't set it yet. + assert!(result.data.graph_geometry.is_none()); +} + +#[actix_web::test] +async fn test_set_and_get_graph_ui() { + // Generate a random graph_id for testing. + let graph_id = Uuid::new_v4(); + + // Create test geometry data. + let node_geometry = NodeGeometry { + app: Some("test_app".to_string()), + extension: "test_extension".to_string(), + x: 100, + y: 200, + }; + + let graph_geometry = GraphGeometry { + nodes_geometry: vec![node_geometry], + }; + + // Create the set request payload. + let set_payload = SetGraphUiRequestPayload { + graph_id, + graph_geometry: graph_geometry.clone(), + }; + + // Create a clean state with empty config. + let designer_state = DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), + out: Arc::new(Box::new(TmanOutputCli)), + pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), + graphs_cache: tokio::sync::RwLock::new(HashMap::new()), + }; + let state = web::Data::new(Arc::new(designer_state)); + + // Create app with both endpoints. + let app = test::init_service( + actix_web::App::new() + .app_data(state.clone()) + .route("/graph-ui/set", web::post().to(set_graph_ui_endpoint)) + .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), + ) + .await; + + // Make the set request. + let set_req = test::TestRequest::post() + .uri("/graph-ui/set") + .set_json(&set_payload) + .to_request(); + + let set_resp = test::call_service(&app, set_req).await; + + // Assert status code for set is OK. + assert_eq!(set_resp.status(), StatusCode::OK); + + // Extract and check the set response. + let set_body = test::read_body(set_resp).await; + let set_result: ApiResponse = + serde_json::from_slice(&set_body).unwrap(); + + // Assert that set was successful. + assert!(set_result.data.success); + + // Now create and make the get request for the same graph_id. + let get_payload = GetGraphUiRequestPayload { graph_id }; + + let get_req = test::TestRequest::post() + .uri("/graph-ui/get") + .set_json(&get_payload) + .to_request(); + + let get_resp = test::call_service(&app, get_req).await; + + // Assert status code for get is OK. + assert_eq!(get_resp.status(), StatusCode::OK); + + // Extract and check the get response. + let get_body = test::read_body(get_resp).await; + let get_result: ApiResponse = + serde_json::from_slice(&get_body).unwrap(); + + // Assert that graph_geometry is now present and matches what we set. + assert!(get_result.data.graph_geometry.is_some()); + + let returned_geometry = get_result.data.graph_geometry.unwrap(); + assert_eq!(returned_geometry.nodes_geometry.len(), 1); + assert_eq!(returned_geometry.nodes_geometry[0].x, 100); + assert_eq!(returned_geometry.nodes_geometry[0].y, 200); + assert_eq!( + returned_geometry.nodes_geometry[0].extension, + "test_extension" + ); + assert_eq!( + returned_geometry.nodes_geometry[0].app, + Some("test_app".to_string()) + ); +} + +#[actix_web::test] +async fn test_update_graph_ui() { + // Generate a random graph_id for testing. + let graph_id = Uuid::new_v4(); + + // Create initial geometry data. + let initial_node_geometry = NodeGeometry { + app: Some("initial_app".to_string()), + extension: "initial_extension".to_string(), + x: 10, + y: 20, + }; + + let initial_graph_geometry = GraphGeometry { + nodes_geometry: vec![initial_node_geometry], + }; + + // Create updated geometry data. + let updated_node_geometry = NodeGeometry { + app: Some("updated_app".to_string()), + extension: "updated_extension".to_string(), + x: 30, + y: 40, + }; + + let updated_graph_geometry = GraphGeometry { + nodes_geometry: vec![updated_node_geometry], + }; + + // Create a designer state with pre-filled graph_ui config. + let mut graph_ui_config = GraphUiMetadata::default(); + graph_ui_config + .graphs_geometry + .insert(graph_id, initial_graph_geometry); + + let tman_metadata = TmanMetadata { + graph_ui: graph_ui_config, + }; + + let designer_state = DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + tman_metadata, + )), + out: Arc::new(Box::new(TmanOutputCli)), + pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), + graphs_cache: tokio::sync::RwLock::new(HashMap::new()), + }; + let state = web::Data::new(Arc::new(designer_state)); + + // Create app with both endpoints. + let app = test::init_service( + actix_web::App::new() + .app_data(state.clone()) + .route("/graph-ui/set", web::post().to(set_graph_ui_endpoint)) + .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), + ) + .await; + + // Check initial state with get. + let get_payload = GetGraphUiRequestPayload { graph_id }; + let get_req = test::TestRequest::post() + .uri("/graph-ui/get") + .set_json(&get_payload) + .to_request(); + + let get_resp = test::call_service(&app, get_req).await; + assert_eq!(get_resp.status(), StatusCode::OK); + + let get_body = test::read_body(get_resp).await; + let get_result: ApiResponse = + serde_json::from_slice(&get_body).unwrap(); + + let initial_geo = get_result.data.graph_geometry.unwrap(); + assert_eq!(initial_geo.nodes_geometry[0].x, 10); + assert_eq!(initial_geo.nodes_geometry[0].y, 20); + + // Now update with new geometry. + let set_payload = SetGraphUiRequestPayload { + graph_id, + graph_geometry: updated_graph_geometry, + }; + + let set_req = test::TestRequest::post() + .uri("/graph-ui/set") + .set_json(&set_payload) + .to_request(); + + let set_resp = test::call_service(&app, set_req).await; + assert_eq!(set_resp.status(), StatusCode::OK); + + // Verify updated geometry. + let get_req = test::TestRequest::post() + .uri("/graph-ui/get") + .set_json(&get_payload) + .to_request(); + + let get_resp = test::call_service(&app, get_req).await; + let get_body = test::read_body(get_resp).await; + let get_result: ApiResponse = + serde_json::from_slice(&get_body).unwrap(); + + let updated_geo = get_result.data.graph_geometry.unwrap(); + assert_eq!(updated_geo.nodes_geometry[0].x, 30); + assert_eq!(updated_geo.nodes_geometry[0].y, 40); + assert_eq!(updated_geo.nodes_geometry[0].extension, "updated_extension"); + assert_eq!( + updated_geo.nodes_geometry[0].app, + Some("updated_app".to_string()) + ); +} + +#[actix_web::test] +async fn test_get_nonexistent_graph_ui() { + // Generate two random graph_ids for testing. + let existing_graph_id = Uuid::new_v4(); + let nonexistent_graph_id = Uuid::new_v4(); + + // Create test geometry data. + let node_geometry = NodeGeometry { + app: Some("test_app".to_string()), + extension: "test_extension".to_string(), + x: 100, + y: 200, + }; + + let graph_geometry = GraphGeometry { + nodes_geometry: vec![node_geometry], + }; + + // Create a designer state with pre-filled graph_ui config for only one + // graph. + let mut graph_ui_config = GraphUiMetadata::default(); + graph_ui_config + .graphs_geometry + .insert(existing_graph_id, graph_geometry); + + let tman_metadata = TmanMetadata { + graph_ui: graph_ui_config, + }; + + let designer_state = DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + tman_metadata, + )), + out: Arc::new(Box::new(TmanOutputCli)), + pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), + graphs_cache: tokio::sync::RwLock::new(HashMap::new()), + }; + let state = web::Data::new(Arc::new(designer_state)); + + // Create app with the get endpoint. + let app = test::init_service( + actix_web::App::new() + .app_data(state.clone()) + .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), + ) + .await; + + // Make request for the nonexistent graph. + let get_payload = GetGraphUiRequestPayload { + graph_id: nonexistent_graph_id, + }; + let get_req = test::TestRequest::post() + .uri("/graph-ui/get") + .set_json(&get_payload) + .to_request(); + + let get_resp = test::call_service(&app, get_req).await; + assert_eq!(get_resp.status(), StatusCode::OK); + + let get_body = test::read_body(get_resp).await; + let get_result: ApiResponse = + serde_json::from_slice(&get_body).unwrap(); + + // Should return None for nonexistent graph. + assert!(get_result.data.graph_geometry.is_none()); + + // Now check the existing graph. + let get_payload = GetGraphUiRequestPayload { + graph_id: existing_graph_id, + }; + let get_req = test::TestRequest::post() + .uri("/graph-ui/get") + .set_json(&get_payload) + .to_request(); + + let get_resp = test::call_service(&app, get_req).await; + let get_body = test::read_body(get_resp).await; + let get_result: ApiResponse = + serde_json::from_slice(&get_body).unwrap(); + + // Should return Some for existing graph. + assert!(get_result.data.graph_geometry.is_some()); +} From 8f2ca6e4087d5e88d68e04f079fd9a9d7c027f1a Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 20:32:26 +0800 Subject: [PATCH 2/8] fix: refine codes --- .../cmd/cmd_check/cmd_check_manifest_json.rs | 6 +- .../cmd/cmd_check/cmd_check_property_json.rs | 6 +- core/src/ten_manager/src/cmd/cmd_check/mod.rs | 10 +- core/src/ten_manager/src/cmd/cmd_create.rs | 8 +- core/src/ten_manager/src/cmd/cmd_delete.rs | 9 +- core/src/ten_manager/src/cmd/cmd_designer.rs | 27 +- core/src/ten_manager/src/cmd/cmd_fetch.rs | 10 +- core/src/ten_manager/src/cmd/cmd_install.rs | 31 +- .../src/cmd/cmd_modify/cmd_modify_graph.rs | 6 +- .../src/ten_manager/src/cmd/cmd_modify/mod.rs | 8 +- core/src/ten_manager/src/cmd/cmd_package.rs | 11 +- core/src/ten_manager/src/cmd/cmd_publish.rs | 12 +- core/src/ten_manager/src/cmd/cmd_run.rs | 10 +- core/src/ten_manager/src/cmd/cmd_uninstall.rs | 8 +- core/src/ten_manager/src/cmd/mod.rs | 28 +- core/src/ten_manager/src/cmd_line.rs | 6 +- core/src/ten_manager/src/config/internal.rs | 59 --- core/src/ten_manager/src/config/mod.rs | 9 +- core/src/ten_manager/src/constants.rs | 2 +- core/src/ten_manager/src/create/mod.rs | 6 +- .../ten_manager/src/dep_and_candidate/mod.rs | 13 +- .../ten_manager/src/designer/apps/addons.rs | 13 +- .../ten_manager/src/designer/apps/create.rs | 49 +-- core/src/ten_manager/src/designer/apps/get.rs | 13 +- .../src/ten_manager/src/designer/apps/load.rs | 22 +- .../ten_manager/src/designer/apps/reload.rs | 22 +- .../src/designer/apps/schema/mod.rs | 13 +- .../ten_manager/src/designer/apps/scripts.rs | 13 +- .../ten_manager/src/designer/apps/unload.rs | 22 +- .../src/designer/builtin_function/install.rs | 6 +- .../designer/builtin_function/install_all.rs | 6 +- .../src/designer/builtin_function/mod.rs | 33 +- .../ten_manager/src/designer/dir_list/mod.rs | 4 +- .../ten_manager/src/designer/doc_link/mod.rs | 4 +- core/src/ten_manager/src/designer/env/mod.rs | 4 +- core/src/ten_manager/src/designer/exec/mod.rs | 4 +- .../src/designer/exec/run_script.rs | 12 +- .../src/designer/extensions/create.rs | 49 +-- .../src/designer/extensions/property.rs | 13 +- .../src/designer/extensions/schema.rs | 13 +- .../src/designer/file_content/mod.rs | 33 +- core/src/ten_manager/src/designer/frontend.rs | 30 +- .../src/designer/graphs/connections/add.rs | 23 +- .../src/designer/graphs/connections/delete.rs | 21 +- .../src/designer/graphs/connections/get.rs | 13 +- .../connections/msg_conversion/update.rs | 27 +- .../ten_manager/src/designer/graphs/get.rs | 13 +- .../src/designer/graphs/nodes/add.rs | 21 +- .../src/designer/graphs/nodes/delete.rs | 21 +- .../src/designer/graphs/nodes/get.rs | 21 +- .../designer/graphs/nodes/property/update.rs | 21 +- .../src/designer/graphs/nodes/replace.rs | 23 +- .../ten_manager/src/designer/graphs/update.rs | 21 +- .../ten_manager/src/designer/help_text/mod.rs | 4 +- .../designer/internal_config/graph_ui/get.rs | 53 --- .../designer/internal_config/graph_ui/mod.rs | 8 - .../designer/internal_config/graph_ui/set.rs | 59 --- .../src/designer/internal_config/mod.rs | 7 - .../src/designer/manifest/validate.rs | 4 +- .../src/designer/messages/compatible.rs | 21 +- core/src/ten_manager/src/designer/mod.rs | 19 +- .../src/designer/preferences/get.rs | 13 +- .../src/designer/preferences/update.rs | 25 +- .../src/designer/preferences/update_field.rs | 20 +- .../src/designer/property/validate.rs | 4 +- .../src/designer/registry/packages.rs | 28 +- .../ten_manager/src/designer/version/mod.rs | 4 +- core/src/ten_manager/src/install/mod.rs | 21 +- core/src/ten_manager/src/main.rs | 4 +- core/src/ten_manager/src/package_file/mod.rs | 7 +- core/src/ten_manager/src/pkg_info/mod.rs | 11 +- core/src/ten_manager/src/registry/local.rs | 10 +- core/src/ten_manager/src/registry/mod.rs | 14 +- core/src/ten_manager/src/registry/remote.rs | 40 +- core/src/ten_manager/src/solver/solve.rs | 84 ++-- .../ten_manager/src/solver/solver_result.rs | 2 +- .../tests/test_case/common/designer_state.rs | 17 +- .../tests/test_case/designer/apps/addons.rs | 14 +- .../tests/test_case/designer/apps/create.rs | 24 +- .../tests/test_case/designer/apps/get.rs | 24 +- .../tests/test_case/designer/apps/load.rs | 14 +- .../tests/test_case/designer/apps/reload.rs | 24 +- .../test_case/designer/apps/schema/mod.rs | 37 +- .../tests/test_case/designer/apps/unload.rs | 39 +- .../designer/builtin_function/install_all.rs | 15 +- .../designer/builtin_function/mod.rs | 15 +- .../tests/test_case/designer/dir_list/mod.rs | 40 +- .../tests/test_case/designer/doc_link/mod.rs | 39 +- .../tests/test_case/designer/env/mod.rs | 22 +- .../designer/extensions/property/mod.rs | 44 ++- .../designer/extensions/schema/mod.rs | 37 +- .../tests/test_case/designer/get_apps.rs | 27 +- .../tests/test_case/designer/get_graphs.rs | 26 +- .../designer/get_packages_scripts.rs | 27 +- .../designer/graphs/connections/add.rs | 87 ++-- .../designer/graphs/connections/delete.rs | 43 +- .../designer/graphs/connections/get.rs | 27 +- .../msg_conversion/add_with_msg_conversion.rs | 57 ++- .../modify_with_msg_conversion.rs | 77 ++-- .../tests/test_case/designer/graphs/get.rs | 29 +- .../test_case/designer/graphs/nodes/add.rs | 79 ++-- .../test_case/designer/graphs/nodes/delete.rs | 43 +- .../test_case/designer/graphs/nodes/get.rs | 30 +- .../designer/graphs/nodes/property/modify.rs | 77 ++-- .../designer/graphs/nodes/replace.rs | 69 ++-- .../tests/test_case/designer/graphs/update.rs | 39 +- .../tests/test_case/designer/help_text/mod.rs | 39 +- .../test_case/designer/internal_config/mod.rs | 372 ------------------ .../tests/test_case/designer/load_apps.rs | 25 +- .../test_case/designer/manifest/validate.rs | 84 ++-- .../test_case/designer/messages/compatible.rs | 52 ++- .../tests/test_case/designer/mod.rs | 2 +- .../test_case/designer/preferences/mod.rs | 122 +++--- .../test_case/designer/property/validate.rs | 87 ++-- .../tests/test_case/designer/reload_apps.rs | 33 +- .../test_case/designer/template_pkgs/mod.rs | 31 +- .../tests/test_case/designer/version/mod.rs | 16 +- 117 files changed, 1380 insertions(+), 1975 deletions(-) delete mode 100644 core/src/ten_manager/src/config/internal.rs delete mode 100644 core/src/ten_manager/src/designer/internal_config/graph_ui/get.rs delete mode 100644 core/src/ten_manager/src/designer/internal_config/graph_ui/mod.rs delete mode 100644 core/src/ten_manager/src/designer/internal_config/graph_ui/set.rs delete mode 100644 core/src/ten_manager/src/designer/internal_config/mod.rs delete mode 100644 core/src/ten_manager/tests/test_case/designer/internal_config/mod.rs diff --git a/core/src/ten_manager/src/cmd/cmd_check/cmd_check_manifest_json.rs b/core/src/ten_manager/src/cmd/cmd_check/cmd_check_manifest_json.rs index d2c838b2a..c06e29bae 100644 --- a/core/src/ten_manager/src/cmd/cmd_check/cmd_check_manifest_json.rs +++ b/core/src/ten_manager/src/cmd/cmd_check/cmd_check_manifest_json.rs @@ -14,7 +14,7 @@ use ten_rust::{ }; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, output::TmanOutput, }; @@ -48,8 +48,8 @@ pub fn parse_sub_cmd( } pub async fn execute_cmd( - _tman_config: Arc, - _tman_internal_config: Arc, + _tman_config: Arc>, + _tman_metadata: Arc>, command_data: CheckManifestJsonCommand, out: Arc>, ) -> Result<()> { diff --git a/core/src/ten_manager/src/cmd/cmd_check/cmd_check_property_json.rs b/core/src/ten_manager/src/cmd/cmd_check/cmd_check_property_json.rs index 165577305..ce88efc39 100644 --- a/core/src/ten_manager/src/cmd/cmd_check/cmd_check_property_json.rs +++ b/core/src/ten_manager/src/cmd/cmd_check/cmd_check_property_json.rs @@ -14,7 +14,7 @@ use ten_rust::{ }; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, output::TmanOutput, }; @@ -48,8 +48,8 @@ pub fn parse_sub_cmd( } pub async fn execute_cmd( - _tman_config: Arc, - _tman_internal_config: Arc, + _tman_config: Arc>, + _tman_metadata: Arc>, command_data: CheckPropertyJsonCommand, out: Arc>, ) -> Result<()> { diff --git a/core/src/ten_manager/src/cmd/cmd_check/mod.rs b/core/src/ten_manager/src/cmd/cmd_check/mod.rs index 1080fb558..848ef6b51 100644 --- a/core/src/ten_manager/src/cmd/cmd_check/mod.rs +++ b/core/src/ten_manager/src/cmd/cmd_check/mod.rs @@ -13,7 +13,7 @@ use anyhow::Result; use clap::{ArgMatches, Command}; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, output::TmanOutput, }; @@ -64,8 +64,8 @@ pub fn parse_sub_cmd(sub_cmd_args: &ArgMatches) -> Result { } pub async fn execute_cmd( - tman_config: Arc, - tman_internal_config: Arc, + tman_config: Arc>, + tman_metadata: Arc>, command_data: CheckCommandData, out: Arc>, ) -> Result<()> { @@ -73,7 +73,7 @@ pub async fn execute_cmd( CheckCommandData::CheckManifestJson(cmd) => { crate::cmd::cmd_check::cmd_check_manifest_json::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -82,7 +82,7 @@ pub async fn execute_cmd( CheckCommandData::CheckPropertyJson(cmd) => { crate::cmd::cmd_check::cmd_check_property_json::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) diff --git a/core/src/ten_manager/src/cmd/cmd_create.rs b/core/src/ten_manager/src/cmd/cmd_create.rs index becdee18f..89491040e 100644 --- a/core/src/ten_manager/src/cmd/cmd_create.rs +++ b/core/src/ten_manager/src/cmd/cmd_create.rs @@ -19,7 +19,7 @@ use ten_rust::pkg_info::{ }; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, create::create_pkg_in_path, output::TmanOutput, version_utils::parse_pkg_name_version_req, @@ -154,8 +154,8 @@ pub fn parse_sub_cmd(sub_cmd_args: &ArgMatches) -> Result { } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: CreateCommand, out: Arc>, ) -> Result<()> { @@ -166,7 +166,7 @@ pub async fn execute_cmd( .context("Failed to get current working directory")?; create_pkg_in_path( - &tman_config, + tman_config, &cwd, &command_data.pkg_type, &command_data.pkg_name, diff --git a/core/src/ten_manager/src/cmd/cmd_delete.rs b/core/src/ten_manager/src/cmd/cmd_delete.rs index 25e36bd45..562295a2b 100644 --- a/core/src/ten_manager/src/cmd/cmd_delete.rs +++ b/core/src/ten_manager/src/cmd/cmd_delete.rs @@ -16,7 +16,8 @@ use semver::Version; use ten_rust::pkg_info::pkg_type::PkgType; -use crate::config::internal::TmanInternalConfig; +use crate::config::is_verbose; +use crate::config::metadata::TmanMetadata; use crate::output::TmanOutput; use crate::{config::TmanConfig, registry::delete_package}; @@ -77,12 +78,12 @@ pub fn parse_sub_cmd( } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: DeleteCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Executing delete command"); out.normal_line(&format!("{:?}", command_data)); } diff --git a/core/src/ten_manager/src/cmd/cmd_designer.rs b/core/src/ten_manager/src/cmd/cmd_designer.rs index d15c3591d..caac341ff 100644 --- a/core/src/ten_manager/src/cmd/cmd_designer.rs +++ b/core/src/ten_manager/src/cmd/cmd_designer.rs @@ -4,11 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - path::Path, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, path::Path, sync::Arc}; use actix_cors::Cors; use actix_web::{http::header, web, App, HttpServer}; @@ -17,7 +13,7 @@ use clap::{value_parser, Arg, ArgMatches, Command}; use console::Emoji; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{is_verbose, metadata::TmanMetadata, TmanConfig}, constants::DESIGNER_BACKEND_DEFAULT_PORT, designer::{configure_routes, frontend::get_frontend_asset, DesignerState}, fs::{check_is_app_folder, get_cwd}, @@ -85,12 +81,12 @@ pub fn parse_sub_cmd( } pub async fn execute_cmd( - tman_config: Arc, - tman_internal_config: Arc, + tman_config: Arc>, + tman_metadata: Arc>, command_data: DesignerCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Executing designer command"); out.normal_line(&format!("{:?}", command_data)); out.normal_line(&format!("{:?}", tman_config)); @@ -115,13 +111,13 @@ pub async fn execute_cmd( } }; - let state = Arc::new(RwLock::new(DesignerState { + let state = Arc::new(DesignerState { tman_config, - tman_internal_config, + tman_metadata, out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); let mut actual_base_dir_opt: Option = Some(base_dir); @@ -138,11 +134,8 @@ pub async fn execute_cmd( } if let Some(actual_base_dir) = actual_base_dir_opt.as_ref() { - // =-=-= - let state_write = state.write().unwrap(); - - let mut pkgs_cache = state_write.pkgs_cache.write().await; - let mut graphs_cache = state_write.graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; get_all_pkgs_in_app( &mut pkgs_cache, diff --git a/core/src/ten_manager/src/cmd/cmd_fetch.rs b/core/src/ten_manager/src/cmd/cmd_fetch.rs index 31141aa91..48f45214e 100644 --- a/core/src/ten_manager/src/cmd/cmd_fetch.rs +++ b/core/src/ten_manager/src/cmd/cmd_fetch.rs @@ -20,7 +20,7 @@ use ten_rust::pkg_info::{ }; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, output::TmanOutput, package_file::unpackage::extract_and_process_tpkg_file, registry::{get_package, get_package_list}, @@ -121,8 +121,8 @@ pub fn parse_sub_cmd(sub_cmd_args: &ArgMatches) -> Result { } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: FetchCommand, out: Arc>, ) -> Result<()> { @@ -135,7 +135,7 @@ pub async fn execute_cmd( // Query the package from the registry. let mut found_packages = get_package_list( - &tman_config, + tman_config.clone(), Some(command_data.pkg_type), Some(command_data.pkg_name.clone()), Some(command_data.version_req.clone()), @@ -157,7 +157,7 @@ pub async fn execute_cmd( let mut temp_file = tempfile::NamedTempFile::new()?; get_package( - tman_config.clone(), + tman_config, &package.basic_info.type_and_name.pkg_type, &package.basic_info.type_and_name.name, &package.basic_info.version, diff --git a/core/src/ten_manager/src/cmd/cmd_install.rs b/core/src/ten_manager/src/cmd/cmd_install.rs index 09d4773af..f9050a1e8 100644 --- a/core/src/ten_manager/src/cmd/cmd_install.rs +++ b/core/src/ten_manager/src/cmd/cmd_install.rs @@ -34,7 +34,7 @@ use ten_rust::pkg_info::{ }; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{is_verbose, metadata::TmanMetadata, TmanConfig}, constants::{APP_DIR_IN_DOT_TEN_DIR, DOT_TEN_DIR}, dep_and_candidate::get_all_candidates_from_deps, fs::{check_is_addon_folder, find_nearest_app_dir}, @@ -282,7 +282,7 @@ ten_package("app_for_standalone") { } fn prepare_basic_standalone_app_dir( - _tman_config: Arc, + _tman_config: Arc>, extension_dir: &Path, ) -> Result { let dot_ten_app_dir = @@ -314,7 +314,7 @@ fn prepare_basic_standalone_app_dir( /// Prepare the `.ten/app/` folder in the extension standalone mode. async fn prepare_standalone_app_dir( - tman_config: Arc, + tman_config: Arc>, extension_dir: &Path, ) -> Result { let dot_ten_app_dir = @@ -330,7 +330,7 @@ async fn prepare_standalone_app_dir( /// Path logic for standalone mode and non-standalone mode. async fn determine_app_dir_to_work_with( - tman_config: Arc, + tman_config: Arc>, standalone: bool, specified_cwd: &Path, ) -> Result { @@ -356,12 +356,12 @@ async fn determine_app_dir_to_work_with( } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: InstallCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Executing install command"); out.normal_line(&format!("command_data: {:?}", command_data)); out.normal_line(&format!("tman_config: {:?}", tman_config)); @@ -446,7 +446,8 @@ pub async fn execute_cmd( tman_config.clone(), &app_dir_to_work_with, out.clone(), - )?; + ) + .await?; out.normal_line(&format!( "{} Filter compatible packages...", @@ -459,7 +460,8 @@ pub async fn execute_cmd( &mut all_compatible_installed_pkgs, &command_data.support, out.clone(), - ); + ) + .await?; if command_data.local_path.is_some() { // tman install @@ -630,22 +632,23 @@ from manifest-lock.json...", &all_candidates, locked_pkgs.as_ref(), out.clone(), - )?; + ) + .await?; // If there are answers are found, print out all the answers. - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("\n"); out.normal_line("Result:"); } if let Some(ref usable_model) = usable_model { for result in usable_model { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!(" {:?}", result)); } } } - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(""); } @@ -676,7 +679,7 @@ from manifest-lock.json...", out.clone(), ); - if has_conflict && !tman_config.assume_yes { + if has_conflict && !tman_config.read().await.assume_yes { if out.is_interactive() { // "y" for continuing to install, "n" for stopping. let ans = Confirm::new( diff --git a/core/src/ten_manager/src/cmd/cmd_modify/cmd_modify_graph.rs b/core/src/ten_manager/src/cmd/cmd_modify/cmd_modify_graph.rs index 1dbd81d02..819d53b61 100644 --- a/core/src/ten_manager/src/cmd/cmd_modify/cmd_modify_graph.rs +++ b/core/src/ten_manager/src/cmd/cmd_modify/cmd_modify_graph.rs @@ -16,7 +16,7 @@ use ten_rust::{ use crate::{ cmd::cmd_modify::jq_util::jq_run, - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, output::TmanOutput, }; @@ -87,8 +87,8 @@ pub fn parse_sub_cmd(sub_cmd_args: &ArgMatches) -> Result { } pub async fn execute_cmd( - _tman_config: Arc, - _tman_internal_config: Arc, + _tman_config: Arc>, + _tman_metadata: Arc>, command_data: ModifyGraphCommand, out: Arc>, ) -> Result<()> { diff --git a/core/src/ten_manager/src/cmd/cmd_modify/mod.rs b/core/src/ten_manager/src/cmd/cmd_modify/mod.rs index 94ced7752..7da862c6e 100644 --- a/core/src/ten_manager/src/cmd/cmd_modify/mod.rs +++ b/core/src/ten_manager/src/cmd/cmd_modify/mod.rs @@ -13,7 +13,7 @@ use anyhow::Result; use clap::{ArgMatches, Command}; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, output::TmanOutput, }; @@ -47,8 +47,8 @@ pub fn parse_sub_cmd(sub_cmd_args: &ArgMatches) -> Result { } pub async fn execute_cmd( - tman_config: Arc, - tman_internal_config: Arc, + tman_config: Arc>, + tman_metadata: Arc>, command_data: ModifyCommandData, out: Arc>, ) -> Result<()> { @@ -56,7 +56,7 @@ pub async fn execute_cmd( ModifyCommandData::ModifyGraph(cmd) => { crate::cmd::cmd_modify::cmd_modify_graph::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) diff --git a/core/src/ten_manager/src/cmd/cmd_package.rs b/core/src/ten_manager/src/cmd/cmd_package.rs index 31e82cd6c..f2d9c009f 100644 --- a/core/src/ten_manager/src/cmd/cmd_package.rs +++ b/core/src/ten_manager/src/cmd/cmd_package.rs @@ -14,7 +14,7 @@ use indicatif::HumanDuration; use ten_rust::pkg_info::get_pkg_info_from_path; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{is_verbose, metadata::TmanMetadata, TmanConfig}, constants::{DOT_TEN_DIR, PACKAGE_DIR_IN_DOT_TEN_DIR}, output::TmanOutput, package_file::{create_package_tar_gz_file, get_tpkg_file_name}, @@ -62,12 +62,12 @@ pub fn parse_sub_cmd( } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: PackageCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Executing package command"); out.normal_line(&format!("{:?}", command_data)); } @@ -120,7 +120,8 @@ pub async fn execute_cmd( &output_path, &cwd, out.clone(), - )?; + ) + .await?; out.normal_line(&format!( "{} Pack package to {:?} in {}", diff --git a/core/src/ten_manager/src/cmd/cmd_publish.rs b/core/src/ten_manager/src/cmd/cmd_publish.rs index 7653ad693..0b98e37ab 100644 --- a/core/src/ten_manager/src/cmd/cmd_publish.rs +++ b/core/src/ten_manager/src/cmd/cmd_publish.rs @@ -14,7 +14,8 @@ use indicatif::HumanDuration; use ten_rust::pkg_info::get_pkg_info_from_path; -use crate::config::internal::TmanInternalConfig; +use crate::config::is_verbose; +use crate::config::metadata::TmanMetadata; use crate::config::TmanConfig; use crate::constants::DOT_TEN_DIR; use crate::constants::PACKAGE_DIR_IN_DOT_TEN_DIR; @@ -42,12 +43,12 @@ pub fn parse_sub_cmd( } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: PublishCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Executing publish command"); out.normal_line(&format!("{:?}", command_data)); } @@ -80,7 +81,8 @@ pub async fn execute_cmd( &output_path, &cwd, out.clone(), - )?; + ) + .await?; upload_package( tman_config.clone(), diff --git a/core/src/ten_manager/src/cmd/cmd_run.rs b/core/src/ten_manager/src/cmd/cmd_run.rs index e86b7ac0e..9b907ad23 100644 --- a/core/src/ten_manager/src/cmd/cmd_run.rs +++ b/core/src/ten_manager/src/cmd/cmd_run.rs @@ -17,7 +17,7 @@ use ten_rust::{ }; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{is_verbose, metadata::TmanMetadata, TmanConfig}, constants::SCRIPTS, output::TmanOutput, }; @@ -65,12 +65,12 @@ pub fn parse_sub_cmd(sub_cmd_args: &ArgMatches) -> Result { } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, cmd: RunCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!("Executing run command: {:?}", cmd)); } @@ -134,7 +134,7 @@ pub async fn execute_cmd( }; // Execute the subprocess. - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "About to run script: {} -> {}", &cmd.script_name, script_cmd diff --git a/core/src/ten_manager/src/cmd/cmd_uninstall.rs b/core/src/ten_manager/src/cmd/cmd_uninstall.rs index cf5443fe6..ccc79b6f3 100644 --- a/core/src/ten_manager/src/cmd/cmd_uninstall.rs +++ b/core/src/ten_manager/src/cmd/cmd_uninstall.rs @@ -19,7 +19,7 @@ use serde_json::from_reader; use ten_rust::pkg_info::constants::TEN_PACKAGES_DIR; use crate::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{is_verbose, metadata::TmanMetadata, TmanConfig}, constants::{ DOT_TEN_DIR, INSTALLED_PATHS_JSON_FILENAME, INSTALL_PATHS_APP_PREFIX, PACKAGE_INFO_DIR_IN_DOT_TEN_DIR, @@ -142,12 +142,12 @@ async fn remove_installed_paths( } pub async fn execute_cmd( - tman_config: Arc, - _tman_internal_config: Arc, + tman_config: Arc>, + _tman_metadata: Arc>, command_data: UninstallCommand, out: Arc>, ) -> Result<()> { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Executing uninstall command"); out.normal_line(&format!("{:?}", command_data)); out.normal_line(&format!("{:?}", tman_config)); diff --git a/core/src/ten_manager/src/cmd/mod.rs b/core/src/ten_manager/src/cmd/mod.rs index 168e2420e..5bb1f4496 100644 --- a/core/src/ten_manager/src/cmd/mod.rs +++ b/core/src/ten_manager/src/cmd/mod.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use anyhow::Result; use super::config::TmanConfig; -use crate::{config::internal::TmanInternalConfig, output::TmanOutput}; +use crate::{config::metadata::TmanMetadata, output::TmanOutput}; pub enum CommandData { Create(self::cmd_create::CreateCommand), @@ -38,8 +38,8 @@ pub enum CommandData { } pub async fn execute_cmd( - tman_config: Arc, - tman_internal_config: Arc, + tman_config: Arc>, + tman_metadata: Arc>, command_data: CommandData, out: Arc>, ) -> Result<()> { @@ -47,7 +47,7 @@ pub async fn execute_cmd( CommandData::Create(cmd) => { crate::cmd::cmd_create::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -56,7 +56,7 @@ pub async fn execute_cmd( CommandData::Install(cmd) => { crate::cmd::cmd_install::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -65,7 +65,7 @@ pub async fn execute_cmd( CommandData::Fetch(cmd) => { crate::cmd::cmd_fetch::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -74,7 +74,7 @@ pub async fn execute_cmd( CommandData::Uninstall(cmd) => { crate::cmd::cmd_uninstall::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -83,7 +83,7 @@ pub async fn execute_cmd( CommandData::Package(cmd) => { crate::cmd::cmd_package::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -92,7 +92,7 @@ pub async fn execute_cmd( CommandData::Publish(cmd) => { crate::cmd::cmd_publish::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -101,7 +101,7 @@ pub async fn execute_cmd( CommandData::Delete(cmd) => { crate::cmd::cmd_delete::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -110,7 +110,7 @@ pub async fn execute_cmd( CommandData::Designer(cmd) => { crate::cmd::cmd_designer::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -119,7 +119,7 @@ pub async fn execute_cmd( CommandData::Check(cmd) => { crate::cmd::cmd_check::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -128,7 +128,7 @@ pub async fn execute_cmd( CommandData::Modify(cmd) => { crate::cmd::cmd_modify::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) @@ -137,7 +137,7 @@ pub async fn execute_cmd( CommandData::Run(cmd) => { crate::cmd::cmd_run::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, cmd, out, ) diff --git a/core/src/ten_manager/src/cmd_line.rs b/core/src/ten_manager/src/cmd_line.rs index 2b26c23d3..60aad832e 100644 --- a/core/src/ten_manager/src/cmd_line.rs +++ b/core/src/ten_manager/src/cmd_line.rs @@ -24,7 +24,7 @@ pub struct ArgsCfg { } pub struct ParsedCmd { - pub tman_config: Arc, + pub tman_config: Arc>, pub command_data: Option, pub show_version: bool, } @@ -179,7 +179,7 @@ pub fn parse_cmd() -> Result { if matches.get_flag("VERSION") { // If `--version` exists, do not parse subcommands. return Ok(ParsedCmd { - tman_config: Arc::new(tman_config), + tman_config: Arc::new(tokio::sync::RwLock::new(tman_config)), command_data: None, show_version: true, }); @@ -231,7 +231,7 @@ pub fn parse_cmd() -> Result { // Return the fully constructed ParsedCmd. Ok(ParsedCmd { - tman_config: Arc::new(tman_config), + tman_config: Arc::new(tokio::sync::RwLock::new(tman_config)), command_data: Some(command_data), show_version: false, }) diff --git a/core/src/ten_manager/src/config/internal.rs b/core/src/ten_manager/src/config/internal.rs deleted file mode 100644 index bb9ef0a3d..000000000 --- a/core/src/ten_manager/src/config/internal.rs +++ /dev/null @@ -1,59 +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. -// -use std::collections::HashMap; -use std::{fs, path::PathBuf}; - -use anyhow::Result; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -use crate::constants::INTERNAL_CONFIG_JSON; - -use super::get_default_home_dir; - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct NodeGeometry { - pub app: Option, - pub extension: String, - - pub x: i64, - pub y: i64, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct GraphGeometry { - pub nodes_geometry: Vec, -} - -#[derive(Debug, Serialize, Deserialize, Default, Clone)] -pub struct GraphUiConfig { - pub graphs_geometry: HashMap, -} - -#[derive(Serialize, Deserialize, Debug, Default, Clone)] -pub struct TmanInternalConfig { - pub graph_ui: GraphUiConfig, -} - -fn get_default_internal_config_path() -> PathBuf { - let mut config_path = get_default_home_dir(); - config_path.push(INTERNAL_CONFIG_JSON); - config_path -} - -// Read the internal configuration from the specified path. -pub fn read_internal_config() -> Result> { - let config_path = get_default_internal_config_path(); - if !config_path.exists() { - return Ok(None); - } - - let config_data = fs::read_to_string(config_path.clone())?; - let config: TmanInternalConfig = serde_json::from_str(&config_data)?; - - Ok(Some(config)) -} diff --git a/core/src/ten_manager/src/config/mod.rs b/core/src/ten_manager/src/config/mod.rs index acebda2e1..bb24c8497 100644 --- a/core/src/ten_manager/src/config/mod.rs +++ b/core/src/ten_manager/src/config/mod.rs @@ -4,11 +4,12 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -pub mod internal; +pub mod metadata; use std::collections::HashMap; use std::fs; use std::path::PathBuf; +use std::sync::Arc; use anyhow::Result; use serde::{Deserialize, Serialize}; @@ -157,3 +158,9 @@ pub fn read_config( Ok(None) } } + +pub async fn is_verbose( + tman_config: Arc>, +) -> bool { + tman_config.read().await.verbose +} diff --git a/core/src/ten_manager/src/constants.rs b/core/src/ten_manager/src/constants.rs index 3b6125171..5d04bafe8 100644 --- a/core/src/ten_manager/src/constants.rs +++ b/core/src/ten_manager/src/constants.rs @@ -78,6 +78,6 @@ pub const TEN_NAME_RULE_PATH: &str = "ten.name"; pub const PACKAGE_CACHE: &str = "package_cache"; pub const CONFIG_JSON: &str = "config.json"; -pub const INTERNAL_CONFIG_JSON: &str = "internal_config.json"; +pub const METADATA_FILE: &str = "metadata.json"; pub const BUF_WRITER_BUF_SIZE: usize = 1024 * 1024; diff --git a/core/src/ten_manager/src/create/mod.rs b/core/src/ten_manager/src/create/mod.rs index 4b78283fb..9d24d4fbf 100644 --- a/core/src/ten_manager/src/create/mod.rs +++ b/core/src/ten_manager/src/create/mod.rs @@ -41,7 +41,7 @@ fn can_package_be_created_in_path( #[allow(clippy::too_many_arguments)] pub async fn create_pkg_in_path( - tman_config: &Arc, + tman_config: Arc>, path: &Path, pkg_type: &PkgType, pkg_name: &String, @@ -62,7 +62,7 @@ pub async fn create_pkg_in_path( // Search for the package in the registry. let mut found_packages = get_package_list( - tman_config, + tman_config.clone(), Some(*pkg_type), Some(template_pkg_name.clone()), Some(template_pkg_version.clone()), @@ -94,7 +94,7 @@ pub async fn create_pkg_in_path( "Failed to create a temporary file for downloading the package", )?; get_package( - tman_config.clone(), + tman_config, &package.basic_info.type_and_name.pkg_type, &package.basic_info.type_and_name.name, &package.basic_info.version, diff --git a/core/src/ten_manager/src/dep_and_candidate/mod.rs b/core/src/ten_manager/src/dep_and_candidate/mod.rs index 6d6f111e2..9d74eef73 100644 --- a/core/src/ten_manager/src/dep_and_candidate/mod.rs +++ b/core/src/ten_manager/src/dep_and_candidate/mod.rs @@ -25,6 +25,7 @@ use ten_rust::pkg_info::{get_pkg_info_from_path, PkgInfo}; use super::config::TmanConfig; use super::registry::get_package_list; +use crate::config::is_verbose; use crate::output::TmanOutput; use crate::registry::pkg_list_cache::{is_superset_of, PackageListCache}; @@ -155,7 +156,7 @@ fn process_local_dependency_to_get_candidate( #[allow(clippy::too_many_arguments)] async fn process_non_local_dependency_to_get_candidate( - tman_config: &Arc, + tman_config: Arc>, support: &ManifestSupport, dependency: &ManifestDependency, all_compatible_installed_pkgs: &HashMap< @@ -201,7 +202,7 @@ async fn process_non_local_dependency_to_get_candidate( // Retrieve all packages from the registry that meet the specified // criteria. let results = get_package_list( - tman_config, + tman_config.clone(), Some(pkg_type_name.pkg_type), Some(pkg_type_name.name.clone()), // With the current design, if there is new information, it will @@ -259,7 +260,7 @@ async fn process_non_local_dependency_to_get_candidate( // the most appropriate one. candidate_pkg_info.compatible_score = compatible_score; - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "=> Found a candidate: {}:{}@{}[{}]", candidate_pkg_info.manifest.type_and_name.pkg_type, @@ -291,7 +292,7 @@ async fn process_non_local_dependency_to_get_candidate( } struct DependenciesContext<'a> { - tman_config: Arc, + tman_config: Arc>, support: &'a ManifestSupport, merged_dependencies: &'a mut HashMap, all_compatible_installed_pkgs: @@ -344,7 +345,7 @@ async fn process_dependencies_to_get_candidates( } process_non_local_dependency_to_get_candidate( - &ctx.tman_config, + ctx.tman_config.clone(), ctx.support, manifest_dep, ctx.all_compatible_installed_pkgs, @@ -417,7 +418,7 @@ fn clean_up_all_candidates( #[allow(clippy::too_many_arguments)] pub async fn get_all_candidates_from_deps( - tman_config: Arc, + tman_config: Arc>, support: &ManifestSupport, mut pkgs_to_be_searched: Vec, extra_dep: Option<&ManifestDependency>, diff --git a/core/src/ten_manager/src/designer/apps/addons.rs b/core/src/ten_manager/src/designer/apps/addons.rs index d48b84ad0..b81ec030a 100644 --- a/core/src/ten_manager/src/designer/apps/addons.rs +++ b/core/src/ten_manager/src/designer/apps/addons.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -108,16 +108,9 @@ fn convert_pkg_info_to_addon( pub async fn get_app_addons_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; // Check if base_dir exists in pkgs_cache. if request_payload.base_dir.is_empty() diff --git a/core/src/ten_manager/src/designer/apps/create.rs b/core/src/ten_manager/src/designer/apps/create.rs index 92e79b3ea..1b502fb15 100644 --- a/core/src/ten_manager/src/designer/apps/create.rs +++ b/core/src/ten_manager/src/designer/apps/create.rs @@ -4,10 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - path::Path, - sync::{Arc, RwLock}, -}; +use std::{path::Path, sync::Arc}; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -40,7 +37,7 @@ pub struct CreateAppResponseData { pub async fn create_app_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { let CreateAppRequestPayload { base_dir, @@ -76,58 +73,24 @@ pub async fn create_app_endpoint( return Ok(HttpResponse::Conflict().json(error_response)); } - let tman_config_clone; - let out_clone; - { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - tman_config, out, .. - } = &*state_read; - - // Clone the values we need - tman_config_clone = tman_config.clone(); - out_clone = out.clone(); - } - // Create app using create_pkg_in_path. match create_pkg_in_path( - &tman_config_clone, + state.tman_config.clone(), Path::new(&base_dir), &PkgType::App, &app_name, &template_name, &VersionReq::default(), None, - &out_clone, + &state.out, ) .await { Ok(_) => { let app_path_str = app_path.to_string_lossy().to_string(); - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Try to load the newly created app into the cache. if let Err(err) = get_all_pkgs_in_app( diff --git a/core/src/ten_manager/src/designer/apps/get.rs b/core/src/ten_manager/src/designer/apps/get.rs index eaa827911..f93ccad7c 100644 --- a/core/src/ten_manager/src/designer/apps/get.rs +++ b/core/src/ten_manager/src/designer/apps/get.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -27,16 +27,9 @@ pub struct GetAppsResponseData { } pub async fn get_apps_endpoint( - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; let response = ApiResponse { status: Status::Ok, diff --git a/core/src/ten_manager/src/designer/apps/load.rs b/core/src/ten_manager/src/designer/apps/load.rs index 8e50659c3..f38c5f283 100644 --- a/core/src/ten_manager/src/designer/apps/load.rs +++ b/core/src/ten_manager/src/designer/apps/load.rs @@ -6,7 +6,7 @@ // use std::collections::HashMap; use std::path::Path; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -32,24 +32,10 @@ pub struct LoadAppResponseData { pub async fn load_app_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; if pkgs_cache.contains_key(&request_payload.base_dir) { let app_uri = extract_app_uri(&pkgs_cache, &request_payload.base_dir); diff --git a/core/src/ten_manager/src/designer/apps/reload.rs b/core/src/ten_manager/src/designer/apps/reload.rs index 6e1088bfa..b67724c4d 100644 --- a/core/src/ten_manager/src/designer/apps/reload.rs +++ b/core/src/ten_manager/src/designer/apps/reload.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use crate::{ designer::{ @@ -26,24 +26,10 @@ pub struct ReloadPkgsRequestPayload { pub async fn reload_app_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; if let Some(base_dir) = &request_payload.base_dir { // Case 1: base_dir is specified in the request payload. diff --git a/core/src/ten_manager/src/designer/apps/schema/mod.rs b/core/src/ten_manager/src/designer/apps/schema/mod.rs index ebe0910cc..6fac02984 100644 --- a/core/src/ten_manager/src/designer/apps/schema/mod.rs +++ b/core/src/ten_manager/src/designer/apps/schema/mod.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -28,16 +28,9 @@ pub struct GetAppSchemaResponseData { pub async fn get_app_schema_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; if let Some(pkgs_info_in_app) = pkgs_cache.get(&request_payload.app_base_dir) diff --git a/core/src/ten_manager/src/designer/apps/scripts.rs b/core/src/ten_manager/src/designer/apps/scripts.rs index 93316f5a0..b0706fdc6 100644 --- a/core/src/ten_manager/src/designer/apps/scripts.rs +++ b/core/src/ten_manager/src/designer/apps/scripts.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -28,16 +28,9 @@ pub struct GetPackagesScriptsResponseData { pub async fn get_app_scripts_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; if let Some(base_dir_pkg_info) = pkgs_cache.get(&request_payload.base_dir) { if let Some(app_pkg) = &base_dir_pkg_info.app_pkg_info { diff --git a/core/src/ten_manager/src/designer/apps/unload.rs b/core/src/ten_manager/src/designer/apps/unload.rs index ea69b7f22..7ca9eb18f 100644 --- a/core/src/ten_manager/src/designer/apps/unload.rs +++ b/core/src/ten_manager/src/designer/apps/unload.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -30,24 +30,10 @@ pub struct UnloadAppResponseData { pub async fn unload_app_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Check if the base_dir exists in pkgs_cache. if !pkgs_cache.contains_key(&request_payload.base_dir) { diff --git a/core/src/ten_manager/src/designer/builtin_function/install.rs b/core/src/ten_manager/src/designer/builtin_function/install.rs index a1f2dbe66..3bb256cc1 100644 --- a/core/src/ten_manager/src/designer/builtin_function/install.rs +++ b/core/src/ten_manager/src/designer/builtin_function/install.rs @@ -50,13 +50,13 @@ impl WsBuiltinFunction { // Clone the tman_config to avoid borrowing self in the async task. let tman_config = self.tman_config.clone(); - let tman_internal_config = self.tman_internal_config.clone(); + let tman_metadata = self.tman_metadata.clone(); // Call `execute_cmd()` in an async task. - tokio::spawn(async move { + tokio::task::spawn_local(async move { let result = crate::cmd::cmd_install::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, install_command, output_ws, ) diff --git a/core/src/ten_manager/src/designer/builtin_function/install_all.rs b/core/src/ten_manager/src/designer/builtin_function/install_all.rs index 7fe064b8f..ad0b7a6c3 100644 --- a/core/src/ten_manager/src/designer/builtin_function/install_all.rs +++ b/core/src/ten_manager/src/designer/builtin_function/install_all.rs @@ -41,13 +41,13 @@ impl WsBuiltinFunction { // Clone the tman_config to avoid borrowing self in the async task. let tman_config = self.tman_config.clone(); - let tman_internal_config = self.tman_internal_config.clone(); + let tman_metadata = self.tman_metadata.clone(); // Call `execute_cmd()` in an async task. - tokio::spawn(async move { + tokio::task::spawn_local(async move { let result = crate::cmd::cmd_install::execute_cmd( tman_config, - tman_internal_config, + tman_metadata, install_command, output_ws, ) diff --git a/core/src/ten_manager/src/designer/builtin_function/mod.rs b/core/src/ten_manager/src/designer/builtin_function/mod.rs index 9e7c94e34..9734088a9 100644 --- a/core/src/ten_manager/src/designer/builtin_function/mod.rs +++ b/core/src/ten_manager/src/designer/builtin_function/mod.rs @@ -8,7 +8,7 @@ mod install; mod install_all; pub mod msg; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix::{Actor, Handler, Message, StreamHandler}; use actix_web::{web, Error, HttpRequest, HttpResponse}; @@ -18,7 +18,7 @@ use anyhow::Result; use msg::InboundMsg; use msg::OutboundMsg; -use crate::config::internal::TmanInternalConfig; +use crate::config::metadata::TmanMetadata; use crate::config::TmanConfig; use crate::designer::DesignerState; @@ -54,20 +54,20 @@ type BuiltinFunctionParser = pub struct WsBuiltinFunction { builtin_function_parser: BuiltinFunctionParser, - tman_config: Arc, - tman_internal_config: Arc, + tman_config: Arc>, + tman_metadata: Arc>, } impl WsBuiltinFunction { fn new( builtin_function_parser: BuiltinFunctionParser, - tman_config: Arc, - tman_internal_config: Arc, + tman_config: Arc>, + tman_metadata: Arc>, ) -> Self { Self { builtin_function_parser, tman_config, - tman_internal_config, + tman_metadata, } } } @@ -199,17 +199,10 @@ impl StreamHandler> pub async fn builtin_function_endpoint( req: HttpRequest, stream: web::Payload, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let tman_config = state_read.tman_config.clone(); - let tman_internal_config = state_read.tman_internal_config.clone(); + let tman_config = state.tman_config.clone(); + let tman_metadata = state.tman_metadata.clone(); let default_parser: BuiltinFunctionParser = Box::new(move |text: &str| { // Attempt to parse the JSON text from client. @@ -235,11 +228,7 @@ pub async fn builtin_function_endpoint( }); ws::start( - WsBuiltinFunction::new( - default_parser, - tman_config, - tman_internal_config, - ), + WsBuiltinFunction::new(default_parser, tman_config, tman_metadata), &req, stream, ) diff --git a/core/src/ten_manager/src/designer/dir_list/mod.rs b/core/src/ten_manager/src/designer/dir_list/mod.rs index 89869212d..6997d45df 100644 --- a/core/src/ten_manager/src/designer/dir_list/mod.rs +++ b/core/src/ten_manager/src/designer/dir_list/mod.rs @@ -6,7 +6,7 @@ // use std::fs; use std::path::Path; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{ error::{ErrorForbidden, ErrorNotFound}, @@ -38,7 +38,7 @@ pub struct DirListResponseData { pub async fn list_dir_endpoint( request_payload: web::Json, - _state: web::Data>>, + _state: web::Data>, ) -> Result { let path = Path::new(&request_payload.path); diff --git a/core/src/ten_manager/src/designer/doc_link/mod.rs b/core/src/ten_manager/src/designer/doc_link/mod.rs index b95c0d214..1a0cfcaf4 100644 --- a/core/src/ten_manager/src/designer/doc_link/mod.rs +++ b/core/src/ten_manager/src/designer/doc_link/mod.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -81,7 +81,7 @@ static DOC_LINKS: OnceLock> = OnceLock::new(); /// JSON payload with a "key" property and returns the corresponding doc link. pub async fn get_doc_link_endpoint( request_payload: web::Json, - _state: web::Data>>, + _state: web::Data>, ) -> Result { let key = &request_payload.key; let locale = &request_payload.locale; diff --git a/core/src/ten_manager/src/designer/env/mod.rs b/core/src/ten_manager/src/designer/env/mod.rs index d65293eda..d5e22b776 100644 --- a/core/src/ten_manager/src/designer/env/mod.rs +++ b/core/src/ten_manager/src/designer/env/mod.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder, Result}; use serde::{Deserialize, Serialize}; @@ -21,7 +21,7 @@ pub struct EnvInfo { } pub async fn get_env_endpoint( - _state: web::Data>>, + _state: web::Data>, ) -> Result { let current_env = ten_rust::env::get_env().map_err(|e| { actix_web::error::ErrorInternalServerError(e.to_string()) diff --git a/core/src/ten_manager/src/designer/exec/mod.rs b/core/src/ten_manager/src/designer/exec/mod.rs index 612f70340..832bab6e3 100644 --- a/core/src/ten_manager/src/designer/exec/mod.rs +++ b/core/src/ten_manager/src/designer/exec/mod.rs @@ -9,7 +9,7 @@ mod msg; mod run_script; use std::process::Child; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix::{Actor, Handler, Message, StreamHandler}; use actix_web::{web, Error, HttpRequest, HttpResponse}; @@ -152,7 +152,7 @@ impl StreamHandler> for WsRunCmd { pub async fn exec_endpoint( req: HttpRequest, stream: web::Payload, - state: web::Data>>, + state: web::Data>, ) -> Result { let state_clone = state.get_ref().clone(); diff --git a/core/src/ten_manager/src/designer/exec/run_script.rs b/core/src/ten_manager/src/designer/exec/run_script.rs index bf45f5433..3b2786b46 100644 --- a/core/src/ten_manager/src/designer/exec/run_script.rs +++ b/core/src/ten_manager/src/designer/exec/run_script.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use anyhow::Result; @@ -13,15 +13,9 @@ use crate::designer::DesignerState; pub async fn extract_command_from_manifest( base_dir: &String, name: &String, - state: Arc>, + state: Arc, ) -> Result { - let state_read = state - .read() - .map_err(|e| anyhow::anyhow!("Failed to acquire read lock: {}", e))?; - - let DesignerState { pkgs_cache, .. } = &*state_read; - - let pkgs_cache = pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; let base_dir_pkg_info = pkgs_cache.get(base_dir).unwrap(); diff --git a/core/src/ten_manager/src/designer/extensions/create.rs b/core/src/ten_manager/src/designer/extensions/create.rs index cc3f4d7b2..31866f088 100644 --- a/core/src/ten_manager/src/designer/extensions/create.rs +++ b/core/src/ten_manager/src/designer/extensions/create.rs @@ -4,10 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - path::Path, - sync::{Arc, RwLock}, -}; +use std::{path::Path, sync::Arc}; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -40,7 +37,7 @@ pub struct CreateExtensionResponseData { pub async fn create_extension_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { let CreateExtensionRequestPayload { base_dir, @@ -76,36 +73,16 @@ pub async fn create_extension_endpoint( return Ok(HttpResponse::Conflict().json(error_response)); } - let tman_config_clone; - let out_clone; - { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - tman_config, out, .. - } = &*state_read; - - // Clone the values we need - tman_config_clone = tman_config.clone(); - out_clone = out.clone(); - } - // Create extension using create_pkg_in_path. match create_pkg_in_path( - &tman_config_clone, + state.tman_config.clone(), Path::new(&base_dir), &PkgType::Extension, &extension_name, &template_name, &VersionReq::default(), None, - &out_clone, + &state.out, ) .await { @@ -113,22 +90,8 @@ pub async fn create_extension_endpoint( let extension_path_str = extension_path.to_string_lossy().to_string(); - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Try to load the newly created extension into the cache. if let Err(err) = get_all_pkgs_in_app( diff --git a/core/src/ten_manager/src/designer/extensions/property.rs b/core/src/ten_manager/src/designer/extensions/property.rs index db6577a02..bbce2a9ed 100644 --- a/core/src/ten_manager/src/designer/extensions/property.rs +++ b/core/src/ten_manager/src/designer/extensions/property.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -30,16 +30,9 @@ pub struct GetExtensionPropertyResponseData { pub async fn get_extension_property_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; // Check if app exists. let pkgs_info_in_app = match pkgs_cache.get(&request_payload.app_base_dir) { diff --git a/core/src/ten_manager/src/designer/extensions/schema.rs b/core/src/ten_manager/src/designer/extensions/schema.rs index cc8253008..f427c2377 100644 --- a/core/src/ten_manager/src/designer/extensions/schema.rs +++ b/core/src/ten_manager/src/designer/extensions/schema.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -30,16 +30,9 @@ pub struct GetExtensionSchemaResponseData { pub async fn get_extension_schema_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; // Check if app exists. let pkgs_info_in_app = match pkgs_cache.get(&request_payload.app_base_dir) { diff --git a/core/src/ten_manager/src/designer/file_content/mod.rs b/core/src/ten_manager/src/designer/file_content/mod.rs index 69c6fc278..abd6d7d2f 100644 --- a/core/src/ten_manager/src/designer/file_content/mod.rs +++ b/core/src/ten_manager/src/designer/file_content/mod.rs @@ -6,7 +6,7 @@ // use std::fs; use std::path::Path; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -28,7 +28,7 @@ struct GetFileContentResponseData { pub async fn get_file_content_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { let file_path = request_payload.file_path.clone(); @@ -42,14 +42,7 @@ pub async fn get_file_content_endpoint( Ok(HttpResponse::Ok().json(response)) } Err(err) => { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - state_read.out.error_line(&format!( + state.out.error_line(&format!( "Error reading file at path {}: {}", file_path, err )); @@ -73,7 +66,7 @@ pub struct SaveFileRequestPayload { pub async fn save_file_content_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { let file_path_str = request_payload.file_path.clone(); let content = &request_payload.content; // Access the content field. @@ -83,14 +76,7 @@ pub async fn save_file_content_endpoint( // Attempt to create parent directories if they don't exist. if let Some(parent) = file_path.parent() { if let Err(e) = fs::create_dir_all(parent) { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - state_read.out.error_line(&format!( + state.out.error_line(&format!( "Error creating directories for {}: {}", parent.display(), e @@ -116,14 +102,7 @@ pub async fn save_file_content_endpoint( Ok(HttpResponse::Ok().json(response)) } Err(err) => { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - state_read.out.error_line(&format!( + state.out.error_line(&format!( "Error writing file at path {}: {}", file_path.display(), err diff --git a/core/src/ten_manager/src/designer/frontend.rs b/core/src/ten_manager/src/designer/frontend.rs index a8b96ec73..a53f48bfd 100644 --- a/core/src/ten_manager/src/designer/frontend.rs +++ b/core/src/ten_manager/src/designer/frontend.rs @@ -4,15 +4,14 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - sync::{Arc, RwLock}, - time::Instant, -}; +use std::{sync::Arc, time::Instant}; use actix_web::{web, HttpRequest, HttpResponse, Responder}; use mime_guess::from_path; use rust_embed::RustEmbed; +use crate::config::is_verbose; + use super::DesignerState; // Points to the frontend build output directory. @@ -22,15 +21,8 @@ struct Asset; pub async fn get_frontend_asset( req: HttpRequest, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - let start_time = Instant::now(); let path = req.path().trim_start_matches('/').to_owned(); let client_ip = req @@ -39,7 +31,7 @@ pub async fn get_frontend_asset( .unwrap_or("unknown") .to_string(); - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!( "[FRONTEND ASSET] Request from IP: {}, Path: '{}'", client_ip, path @@ -52,7 +44,7 @@ pub async fn get_frontend_asset( Some(content) => { let size = content.data.len(); - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!("[FRONTEND ASSET] Serving index.html, size: {} bytes, time: {:?}", size, start_time.elapsed()); } Ok(HttpResponse::Ok() @@ -60,7 +52,7 @@ pub async fn get_frontend_asset( .body(content.data.into_owned())) } None => { - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!("[FRONTEND ASSET] ERROR: index.html not found!"); } @@ -73,7 +65,7 @@ pub async fn get_frontend_asset( let mime = from_path(&path).first_or_octet_stream(); let size = content.data.len(); - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!("[FRONTEND ASSET] Serving: '{}', type: {}, size: {} bytes, time: {:?}", path, mime.as_ref(), size, start_time.elapsed()); } @@ -85,7 +77,7 @@ pub async fn get_frontend_asset( // If the file is not found, return `index.html` to support React // Router. None => { - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!("[FRONTEND ASSET] Asset '{}' not found, falling back to index.html (SPA mode)", path); } @@ -93,7 +85,7 @@ pub async fn get_frontend_asset( Some(content) => { let size = content.data.len(); - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!("[FRONTEND ASSET] Serving index.html (fallback), size: {} bytes, time: {:?}", size, start_time.elapsed()); } @@ -103,7 +95,7 @@ pub async fn get_frontend_asset( .body(content.data.into_owned())) } None => { - if state_read.tman_config.verbose { + if is_verbose(state.tman_config.clone()).await { println!("[FRONTEND ASSET] ERROR: index.html fallback not found!"); } diff --git a/core/src/ten_manager/src/designer/graphs/connections/add.rs b/core/src/ten_manager/src/designer/graphs/connections/add.rs index a6dfbf5a2..dcc9a7d8b 100644 --- a/core/src/ten_manager/src/designer/graphs/connections/add.rs +++ b/core/src/ten_manager/src/designer/graphs/connections/add.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -120,23 +120,10 @@ fn update_property_file( pub async fn add_graph_connection_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( @@ -163,7 +150,7 @@ pub async fn add_graph_connection_endpoint( request_payload.msg_name.clone(), request_payload.dest_app.clone(), request_payload.dest_extension.clone(), - &mut pkgs_cache, + &pkgs_cache, request_payload.msg_conversion.clone(), ) { let error_response = ErrorResponse { diff --git a/core/src/ten_manager/src/designer/graphs/connections/delete.rs b/core/src/ten_manager/src/designer/graphs/connections/delete.rs index 2cf8cbccc..d46868a8c 100644 --- a/core/src/ten_manager/src/designer/graphs/connections/delete.rs +++ b/core/src/ten_manager/src/designer/graphs/connections/delete.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -141,24 +141,11 @@ fn delete_connection( pub async fn delete_graph_connection_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { // Get a write lock on the state since we need to modify the graph. - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( diff --git a/core/src/ten_manager/src/designer/graphs/connections/get.rs b/core/src/ten_manager/src/designer/graphs/connections/get.rs index d4f6958b6..c7649e5a1 100644 --- a/core/src/ten_manager/src/designer/graphs/connections/get.rs +++ b/core/src/ten_manager/src/designer/graphs/connections/get.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -103,16 +103,9 @@ impl From for GraphConnection { pub async fn get_graph_connections_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let graphs_cache = state_read.graphs_cache.read().await; + let graphs_cache = state.graphs_cache.read().await; // Look up the graph directly by UUID from graphs_cache if let Some(graph_info) = graphs_cache.get(&request_payload.graph_id) { diff --git a/core/src/ten_manager/src/designer/graphs/connections/msg_conversion/update.rs b/core/src/ten_manager/src/designer/graphs/connections/msg_conversion/update.rs index 86d2895a3..ede60c2d0 100644 --- a/core/src/ten_manager/src/designer/graphs/connections/msg_conversion/update.rs +++ b/core/src/ten_manager/src/designer/graphs/connections/msg_conversion/update.rs @@ -4,10 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -188,24 +185,10 @@ pub async fn update_graph_connection_msg_conversion_endpoint( request_payload: web::Json< UpdateGraphConnectionMsgConversionRequestPayload, >, - state: web::Data>>, + state: web::Data>, ) -> Result { - // Get a write lock on the state since we may need to modify the graph. - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( @@ -225,7 +208,7 @@ pub async fn update_graph_connection_msg_conversion_endpoint( // Validate connection schema first. if let Err(e) = validate_connection_schema( - &mut pkgs_cache, + &pkgs_cache, &mut graph_info.graph, &graph_info.app_base_dir, &MsgConversionValidateInfo { diff --git a/core/src/ten_manager/src/designer/graphs/get.rs b/core/src/ten_manager/src/designer/graphs/get.rs index c5b1ae1e8..9f04495de 100644 --- a/core/src/ten_manager/src/designer/graphs/get.rs +++ b/core/src/ten_manager/src/designer/graphs/get.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -27,16 +27,9 @@ pub struct GetGraphsResponseData { pub async fn get_graphs_endpoint( _request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let graphs_cache = state_read.graphs_cache.read().await; + let graphs_cache = state.graphs_cache.read().await; let graphs: Vec = graphs_cache .iter() diff --git a/core/src/ten_manager/src/designer/graphs/nodes/add.rs b/core/src/ten_manager/src/designer/graphs/nodes/add.rs index deddf0934..e53646cda 100644 --- a/core/src/ten_manager/src/designer/graphs/nodes/add.rs +++ b/core/src/ten_manager/src/designer/graphs/nodes/add.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -46,24 +46,11 @@ pub struct AddGraphNodeResponsePayload { pub async fn add_graph_node_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { // Get a write lock on the state since we need to modify the graph. - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( diff --git a/core/src/ten_manager/src/designer/graphs/nodes/delete.rs b/core/src/ten_manager/src/designer/graphs/nodes/delete.rs index 7b7580e42..8ddbfc25b 100644 --- a/core/src/ten_manager/src/designer/graphs/nodes/delete.rs +++ b/core/src/ten_manager/src/designer/graphs/nodes/delete.rs @@ -5,7 +5,7 @@ // Refer to the "LICENSE" file in the root directory for more information. // use std::collections::HashMap; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -139,24 +139,11 @@ pub fn graph_delete_extension_node( pub async fn delete_graph_node_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { // Get a write lock on the state since we need to modify the graph. - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( diff --git a/core/src/ten_manager/src/designer/graphs/nodes/get.rs b/core/src/ten_manager/src/designer/graphs/nodes/get.rs index 3665e9962..ac837db22 100644 --- a/core/src/ten_manager/src/designer/graphs/nodes/get.rs +++ b/core/src/ten_manager/src/designer/graphs/nodes/get.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::{anyhow, Result}; @@ -93,23 +93,10 @@ impl From for GraphNode { /// Retrieve graph nodes for a specific graph. pub async fn get_graph_nodes_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &*state_read; - - let pkgs_cache = pkgs_cache.read().await; - let graphs_cache = graphs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; + let graphs_cache = state.graphs_cache.read().await; let graph_id = &request_payload.graph_id; diff --git a/core/src/ten_manager/src/designer/graphs/nodes/property/update.rs b/core/src/ten_manager/src/designer/graphs/nodes/property/update.rs index fea318829..081ff7fab 100644 --- a/core/src/ten_manager/src/designer/graphs/nodes/property/update.rs +++ b/core/src/ten_manager/src/designer/graphs/nodes/property/update.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -73,24 +73,11 @@ fn update_node_property_in_graph( pub async fn update_graph_node_property_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { // Get a write lock on the state since we need to modify the graph. - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( diff --git a/core/src/ten_manager/src/designer/graphs/nodes/replace.rs b/core/src/ten_manager/src/designer/graphs/nodes/replace.rs index 6693a5208..468b7010a 100644 --- a/core/src/ten_manager/src/designer/graphs/nodes/replace.rs +++ b/core/src/ten_manager/src/designer/graphs/nodes/replace.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -39,24 +39,11 @@ pub struct ReplaceGraphNodeResponsePayload { pub async fn replace_graph_node_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { // Get a write lock on the state since we need to modify the graph. - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Get the specified graph from graphs_cache. let graph_info = match graphs_cache_find_by_id_mut( @@ -80,7 +67,7 @@ pub async fn replace_graph_node_endpoint( &request_payload.app, &request_payload.addon, &graph_info.app_base_dir, - &mut pkgs_cache, + &pkgs_cache, ) { let error_response = ErrorResponse { status: Status::Fail, diff --git a/core/src/ten_manager/src/designer/graphs/update.rs b/core/src/ten_manager/src/designer/graphs/update.rs index 9fe826f3c..a266f8fed 100644 --- a/core/src/ten_manager/src/designer/graphs/update.rs +++ b/core/src/ten_manager/src/designer/graphs/update.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -64,23 +64,10 @@ pub struct UpdateGraphResponseData { pub async fn update_graph_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &mut *state_write; - - let mut pkgs_cache = pkgs_cache.write().await; - let mut graphs_cache = graphs_cache.write().await; + let mut pkgs_cache = state.pkgs_cache.write().await; + let mut graphs_cache = state.graphs_cache.write().await; // Convert GraphNodeForUpdate to GraphNode let graph_nodes: Vec = request_payload diff --git a/core/src/ten_manager/src/designer/help_text/mod.rs b/core/src/ten_manager/src/designer/help_text/mod.rs index 68491ea64..978998c46 100644 --- a/core/src/ten_manager/src/designer/help_text/mod.rs +++ b/core/src/ten_manager/src/designer/help_text/mod.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -77,7 +77,7 @@ static HELP_TEXTS: OnceLock> = OnceLock::new(); /// JSON payload with a "key" property and returns the corresponding help text. pub async fn get_help_text_endpoint( request_payload: web::Json, - _state: web::Data>>, + _state: web::Data>, ) -> Result { let key = &request_payload.key; let locale = &request_payload.locale; diff --git a/core/src/ten_manager/src/designer/internal_config/graph_ui/get.rs b/core/src/ten_manager/src/designer/internal_config/graph_ui/get.rs deleted file mode 100644 index 4c4fa7b61..000000000 --- a/core/src/ten_manager/src/designer/internal_config/graph_ui/get.rs +++ /dev/null @@ -1,53 +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. -// -use std::sync::{Arc, RwLock}; - -use actix_web::{web, HttpResponse, Responder}; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -use crate::config::internal::GraphGeometry; -use crate::designer::response::{ApiResponse, Status}; -use crate::designer::DesignerState; - -#[derive(Debug, Serialize, Deserialize)] -pub struct GetGraphUiRequestPayload { - pub graph_id: Uuid, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct GetGraphUiResponseData { - #[serde(skip_serializing_if = "Option::is_none")] - pub graph_geometry: Option, -} - -pub async fn get_graph_ui_endpoint( - request_payload: web::Json, - state: web::Data>>, -) -> Result { - let graph_id = request_payload.graph_id; - - let state_read = state.read().unwrap(); - - // Look for the graph geometry with the given graph_id. - let graph_geometry = state_read - .tman_internal_config - .graph_ui - .graphs_geometry - .get(&graph_id) - .cloned(); - - let response_data = GetGraphUiResponseData { graph_geometry }; - - let response = ApiResponse { - status: Status::Ok, - data: response_data, - meta: None, - }; - - Ok(HttpResponse::Ok().json(response)) -} diff --git a/core/src/ten_manager/src/designer/internal_config/graph_ui/mod.rs b/core/src/ten_manager/src/designer/internal_config/graph_ui/mod.rs deleted file mode 100644 index 6866b1741..000000000 --- a/core/src/ten_manager/src/designer/internal_config/graph_ui/mod.rs +++ /dev/null @@ -1,8 +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. -// -pub mod get; -pub mod set; diff --git a/core/src/ten_manager/src/designer/internal_config/graph_ui/set.rs b/core/src/ten_manager/src/designer/internal_config/graph_ui/set.rs deleted file mode 100644 index 463a87574..000000000 --- a/core/src/ten_manager/src/designer/internal_config/graph_ui/set.rs +++ /dev/null @@ -1,59 +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. -// -use std::sync::{Arc, RwLock}; - -use actix_web::{web, HttpResponse, Responder}; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -use crate::config::internal::GraphGeometry; -use crate::designer::response::{ApiResponse, Status}; -use crate::designer::DesignerState; - -#[derive(Debug, Serialize, Deserialize)] -pub struct SetGraphUiRequestPayload { - pub graph_id: Uuid, - pub graph_geometry: GraphGeometry, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SetGraphUiResponseData { - pub success: bool, -} - -pub async fn set_graph_ui_endpoint( - request_payload: web::Json, - state: web::Data>>, -) -> Result { - let mut state_write = state.write().unwrap(); - - // Extract the payload data. - let payload = request_payload.into_inner(); - let graph_id = payload.graph_id; - let graph_geometry = payload.graph_geometry; - - let internal_config = Arc::get_mut(&mut state_write.tman_internal_config) - .ok_or_else(|| { - actix_web::error::ErrorInternalServerError( - "Failed to get mutable TmanInternalConfig", - ) - })?; - - internal_config - .graph_ui - .graphs_geometry - .insert(graph_id, graph_geometry); - - let response_data = SetGraphUiResponseData { success: true }; - let response = ApiResponse { - status: Status::Ok, - data: response_data, - meta: None, - }; - - Ok(HttpResponse::Ok().json(response)) -} diff --git a/core/src/ten_manager/src/designer/internal_config/mod.rs b/core/src/ten_manager/src/designer/internal_config/mod.rs deleted file mode 100644 index ac396131c..000000000 --- a/core/src/ten_manager/src/designer/internal_config/mod.rs +++ /dev/null @@ -1,7 +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. -// -pub mod graph_ui; diff --git a/core/src/ten_manager/src/designer/manifest/validate.rs b/core/src/ten_manager/src/designer/manifest/validate.rs index 95b1e18e6..7281b30ba 100644 --- a/core/src/ten_manager/src/designer/manifest/validate.rs +++ b/core/src/ten_manager/src/designer/manifest/validate.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, Responder}; use anyhow::Result; @@ -29,7 +29,7 @@ pub struct ValidateManifestResponseData { pub async fn validate_manifest_endpoint( request_payload: web::Json, - _state: web::Data>>, + _state: web::Data>, ) -> Result { let manifest_json_str = &request_payload.manifest_json_str; diff --git a/core/src/ten_manager/src/designer/messages/compatible.rs b/core/src/ten_manager/src/designer/messages/compatible.rs index b4671815c..db7e819c6 100644 --- a/core/src/ten_manager/src/designer/messages/compatible.rs +++ b/core/src/ten_manager/src/designer/messages/compatible.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use anyhow::Result; @@ -114,23 +114,10 @@ fn get_extension_graph_node<'a>( pub async fn get_compatible_messages_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let DesignerState { - pkgs_cache, - graphs_cache, - .. - } = &*state_read; - - let pkgs_cache = pkgs_cache.read().await; - let graphs_cache = graphs_cache.read().await; + let pkgs_cache = state.pkgs_cache.read().await; + let graphs_cache = state.graphs_cache.read().await; let graph_info = graphs_cache.get(&request_payload.graph_id); let app_base_dir_of_graph = match graph_info { diff --git a/core/src/ten_manager/src/designer/mod.rs b/core/src/ten_manager/src/designer/mod.rs index 3b0655733..7f11364ba 100644 --- a/core/src/ten_manager/src/designer/mod.rs +++ b/core/src/ten_manager/src/designer/mod.rs @@ -16,10 +16,10 @@ pub mod file_content; pub mod frontend; pub mod graphs; pub mod help_text; -pub mod internal_config; pub mod locale; pub mod manifest; pub mod messages; +pub mod metadata; pub mod preferences; pub mod property; pub mod registry; @@ -28,10 +28,7 @@ pub mod template_pkgs; pub mod terminal; pub mod version; -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::web; use uuid::Uuid; @@ -40,12 +37,12 @@ use ten_rust::{ base_dir_pkg_info::PkgsInfoInApp, graph::graph_info::GraphInfo, }; -use crate::config::{internal::TmanInternalConfig, TmanConfig}; +use crate::config::{metadata::TmanMetadata, TmanConfig}; use crate::output::TmanOutput; pub struct DesignerState { - pub tman_config: Arc, - pub tman_internal_config: Arc, + pub tman_config: Arc>, + pub tman_metadata: Arc>, pub out: Arc>, pub pkgs_cache: tokio::sync::RwLock>, pub graphs_cache: tokio::sync::RwLock>, @@ -53,7 +50,7 @@ pub struct DesignerState { pub fn configure_routes( cfg: &mut web::ServiceConfig, - state: web::Data>>, + state: web::Data>, ) { cfg.service( web::scope("/api/designer/v1") @@ -192,11 +189,11 @@ pub fn configure_routes( // Internal config endpoints. .route( "/internal-config/graph-ui/set", - web::post().to(internal_config::graph_ui::set::set_graph_ui_endpoint), + web::post().to(metadata::graph_ui::set::set_graph_ui_endpoint), ) .route( "/internal-config/graph-ui/get", - web::post().to(internal_config::graph_ui::get::get_graph_ui_endpoint), + web::post().to(metadata::graph_ui::get::get_graph_ui_endpoint), ) // File system endpoints. .route("/dir-list", web::post().to(dir_list::list_dir_endpoint)) diff --git a/core/src/ten_manager/src/designer/preferences/get.rs b/core/src/ten_manager/src/designer/preferences/get.rs index b8acb1915..0cb2eb9b9 100644 --- a/core/src/ten_manager/src/designer/preferences/get.rs +++ b/core/src/ten_manager/src/designer/preferences/get.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use crate::designer::response::{ApiResponse, Status}; use crate::designer::DesignerState; @@ -20,16 +20,9 @@ pub struct GetPreferencesResponseData { /// Get the full content of designer frontend preferences. pub async fn get_preferences_endpoint( - state: web::Data>>, + state: web::Data>, ) -> Result { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - let preferences = state_read.tman_config.designer.clone(); + let preferences = state.tman_config.read().await.designer.clone(); let response_data = GetPreferencesResponseData { preferences }; let response = ApiResponse { diff --git a/core/src/ten_manager/src/designer/preferences/update.rs b/core/src/ten_manager/src/designer/preferences/update.rs index 8dc0daf03..b90bca9e3 100644 --- a/core/src/ten_manager/src/designer/preferences/update.rs +++ b/core/src/ten_manager/src/designer/preferences/update.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -24,35 +24,24 @@ pub struct UpdatePreferencesRequestPayload { /// Update the full content of designer frontend preferences. pub async fn update_preferences_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - // Validate against schema. // Convert Designer to Value for validation. + let mut tman_config = state.tman_config.write().await; + let preferences_value = serde_json::to_value(&request_payload.preferences) .map_err(actix_web::error::ErrorBadRequest)?; + + // Validate against schema. if let Err(e) = validate_designer_config(&preferences_value) { return Err(actix_web::error::ErrorBadRequest(e.to_string())); } - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let tman_config = - Arc::get_mut(&mut state_write.tman_config).ok_or_else(|| { - actix_web::error::ErrorInternalServerError( - "Failed to get mutable TmanConfig", - ) - })?; - // Update designer field. tman_config.designer = request_payload.preferences.clone(); // Save to config file - save_config_to_file(tman_config)?; + save_config_to_file(&mut tman_config)?; let response = ApiResponse { status: Status::Ok, diff --git a/core/src/ten_manager/src/designer/preferences/update_field.rs b/core/src/ten_manager/src/designer/preferences/update_field.rs index cc7685162..f47ce7cd5 100644 --- a/core/src/ten_manager/src/designer/preferences/update_field.rs +++ b/core/src/ten_manager/src/designer/preferences/update_field.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -25,21 +25,9 @@ pub struct UpdatePreferencesFieldRequestPayload { /// Update a specific field in designer frontend preferences. pub async fn update_preferences_field_endpoint( request_payload: web::Json, - state: web::Data>>, + state: web::Data>, ) -> Result { - let mut state_write = state.write().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire write lock: {}", - e - )) - })?; - - let tman_config = - Arc::get_mut(&mut state_write.tman_config).ok_or_else(|| { - actix_web::error::ErrorInternalServerError( - "Failed to get mutable TmanConfig", - ) - })?; + let mut tman_config = state.tman_config.write().await; // Update specific field in designer frontend preferences. let mut designer_value = serde_json::to_value(&tman_config.designer) @@ -65,7 +53,7 @@ pub async fn update_preferences_field_endpoint( .map_err(actix_web::error::ErrorBadRequest)?; // Save to config file. - save_config_to_file(tman_config)?; + save_config_to_file(&mut tman_config)?; let response = ApiResponse { status: Status::Ok, diff --git a/core/src/ten_manager/src/designer/property/validate.rs b/core/src/ten_manager/src/designer/property/validate.rs index 05a04a305..cdbce416e 100644 --- a/core/src/ten_manager/src/designer/property/validate.rs +++ b/core/src/ten_manager/src/designer/property/validate.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, Responder}; use anyhow::Result; @@ -29,7 +29,7 @@ pub struct ValidatePropertyResponseData { pub async fn validate_property_endpoint( request_payload: web::Json, - _state: web::Data>>, + _state: web::Data>, ) -> Result { let property_json_str = &request_payload.property_json_str; diff --git a/core/src/ten_manager/src/designer/registry/packages.rs b/core/src/ten_manager/src/designer/registry/packages.rs index 733b0d3b5..9af8ed4f1 100644 --- a/core/src/ten_manager/src/designer/registry/packages.rs +++ b/core/src/ten_manager/src/designer/registry/packages.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use semver::VersionReq; @@ -46,28 +46,8 @@ pub struct GetPackagesResponseData { pub async fn get_packages_endpoint( request_query: web::Query, - state: web::Data>>, + state: web::Data>, ) -> Result { - let tman_config_clone; - let out_clone; - { - let state_read = state.read().map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - })?; - - // Destructure to avoid multiple mutable borrows. - let DesignerState { - tman_config, out, .. - } = &*state_read; - - // Clone the values we need - tman_config_clone = tman_config.clone(); - out_clone = out.clone(); - } - // Parse version requirement if provided. let version_req = if let Some(version_req_str) = &request_query.version_req { @@ -87,13 +67,13 @@ pub async fn get_packages_endpoint( // Call the registry function to get package list with optional parameters. match registry::get_package_list( - &tman_config_clone, + state.tman_config.clone(), request_query.pkg_type, request_query.name.clone(), version_req, request_query.page_size, request_query.page, - &out_clone, + &state.out, ) .await { diff --git a/core/src/ten_manager/src/designer/version/mod.rs b/core/src/ten_manager/src/designer/version/mod.rs index 7c6e4a7d2..fca44eec4 100644 --- a/core/src/ten_manager/src/designer/version/mod.rs +++ b/core/src/ten_manager/src/designer/version/mod.rs @@ -4,7 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; @@ -32,7 +32,7 @@ struct CheckUpdateResponseData { } pub async fn get_version_endpoint( - _state: web::Data>>, + _state: web::Data>, ) -> Result { let version_info = GetVersionResponseData { version: VERSION.to_string(), diff --git a/core/src/ten_manager/src/install/mod.rs b/core/src/ten_manager/src/install/mod.rs index 1a9832c7a..69e725ffc 100644 --- a/core/src/ten_manager/src/install/mod.rs +++ b/core/src/ten_manager/src/install/mod.rs @@ -29,6 +29,7 @@ use ten_rust::pkg_info::{ use super::{config::TmanConfig, registry::get_package}; use crate::{ cmd::cmd_install::{InstallCommand, LocalInstallMode}, + config::is_verbose, fs::copy_folder_recursively, manifest_lock::{ parse_manifest_lock_in_folder, write_pkg_lockfile, ManifestLock, @@ -130,7 +131,7 @@ fn install_local_dependency_pkg_info( } async fn install_non_local_dependency_pkg_info( - tman_config: Arc, + tman_config: Arc>, pkg_info: &PkgInfo, dest_dir_path: &String, out: Arc>, @@ -172,14 +173,14 @@ async fn install_non_local_dependency_pkg_info( } pub async fn install_pkg_info( - tman_config: Arc, + tman_config: Arc>, command_data: &InstallCommand, pkg_info: &PkgInfo, base_dir: &Path, out: Arc>, ) -> Result<()> { if pkg_info.is_installed { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "{}:{} has already been installed.", get_pkg_type(pkg_info), @@ -431,8 +432,8 @@ pub fn write_installing_pkg_into_manifest_file( /// Filter out the packages in `all_pkgs` that meet the current environment's /// requirements and treat them as candidates. -pub fn filter_compatible_pkgs_to_candidates( - tman_config: Arc, +pub async fn filter_compatible_pkgs_to_candidates( + tman_config: Arc>, all_pkgs: &Vec, all_candidates: &mut HashMap< PkgTypeAndName, @@ -440,9 +441,9 @@ pub fn filter_compatible_pkgs_to_candidates( >, support: &ManifestSupport, out: Arc>, -) { +) -> Result<()> { for existed_pkg in all_pkgs.to_owned().iter_mut() { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "Check support score for {:?}", existed_pkg @@ -457,7 +458,7 @@ pub fn filter_compatible_pkgs_to_candidates( if compatible_score >= 0 { existed_pkg.compatible_score = compatible_score; - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "The existed {} package {} is compatible with the current system.", get_pkg_type(existed_pkg), @@ -472,7 +473,7 @@ pub fn filter_compatible_pkgs_to_candidates( } else { // The existed package is not compatible with the current system, so // it should not be considered as a candidate. - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "The existed {} package {} is not compatible with the current \ system.", @@ -482,6 +483,8 @@ pub fn filter_compatible_pkgs_to_candidates( } } } + + Ok(()) } fn get_supports_str(pkg: &PkgInfo) -> String { diff --git a/core/src/ten_manager/src/main.rs b/core/src/ten_manager/src/main.rs index af42c4ea4..cd240a4aa 100644 --- a/core/src/ten_manager/src/main.rs +++ b/core/src/ten_manager/src/main.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use console::Emoji; use ten_manager::cmd::execute_cmd; -use ten_manager::config::internal::TmanInternalConfig; +use ten_manager::config::metadata::TmanMetadata; use tokio::runtime::Runtime; use ten_manager::cmd_line; @@ -62,7 +62,7 @@ fn main() { let rt = Runtime::new().unwrap(); let result = rt.block_on(execute_cmd( parsed_cmd.tman_config, - Arc::new(TmanInternalConfig::default()), + Arc::new(tokio::sync::RwLock::new(TmanMetadata::default())), parsed_cmd.command_data.unwrap(), out.clone(), )); diff --git a/core/src/ten_manager/src/package_file/mod.rs b/core/src/ten_manager/src/package_file/mod.rs index 815bda61f..e9686496f 100644 --- a/core/src/ten_manager/src/package_file/mod.rs +++ b/core/src/ten_manager/src/package_file/mod.rs @@ -22,6 +22,7 @@ use ten_rust::pkg_info::{ }; use super::{config::TmanConfig, constants::TEN_PACKAGE_FILE_EXTENSION}; +use crate::config::is_verbose; use crate::output::TmanOutput; use crate::{constants::DOT_TEN_DIR, fs::pathbuf_to_string_lossy}; use package::tar_gz_files_to_file; @@ -39,8 +40,8 @@ pub fn get_tpkg_file_name(pkg_info: &PkgInfo) -> Result { Ok(output_pkg_file_name) } -pub fn create_package_tar_gz_file( - tman_config: Arc, +pub async fn create_package_tar_gz_file( + tman_config: Arc>, output_pkg_file_path: &Path, folder_to_tar_gz: &Path, out: Arc>, @@ -145,7 +146,7 @@ pub fn create_package_tar_gz_file( } } - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Files to be packed:"); for file in &files_to_include { out.normal_line(&format!("> {:?}", file)); diff --git a/core/src/ten_manager/src/pkg_info/mod.rs b/core/src/ten_manager/src/pkg_info/mod.rs index c28ac1351..53c14d3f3 100644 --- a/core/src/ten_manager/src/pkg_info/mod.rs +++ b/core/src/ten_manager/src/pkg_info/mod.rs @@ -11,7 +11,10 @@ use std::{collections::HashMap, path::Path, sync::Arc}; use anyhow::{anyhow, Result}; -use crate::{config::TmanConfig, output::TmanOutput}; +use crate::{ + config::{is_verbose, TmanConfig}, + output::TmanOutput, +}; use ten_rust::{ base_dir_pkg_info::PkgsInfoInApp, graph::graph_info::GraphInfo, @@ -20,8 +23,8 @@ use ten_rust::{ /// Retrieves information about all installed packages for the specified /// application. -pub fn tman_get_all_installed_pkgs_info_of_app( - tman_config: Arc, +pub async fn tman_get_all_installed_pkgs_info_of_app( + tman_config: Arc>, app_path: &Path, out: Arc>, ) -> Result> { @@ -30,7 +33,7 @@ pub fn tman_get_all_installed_pkgs_info_of_app( // Use the to_vec method to combine all package types into a single vector. let all_pkgs = pkg_info_struct.to_vec(); - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!("{:?}", all_pkgs)); } Ok(all_pkgs) diff --git a/core/src/ten_manager/src/registry/local.rs b/core/src/ten_manager/src/registry/local.rs index bb5078b75..2d03bea88 100644 --- a/core/src/ten_manager/src/registry/local.rs +++ b/core/src/ten_manager/src/registry/local.rs @@ -29,7 +29,7 @@ use super::found_result::{ get_pkg_registry_info_from_manifest, PkgRegistryInfo, }; use super::pkg_cache::{find_in_package_cache, store_file_to_package_cache}; -use crate::config::TmanConfig; +use crate::config::{is_verbose, TmanConfig}; use crate::constants::{ DEFAULT_REGISTRY_PAGE_SIZE, TEN_PACKAGE_FILE_EXTENSION, }; @@ -161,7 +161,7 @@ fn is_same_file_by_hash( } pub async fn get_package( - tman_config: Arc, + tman_config: Arc>, pkg_type: &PkgType, pkg_name: &str, pkg_version: &Version, @@ -190,7 +190,7 @@ pub async fn get_package( if let Ok(true) = is_same_file_by_hash(&cached_file_path, url) { // If the content is the same, directly copy the cached file to // `temp_path`. - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "{} Found the package file ({}) in the package cache, using it directly.", Emoji("🚀", ":-)"), @@ -231,7 +231,7 @@ pub async fn get_package( fs::copy(&path_url, temp_path.path())?; - if tman_config.enable_package_cache { + if tman_config.read().await.enable_package_cache { // Place the downloaded file into the cache. store_file_to_package_cache( pkg_type, @@ -475,7 +475,7 @@ fn search_versions( #[allow(clippy::too_many_arguments)] pub async fn get_package_list( - _tman_config: &Arc, + _tman_config: Arc>, base_url: &str, pkg_type: Option, name: Option, diff --git a/core/src/ten_manager/src/registry/mod.rs b/core/src/ten_manager/src/registry/mod.rs index 1fc56eec0..fe6e446cb 100644 --- a/core/src/ten_manager/src/registry/mod.rs +++ b/core/src/ten_manager/src/registry/mod.rs @@ -24,12 +24,14 @@ use super::constants::DEFAULT; use crate::output::TmanOutput; pub async fn upload_package( - tman_config: Arc, + tman_config: Arc>, package_file_path: &str, pkg_info: &PkgInfo, out: Arc>, ) -> Result { let default_registry_url = tman_config + .read() + .await .registry .get(DEFAULT) .ok_or_else(|| anyhow!("Default registry not found"))? @@ -69,7 +71,7 @@ pub async fn upload_package( } pub async fn get_package( - tman_config: Arc, + tman_config: Arc>, pkg_type: &PkgType, pkg_name: &str, pkg_version: &Version, @@ -135,7 +137,7 @@ pub async fn get_package( /// supported). /// * If there's an error retrieving the package list from the registry. pub async fn get_package_list( - tman_config: &Arc, + tman_config: Arc>, pkg_type: Option, name: Option, version_req: Option, @@ -145,6 +147,8 @@ pub async fn get_package_list( ) -> Result> { // Retrieve the default registry URL from configuration. let default_registry_url = tman_config + .read() + .await .registry .get(DEFAULT) .ok_or_else(|| anyhow!("Default registry not found"))? @@ -195,7 +199,7 @@ pub async fn get_package_list( } pub async fn delete_package( - tman_config: Arc, + tman_config: Arc>, pkg_type: PkgType, name: &String, version: &Version, @@ -204,6 +208,8 @@ pub async fn delete_package( ) -> Result<()> { // Retrieve the default registry URL. let default_registry_url = tman_config + .read() + .await .registry .get(DEFAULT) .ok_or_else(|| anyhow!("Default registry not found"))? diff --git a/core/src/ten_manager/src/registry/remote.rs b/core/src/ten_manager/src/registry/remote.rs index 48cbe35f0..13765cf02 100644 --- a/core/src/ten_manager/src/registry/remote.rs +++ b/core/src/ten_manager/src/registry/remote.rs @@ -23,6 +23,7 @@ use tokio::time::sleep; use ten_rust::pkg_info::PkgInfo; use super::pkg_cache::{find_in_package_cache, store_file_to_package_cache}; +use crate::config::is_verbose; use crate::constants::{ DEFAULT_REGISTRY_PAGE_SIZE, REMOTE_REGISTRY_MAX_RETRIES, REMOTE_REGISTRY_REQUEST_TIMEOUT_SECS, REMOTE_REGISTRY_RETRY_DELAY_MS, @@ -32,7 +33,7 @@ use crate::output::TmanOutput; use crate::{config::TmanConfig, registry::found_result::PkgRegistryInfo}; async fn retry_async<'a, F, T>( - tman_config: Arc, + tman_config: Arc>, max_retries: u32, retry_delay: Duration, out: Arc>, @@ -47,7 +48,7 @@ where match operation().await { Ok(result) => return Ok(result), Err(e) => { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "Attempt {} failed: {:?}", attempt + 1, @@ -74,7 +75,7 @@ struct UploadInfo { } async fn get_package_upload_info( - tman_config: Arc, + tman_config: Arc>, base_url: &str, client: &reqwest::Client, pkg_info: &PkgInfo, @@ -124,7 +125,7 @@ async fn get_package_upload_info( content_format: Some("gzip".to_string()), }); - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "Payload of publishing: {}", payload @@ -133,7 +134,7 @@ async fn get_package_upload_info( let mut headers = HeaderMap::new(); - if let Some(user_token) = &tman_config.user_token { + if let Some(user_token) = &tman_config.read().await.user_token { let basic_token = format!("Basic {}", user_token); headers.insert( AUTHORIZATION, @@ -146,7 +147,7 @@ async fn get_package_upload_info( })?, ); } else { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Authorization token is missing"); } return Err(anyhow!("Authorization token is missing")); @@ -191,7 +192,7 @@ async fn get_package_upload_info( } async fn upload_package_to_remote( - tman_config: Arc, + tman_config: Arc>, client: &reqwest::Client, package_file_path: &str, url: &str, @@ -252,7 +253,7 @@ async fn upload_package_to_remote( } async fn ack_of_uploading( - tman_config: Arc, + tman_config: Arc>, base_url: &str, client: &reqwest::Client, resource_id: &str, @@ -306,7 +307,7 @@ async fn ack_of_uploading( } pub async fn upload_package( - tman_config: Arc, + tman_config: Arc>, base_url: &str, package_file_path: &str, pkg_info: &PkgInfo, @@ -360,7 +361,7 @@ fn parse_content_range(content_range: &str) -> Option<(u64, u64, u64)> { } pub async fn get_package( - tman_config: Arc, + tman_config: Arc>, pkg_type: &PkgType, pkg_name: &str, pkg_version: &Version, @@ -384,7 +385,7 @@ pub async fn get_package( { // If the filename matches, directly copy the cached file to // `temp_file`. - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "{} Found the package file ({}) in the package cache, using it directly.", Emoji("🚀", ":-)"), @@ -519,7 +520,7 @@ pub async fn get_package( // Only print when `download_complete` is `true`. if *download_complete.read().await { let temp_file_borrow = temp_file.read().await; - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "Package downloaded successfully from {} and written to {}", url, @@ -527,7 +528,7 @@ pub async fn get_package( )); } - if tman_config.enable_package_cache { + if tman_config.read().await.enable_package_cache { // Place the downloaded file into the cache. let downloaded_path = temp_file_borrow.path(); store_file_to_package_cache( @@ -587,7 +588,7 @@ struct RegistryPackagesData { /// * If parsing the JSON response fails. #[allow(clippy::too_many_arguments)] pub async fn get_package_list( - tman_config: &Arc, + tman_config: Arc>, base_url: &str, pkg_type: Option, name: Option, @@ -652,7 +653,7 @@ pub async fn get_package_list( .append_pair("page", ¤t_page.to_string()); } // query is dropped here - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { let query_info = format!( "{}{}{}", pkg_type.as_ref().map_or("".to_string(), |pt| format!("type={} ", pt)), @@ -720,7 +721,7 @@ pub async fn get_package_list( let packages_is_empty = api_response.data.packages.is_empty(); results.extend(api_response.data.packages); - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!( "Fetched {} packages (total: {}) at page {} for {}:{}@{}", results.len(), @@ -749,7 +750,7 @@ pub async fn get_package_list( } pub async fn delete_package( - tman_config: Arc, + tman_config: Arc>, base_url: &str, pkg_type: PkgType, name: &str, @@ -806,7 +807,8 @@ pub async fn delete_package( let mut headers = HeaderMap::new(); - if let Some(admin_token) = &tman_config.admin_token { + if let Some(admin_token) = &tman_config.read().await.admin_token + { let basic_token = format!("Basic {}", admin_token); headers.insert( AUTHORIZATION, @@ -819,7 +821,7 @@ pub async fn delete_package( })?, ); } else { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Authorization token is missing"); } return Err(anyhow!("Authorization token is missing")); diff --git a/core/src/ten_manager/src/solver/solve.rs b/core/src/ten_manager/src/solver/solve.rs index 179213235..8f611929b 100644 --- a/core/src/ten_manager/src/solver/solve.rs +++ b/core/src/ten_manager/src/solver/solve.rs @@ -21,7 +21,7 @@ use ten_rust::pkg_info::{ pkg_type_and_name::PkgTypeAndName, PkgInfo, }; -use crate::config::TmanConfig; +use crate::config::{is_verbose, TmanConfig}; use crate::output::TmanOutput; #[derive(Debug)] pub struct DependencyRelationship { @@ -30,8 +30,8 @@ pub struct DependencyRelationship { pub dependency: ManifestDependency, } -fn get_model( - tman_config: Arc, +async fn get_model( + tman_config: Arc>, model: &Model, is_usable: &mut bool, out: Arc>, @@ -41,7 +41,7 @@ fn get_model( .symbols(ShowType::SHOWN) .expect("Failed to retrieve symbols in the model."); - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("Model:"); } @@ -49,7 +49,7 @@ fn get_model( *is_usable = true; for symbol in atoms { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!(" {}", symbol)); } @@ -58,7 +58,8 @@ fn get_model( *is_usable = false; } } - if tman_config.verbose { + + if is_verbose(tman_config.clone()).await { out.normal_line(""); } @@ -66,17 +67,17 @@ fn get_model( } #[allow(dead_code)] -fn print_prefix( - tman_config: Arc, +async fn print_prefix( + tman_config: Arc>, depth: u8, out: Arc>, ) { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(""); } for _ in 0..depth { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(" "); } } @@ -84,8 +85,8 @@ fn print_prefix( // Recursively print the configuration object. #[allow(dead_code)] -fn print_configuration( - tman_config: Arc, +async fn print_configuration( + tman_config: Arc>, conf: &Configuration, key: Id, depth: u8, @@ -104,30 +105,32 @@ fn print_configuration( let subkey = conf .array_at(key, i) .expect("Failed to retrieve statistics array."); - print_prefix(tman_config.clone(), depth, out.clone()); + print_prefix(tman_config.clone(), depth, out.clone()).await; - print_configuration( + Box::pin(print_configuration( tman_config.clone(), conf, subkey, depth + 1, out.clone(), - ); + )) + .await; } } else if configuration_type.contains(ConfigurationType::MAP) { let size = conf.map_size(key).unwrap(); for i in 0..size { let name = conf.map_subkey_name(key, i).unwrap(); let subkey = conf.map_at(key, name).unwrap(); - print_prefix(tman_config.clone(), depth, out.clone()); + print_prefix(tman_config.clone(), depth, out.clone()).await; - print_configuration( + Box::pin(print_configuration( tman_config.clone(), conf, subkey, depth + 1, out.clone(), - ); + )) + .await; } } else { unreachable!() @@ -136,8 +139,8 @@ fn print_configuration( // recursively print the statistics object #[allow(dead_code)] -fn print_statistics( - tman_config: Arc, +async fn print_statistics( + tman_config: Arc>, stats: &Statistics, key: u64, depth: u8, @@ -160,15 +163,16 @@ fn print_statistics( let subkey = stats .array_at(key, i) .expect("Failed to retrieve statistics array."); - print_prefix(tman_config.clone(), depth, out.clone()); + print_prefix(tman_config.clone(), depth, out.clone()).await; - print_statistics( + Box::pin(print_statistics( tman_config.clone(), stats, subkey, depth + 1, out.clone(), - ); + )) + .await; } } @@ -177,15 +181,16 @@ fn print_statistics( for i in 0..size { let name = stats.map_subkey_name(key, i).unwrap(); let subkey = stats.map_at(key, name).unwrap(); - print_prefix(tman_config.clone(), depth, out.clone()); + print_prefix(tman_config.clone(), depth, out.clone()).await; - print_statistics( + Box::pin(print_statistics( tman_config.clone(), stats, subkey, depth + 1, out.clone(), - ); + )) + .await; } } @@ -199,8 +204,8 @@ type SolveOutcome = (UsableModel, NonUsableModels); type SolveResult = Result; #[allow(unused_assignments)] -fn solve( - tman_config: Arc, +async fn solve( + tman_config: Arc>, input: &str, out: Arc>, ) -> SolveResult { @@ -209,7 +214,7 @@ fn solve( let mut ctl = control({ let args = vec![]; - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { // args.push("--verbose".to_string()); } @@ -293,7 +298,9 @@ fn solve( model, &mut is_usable, out.clone(), - ) { + ) + .await + { if is_usable { usable_model = Some(m); @@ -309,7 +316,7 @@ fn solve( } // Stop if there are no more models. Ok(None) => { - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line("No more models"); } break; @@ -603,8 +610,8 @@ fn create_input_str_for_all_possible_pkgs_info( Ok(()) } -fn create_input_str( - tman_config: Arc, +async fn create_input_str( + tman_config: Arc>, pkg_type: &PkgType, pkg_name: &String, extra_dep_relationship: Option<&DependencyRelationship>, @@ -644,15 +651,15 @@ fn create_input_str( } } - if tman_config.verbose { + if is_verbose(tman_config.clone()).await { out.normal_line(&format!("Input: \n{}", input_str)); } Ok(input_str) } -pub fn solve_all( - tman_config: Arc, +pub async fn solve_all( + tman_config: Arc>, pkg_type: &PkgType, pkg_name: &String, extra_dep_relationship: Option<&DependencyRelationship>, @@ -668,6 +675,7 @@ pub fn solve_all( all_candidates, locked_pkgs, out.clone(), - )?; - solve(tman_config, &input_str, out) + ) + .await?; + solve(tman_config, &input_str, out).await } diff --git a/core/src/ten_manager/src/solver/solver_result.rs b/core/src/ten_manager/src/solver/solver_result.rs index a71fafbd9..76494ae7c 100644 --- a/core/src/ten_manager/src/solver/solver_result.rs +++ b/core/src/ten_manager/src/solver/solver_result.rs @@ -109,7 +109,7 @@ pub fn filter_solver_results_by_type_and_name<'a>( } pub async fn install_solver_results_in_app_folder( - tman_config: Arc, + tman_config: Arc>, command_data: &InstallCommand, solver_results: &Vec<&PkgInfo>, app_dir: &Path, diff --git a/core/src/ten_manager/tests/test_case/common/designer_state.rs b/core/src/ten_manager/tests/test_case/common/designer_state.rs index 00d1c3d8c..043c501bd 100644 --- a/core/src/ten_manager/tests/test_case/common/designer_state.rs +++ b/core/src/ten_manager/tests/test_case/common/designer_state.rs @@ -4,20 +4,17 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use ten_manager::{ - config::{internal::TmanInternalConfig, read_config, TmanConfig}, + config::{metadata::TmanMetadata, read_config, TmanConfig}, designer::DesignerState, output::TmanOutputCli, }; use super::tman_config::find_config_json; -pub fn create_designer_state() -> Arc> { +pub fn create_designer_state() -> Arc { let tman_config_file_path = find_config_json().map(|p| p.to_string_lossy().into_owned()); @@ -35,12 +32,14 @@ pub fn create_designer_state() -> Arc> { // Setup designer state let designer_state = DesignerState { - tman_config: Arc::new(tman_config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(tman_config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - Arc::new(RwLock::new(designer_state)) + Arc::new(designer_state) } diff --git a/core/src/ten_manager/tests/test_case/designer/apps/addons.rs b/core/src/ten_manager/tests/test_case/designer/apps/addons.rs index 5af6903ac..53693f2e2 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/addons.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/addons.rs @@ -7,11 +7,11 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{test, web, App}; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_manager::config::TmanConfig; use ten_manager::constants::TEST_DIR; use ten_manager::designer::apps::addons::{ @@ -27,8 +27,12 @@ mod tests { #[actix_web::test] async fn test_get_addons() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -91,7 +95,7 @@ mod tests { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( diff --git a/core/src/ten_manager/tests/test_case/designer/apps/create.rs b/core/src/ten_manager/tests/test_case/designer/apps/create.rs index ecb800329..fa3f6dd5c 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/create.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/create.rs @@ -7,12 +7,12 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{test, web, App}; use tempfile::tempdir; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_manager::config::TmanConfig; use ten_manager::constants::DEFAULT_APP_CPP; use ten_manager::designer::apps::create::{ @@ -28,13 +28,17 @@ mod tests { let temp_path = temp_dir.path().to_string_lossy().to_string(); let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -73,13 +77,17 @@ mod tests { #[actix_web::test] async fn test_create_app_invalid_dir() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/apps/get.rs b/core/src/ten_manager/tests/test_case/designer/apps/get.rs index 03ae9eeeb..d75cf009b 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/get.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/get.rs @@ -7,10 +7,10 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{test, web, App}; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_rust::base_dir_pkg_info::PkgsInfoInApp; use ten_manager::config::TmanConfig; @@ -25,8 +25,12 @@ mod tests { #[actix_web::test] async fn test_get_apps_some() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -40,7 +44,7 @@ mod tests { pkgs_cache.insert(TEST_DIR.to_string(), empty_pkg_info); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -71,13 +75,17 @@ mod tests { #[actix_web::test] async fn test_get_apps_none() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/apps/load.rs b/core/src/ten_manager/tests/test_case/designer/apps/load.rs index 87fe9af89..40cbb30ad 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/load.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/load.rs @@ -7,11 +7,11 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{test, web, App}; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_manager::config::TmanConfig; use ten_manager::designer::apps::load::{ load_app_endpoint, LoadAppRequestPayload, LoadAppResponseData, @@ -23,13 +23,17 @@ mod tests { #[actix_web::test] async fn test_load_app_fail() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/apps/reload.rs b/core/src/ten_manager/tests/test_case/designer/apps/reload.rs index 3e738ddf8..dc867f6d6 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/reload.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/reload.rs @@ -7,11 +7,11 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ apps::reload::{reload_app_endpoint, ReloadPkgsRequestPayload}, @@ -29,8 +29,12 @@ mod tests { async fn test_reload_app_error_base_dir_not_found() { // Set up the designer state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -56,7 +60,7 @@ mod tests { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -108,11 +112,13 @@ mod tests { // Set up the designer state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig { verbose: true, ..TmanConfig::default() - }), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + })), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -131,7 +137,7 @@ mod tests { pkgs_cache.insert(invalid_path.to_string(), empty_pkg_info); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/apps/schema/mod.rs b/core/src/ten_manager/tests/test_case/designer/apps/schema/mod.rs index aaccaeabb..3bcc45319 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/schema/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/schema/mod.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ apps::schema::{ @@ -32,8 +29,12 @@ mod tests { async fn test_get_app_schema_success() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -57,7 +58,7 @@ mod tests { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -114,8 +115,12 @@ mod tests { async fn test_get_app_schema_app_not_found() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -139,7 +144,7 @@ mod tests { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -171,14 +176,18 @@ mod tests { async fn test_get_extension_schema_app_not_found() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/apps/unload.rs b/core/src/ten_manager/tests/test_case/designer/apps/unload.rs index ab312ae10..43d8a373a 100644 --- a/core/src/ten_manager/tests/test_case/designer/apps/unload.rs +++ b/core/src/ten_manager/tests/test_case/designer/apps/unload.rs @@ -7,10 +7,10 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{test, web, App}; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use crate::test_case::common::mock::inject_all_pkgs_for_mock; use ten_manager::config::TmanConfig; @@ -26,8 +26,12 @@ mod tests { async fn test_unload_app_success() { // Create designer state with an app in pkgs_cache. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -56,7 +60,7 @@ mod tests { assert!(pkgs_cache.contains_key(TEST_DIR)); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Initialize test service. let app = test::init_service( @@ -92,10 +96,7 @@ mod tests { assert_eq!(response.status, Status::Ok); assert_eq!(response.data["success"], true); - // Verify that the app has been removed from pkgs_cache. - let state = designer_state.read().unwrap(); - - let pkgs_cache = state.pkgs_cache.read().await; + let pkgs_cache = designer_state.pkgs_cache.read().await; assert!(!pkgs_cache.contains_key(TEST_DIR)); } @@ -103,14 +104,18 @@ mod tests { async fn test_unload_app_invalid_base_dir() { // Create designer state without any apps in pkgs_cache. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Initialize test service. let app = test::init_service( @@ -151,14 +156,18 @@ mod tests { async fn test_unload_app_not_loaded() { // Create designer state without any apps in pkgs_cache. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Initialize test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/builtin_function/install_all.rs b/core/src/ten_manager/tests/test_case/designer/builtin_function/install_all.rs index 6c01c538e..02d82b699 100644 --- a/core/src/ten_manager/tests/test_case/designer/builtin_function/install_all.rs +++ b/core/src/ten_manager/tests/test_case/designer/builtin_function/install_all.rs @@ -4,17 +4,14 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use futures_util::{SinkExt, StreamExt}; use tokio_tungstenite::{connect_async, tungstenite::protocol::Message}; use ten_manager::{ - config::internal::TmanInternalConfig, + config::metadata::TmanMetadata, designer::builtin_function::{builtin_function_endpoint, msg::InboundMsg}, }; use ten_manager::{ @@ -106,14 +103,16 @@ async fn test_ws_builtin_function_install_all() { #[actix_rt::test] async fn test_cmd_builtin_function_install_all() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Initialize the test service with the WebSocket endpoint. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/builtin_function/mod.rs b/core/src/ten_manager/tests/test_case/designer/builtin_function/mod.rs index ce069fe3a..42a6123dc 100644 --- a/core/src/ten_manager/tests/test_case/designer/builtin_function/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/builtin_function/mod.rs @@ -6,10 +6,7 @@ // pub mod install_all; -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{ http::{header, StatusCode}, @@ -17,7 +14,7 @@ use actix_web::{ }; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{builtin_function::builtin_function_endpoint, DesignerState}, output::TmanOutputCli, }; @@ -25,14 +22,16 @@ use ten_manager::{ #[actix_rt::test] async fn test_cmd_builtin_function_websocket_connection() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Initialize the test service with the WebSocket endpoint. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/dir_list/mod.rs b/core/src/ten_manager/tests/test_case/designer/dir_list/mod.rs index 2e301c9ab..837921834 100644 --- a/core/src/ten_manager/tests/test_case/designer/dir_list/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/dir_list/mod.rs @@ -9,13 +9,13 @@ mod tests { use std::collections::HashMap; use std::fs::{self, File}; use std::io::Write; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{test, web, App}; use serde::{Deserialize, Serialize}; use tempfile::tempdir; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_manager::{ config::TmanConfig, designer::{ @@ -52,13 +52,17 @@ mod tests { writeln!(file, "Hello, world!").unwrap(); // Initialize DesignerState. - let state = web::Data::new(Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = web::Data::new(Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }))); + })); // Configure the `list_dir` route. let app = test::init_service(App::new().app_data(state.clone()).route( @@ -104,13 +108,17 @@ mod tests { writeln!(f2, "File 2").unwrap(); // Initialize DesignerState. - let state = web::Data::new(Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = web::Data::new(Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }))); + })); // Configure the `list_dir` route. let app = test::init_service(App::new().app_data(state.clone()).route( @@ -148,13 +156,17 @@ mod tests { #[actix_web::test] async fn test_list_dir_with_non_existing_path() { - let state = web::Data::new(Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = web::Data::new(Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }))); + })); let app = test::init_service(App::new().app_data(state.clone()).route( "/api/designer/v1/dir-list", diff --git a/core/src/ten_manager/tests/test_case/designer/doc_link/mod.rs b/core/src/ten_manager/tests/test_case/designer/doc_link/mod.rs index f2b1fc118..86d45a7e0 100644 --- a/core/src/ten_manager/tests/test_case/designer/doc_link/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/doc_link/mod.rs @@ -4,15 +4,12 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ doc_link::{ get_doc_link_endpoint, DocLinkKey, GetDocLinkRequestPayload, @@ -35,13 +32,15 @@ async fn test_get_doc_link_success() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( @@ -83,13 +82,15 @@ async fn test_get_doc_link_chinese() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( @@ -133,13 +134,15 @@ async fn test_get_doc_link_language_fallback() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( @@ -181,13 +184,15 @@ async fn test_get_doc_link_not_found() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/env/mod.rs b/core/src/ten_manager/tests/test_case/designer/env/mod.rs index 2ee9c9d0b..af259c1d0 100644 --- a/core/src/ten_manager/tests/test_case/designer/env/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/env/mod.rs @@ -14,7 +14,7 @@ mod tests { use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{env::get_env_endpoint, DesignerState}, output::TmanOutputCli, }; @@ -22,13 +22,17 @@ mod tests { #[actix_web::test] async fn test_get_env_success() { // Create test state. - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = test::init_service( @@ -63,8 +67,12 @@ mod tests { async fn test_get_env_error() { // Create test state let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), diff --git a/core/src/ten_manager/tests/test_case/designer/extensions/property/mod.rs b/core/src/ten_manager/tests/test_case/designer/extensions/property/mod.rs index e7d2d48c7..d4fe1f501 100644 --- a/core/src/ten_manager/tests/test_case/designer/extensions/property/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/extensions/property/mod.rs @@ -7,11 +7,11 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{http::StatusCode, test, web, App}; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_manager::config::TmanConfig; use ten_manager::constants::TEST_DIR; use ten_manager::designer::extensions::property::{ @@ -30,8 +30,12 @@ mod tests { async fn test_get_extension_property_success() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -73,7 +77,7 @@ mod tests { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -128,14 +132,18 @@ mod tests { async fn test_get_extension_property_app_not_found() { // Set up the designer state with empty cache. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service let app = test::init_service( @@ -169,8 +177,12 @@ mod tests { async fn test_get_extension_property_extension_not_found() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -187,7 +199,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -221,8 +233,12 @@ mod tests { async fn test_get_extension_property_no_property() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -239,7 +255,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/extensions/schema/mod.rs b/core/src/ten_manager/tests/test_case/designer/extensions/schema/mod.rs index ec18d3c87..f7869cddd 100644 --- a/core/src/ten_manager/tests/test_case/designer/extensions/schema/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/extensions/schema/mod.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ extensions::schema::{ @@ -33,8 +30,12 @@ mod tests { async fn test_get_extension_schema_success() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -51,7 +52,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -109,8 +110,12 @@ mod tests { async fn test_get_extension_schema_extension_not_found() { // Set up the designer state with initial data let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -127,7 +132,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -160,14 +165,18 @@ mod tests { async fn test_get_extension_schema_app_not_found() { // Set up the designer state with initial data let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/get_apps.rs b/core/src/ten_manager/tests/test_case/designer/get_apps.rs index 4611db7b1..b6b82c865 100644 --- a/core/src/ten_manager/tests/test_case/designer/get_apps.rs +++ b/core/src/ten_manager/tests/test_case/designer/get_apps.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ apps::get::{get_apps_endpoint, GetAppsResponseData}, response::{ApiResponse, Status}, @@ -27,8 +24,12 @@ mod tests { async fn test_get_apps_with_uri() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -53,7 +54,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -97,8 +98,12 @@ mod tests { async fn test_get_apps_without_uri() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -123,7 +128,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/get_graphs.rs b/core/src/ten_manager/tests/test_case/designer/get_graphs.rs index fa5d9bf9d..c599c4b41 100644 --- a/core/src/ten_manager/tests/test_case/designer/get_graphs.rs +++ b/core/src/ten_manager/tests/test_case/designer/get_graphs.rs @@ -4,15 +4,12 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ graphs::{ connections::get::{ @@ -36,8 +33,10 @@ use crate::test_case::common::mock::inject_all_pkgs_for_mock; #[actix_rt::test] async fn test_cmd_designer_graphs_app_property_not_exist() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -75,7 +74,7 @@ async fn test_cmd_designer_graphs_app_property_not_exist() { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( "/api/designer/v1/graphs", @@ -107,8 +106,10 @@ async fn test_cmd_designer_graphs_app_property_not_exist() { #[actix_rt::test] async fn test_cmd_designer_connections_has_msg_conversion() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -146,7 +147,7 @@ async fn test_cmd_designer_connections_has_msg_conversion() { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() .app_data(web::Data::new(designer_state.clone())) @@ -159,8 +160,7 @@ async fn test_cmd_designer_connections_has_msg_conversion() { let request_payload = GetGraphConnectionsRequestPayload { graph_id: { - let state_read = designer_state.read().unwrap(); - let graphs_cache = state_read.graphs_cache.read().await; + let graphs_cache = designer_state.graphs_cache.read().await; graphs_cache .iter() diff --git a/core/src/ten_manager/tests/test_case/designer/get_packages_scripts.rs b/core/src/ten_manager/tests/test_case/designer/get_packages_scripts.rs index 4f4940655..0fbc2768e 100644 --- a/core/src/ten_manager/tests/test_case/designer/get_packages_scripts.rs +++ b/core/src/ten_manager/tests/test_case/designer/get_packages_scripts.rs @@ -6,15 +6,12 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ apps::scripts::{ get_app_scripts_endpoint, GetPackagesScriptsRequestPayload, @@ -31,8 +28,12 @@ mod tests { async fn test_get_apps_scripts_success() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -57,7 +58,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -104,14 +105,18 @@ mod tests { async fn test_get_apps_scripts_base_dir_not_found() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/connections/add.rs b/core/src/ten_manager/tests/test_case/designer/graphs/connections/add.rs index 44653ee1e..9da066f1e 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/connections/add.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/connections/add.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ graphs::connections::add::{ add_graph_connection_endpoint, @@ -36,8 +33,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_success_1() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -137,7 +138,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -206,8 +207,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_success_2() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -328,7 +333,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -398,8 +403,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_invalid_graph() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -437,7 +446,7 @@ mod tests { assert!(inject_ret.is_ok()); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -471,8 +480,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_preserves_order() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -572,7 +585,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); let app = test::init_service( App::new() @@ -650,8 +663,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_file_comparison() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -751,7 +768,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); let app = test::init_service( App::new() @@ -829,8 +846,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_data_type() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -916,7 +937,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); let app = test::init_service( App::new() @@ -982,8 +1003,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_frame_types() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -1069,7 +1094,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); let app = test::init_service( App::new() @@ -1147,8 +1172,12 @@ mod tests { #[actix_web::test] async fn test_add_multiple_connections_preservation_order() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -1247,7 +1276,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/connections/delete.rs b/core/src/ten_manager/tests/test_case/designer/graphs/connections/delete.rs index dd92648ab..4ebfc68cc 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/connections/delete.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/connections/delete.rs @@ -6,10 +6,7 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_rust::pkg_info::{ @@ -19,7 +16,7 @@ mod tests { use uuid::Uuid; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::connections::delete::{ @@ -41,8 +38,12 @@ mod tests { #[actix_web::test] async fn test_delete_graph_connection_invalid_graph() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -59,7 +60,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -101,8 +102,12 @@ mod tests { #[actix_web::test] async fn test_delete_graph_connection_nonexistent_connection() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -131,7 +136,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -192,8 +197,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -230,7 +239,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -272,11 +281,7 @@ mod tests { assert!(response.data.success); // Verify the connection was actually removed from the data. - let state_read = designer_state.read().unwrap(); - - let DesignerState { graphs_cache, .. } = &*state_read; - - let graphs_cache = graphs_cache.read().await; + let graphs_cache = designer_state.graphs_cache.read().await; if let Some(predefined_graph) = graphs_cache_find_by_id(&graphs_cache, &graph_id_clone) { diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/connections/get.rs b/core/src/ten_manager/tests/test_case/designer/graphs/connections/get.rs index ff14ce241..d7e55c3f4 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/connections/get.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/connections/get.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::connections::{ @@ -37,8 +34,12 @@ mod tests { #[actix_web::test] async fn test_get_connections_success() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -72,7 +73,7 @@ mod tests { .expect("No graph with name 'default' found"); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -130,8 +131,12 @@ mod tests { #[actix_web::test] async fn test_get_connections_have_all_data_type() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -196,7 +201,7 @@ mod tests { .expect("No graph with name 'default' found"); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() .app_data(web::Data::new(designer_state.clone())) diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/add_with_msg_conversion.rs b/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/add_with_msg_conversion.rs index acdd10420..b659d614f 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/add_with_msg_conversion.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/add_with_msg_conversion.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ graphs::connections::add::{ add_graph_connection_endpoint, @@ -39,8 +36,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_with_msg_conversion() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -157,7 +158,7 @@ mod tests { result: None, }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -228,8 +229,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_with_result_conversion_1() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -345,7 +350,7 @@ mod tests { }), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -413,8 +418,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_with_result_conversion_2() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -536,7 +545,7 @@ mod tests { }), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -604,8 +613,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_with_result_conversion_3() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -727,7 +740,7 @@ mod tests { }), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -795,8 +808,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_connection_with_result_conversion_4() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -919,7 +936,7 @@ mod tests { }), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/modify_with_msg_conversion.rs b/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/modify_with_msg_conversion.rs index 91b8ffe0a..2a2e92288 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/modify_with_msg_conversion.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/connections/msg_conversion/modify_with_msg_conversion.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ graphs::connections::{ add::{ @@ -45,8 +42,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_msg_conversion_1() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -131,7 +132,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -291,8 +292,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_msg_conversion_2() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -378,7 +383,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -488,8 +493,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_msg_conversion_3() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -575,7 +584,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -691,8 +700,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_msg_conversion_schema_failure_1() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -777,7 +790,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -908,8 +921,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_msg_conversion_schema_failure_2() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -994,7 +1011,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -1132,8 +1149,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_msg_conversion_schema_failure_3() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -1219,7 +1240,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -1312,8 +1333,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_connection_remove_msg_conversion() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -1428,7 +1453,7 @@ mod tests { }), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/get.rs b/core/src/ten_manager/tests/test_case/designer/graphs/get.rs index 4dfe1a3b5..ee2191d4a 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/get.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/get.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::get::{ @@ -31,8 +28,12 @@ mod tests { #[actix_web::test] async fn test_get_graphs_success() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -49,7 +50,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -121,13 +122,17 @@ mod tests { #[actix_web::test] async fn test_get_graphs_no_app_package() { - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/add.rs b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/add.rs index 1cdb404d6..e9e32b4b9 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/add.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/add.rs @@ -6,17 +6,12 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - fs, - path::Path, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, fs, path::Path, sync::Arc}; use actix_web::{test, web, App}; use serde_json::Value; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::nodes::add::{ @@ -42,8 +37,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_node_invalid_graph() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -60,7 +59,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -101,8 +100,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_node_invalid_app_uri() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -129,7 +132,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -172,8 +175,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_node_success() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -203,7 +210,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -249,8 +256,12 @@ mod tests { #[actix_web::test] async fn test_add_graph_node_without_app_uri_success() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -277,7 +288,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -347,8 +358,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -383,7 +398,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -455,8 +470,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -506,7 +525,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // First add a node, then delete it. // Setup the add endpoint. @@ -583,8 +602,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -634,7 +657,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // First add a node, then delete it. // Setup the add endpoint. diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/delete.rs b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/delete.rs index ac53dc55b..3319568ae 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/delete.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/delete.rs @@ -6,10 +6,7 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_rust::pkg_info::constants::{ @@ -18,7 +15,7 @@ mod tests { use uuid::Uuid; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::nodes::{ @@ -42,8 +39,12 @@ mod tests { #[actix_web::test] async fn test_delete_graph_node_invalid_graph() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -60,7 +61,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -100,8 +101,12 @@ mod tests { #[actix_web::test] async fn test_delete_graph_node_nonexistent_node() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -131,7 +136,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -193,8 +198,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -231,7 +240,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // First add a node, then delete it. // Setup the add endpoint. @@ -323,11 +332,7 @@ mod tests { assert!(response.data.success); // Verify the node was actually removed from the data. - let state_read = designer_state.read().unwrap(); - - let DesignerState { graphs_cache, .. } = &*state_read; - - let graphs_cache = graphs_cache.read().await; + let graphs_cache = designer_state.graphs_cache.read().await; if let Some(graph_info) = graphs_cache_find_by_id(&graphs_cache, &graph_id_clone) diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/get.rs b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/get.rs index fe2d08053..e896aa933 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/get.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/get.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::nodes::get::{ @@ -32,8 +29,12 @@ mod tests { #[actix_web::test] async fn test_get_extensions_success() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -50,12 +51,11 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Find the uuid of the "default" graph. let graph_id = { - let state = designer_state.read().unwrap(); - let graphs_cache = state.graphs_cache.read().await; + let graphs_cache = designer_state.graphs_cache.read().await; graphs_cache .iter() @@ -124,8 +124,12 @@ mod tests { #[actix_web::test] async fn test_get_extensions_no_graph() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -142,7 +146,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/property/modify.rs b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/property/modify.rs index a4bcd92c5..f58d8ab02 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/property/modify.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/property/modify.rs @@ -6,15 +6,12 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use serde_json::json; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::nodes::property::update::{ @@ -62,8 +59,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -114,7 +115,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -186,8 +187,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_node_property_invalid_graph() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -204,7 +209,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -247,8 +252,12 @@ mod tests { #[actix_web::test] async fn test_update_graph_node_property_node_not_found() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -277,7 +286,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -342,8 +351,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -394,7 +407,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -481,8 +494,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -533,7 +550,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -613,8 +630,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -663,7 +684,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -749,8 +770,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -799,7 +824,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/replace.rs b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/replace.rs index 86404cef1..c6c5eb250 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/nodes/replace.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/nodes/replace.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ graphs::nodes::replace::{ @@ -39,8 +36,12 @@ mod tests { async fn test_replace_graph_node_invalid_graph() { // Setup a designer state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -57,7 +58,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Setup test app. let app = test::init_service( @@ -99,8 +100,12 @@ mod tests { async fn test_replace_graph_node_not_found() { // Setup a designer state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -125,7 +130,7 @@ mod tests { *id }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Setup test app. let app = test::init_service( @@ -186,8 +191,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -236,7 +245,7 @@ mod tests { *id }; - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); // Setup test app. let app = test::init_service( @@ -251,8 +260,7 @@ mod tests { // Find an existing node name for our test. let existing_node_name = { - let designer_state = designer_state_arc.read().unwrap(); - let graphs_cache = designer_state.graphs_cache.read().await; + let graphs_cache = designer_state_arc.graphs_cache.read().await; let graph_info = graphs_cache.get(&graph_id).unwrap(); @@ -350,8 +358,12 @@ mod tests { // Initialize test state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -400,7 +412,7 @@ mod tests { *id }; - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); // Setup test app. let app = test::init_service( @@ -415,8 +427,7 @@ mod tests { // Find an existing node name for our test. let existing_node_name = { - let designer_state = designer_state_arc.read().unwrap(); - let graphs_cache = designer_state.graphs_cache.read().await; + let graphs_cache = designer_state_arc.graphs_cache.read().await; let graph_info = graphs_cache.get(&graph_id).unwrap(); // Assuming there's at least one node in the graph. @@ -494,8 +505,12 @@ mod tests { async fn test_replace_graph_node_success() { // Setup a designer state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -524,7 +539,7 @@ mod tests { *id }; - let designer_state_arc = Arc::new(RwLock::new(designer_state)); + let designer_state_arc = Arc::new(designer_state); // Setup test app. let app = test::init_service( @@ -539,8 +554,7 @@ mod tests { // Find an existing node name and addon for our test. let (existing_node_name, existing_app_uri) = { - let designer_state = designer_state_arc.read().unwrap(); - let graphs_cache = designer_state.graphs_cache.read().await; + let graphs_cache = designer_state_arc.graphs_cache.read().await; let graph_info = graphs_cache.get(&graph_id).unwrap(); // Assuming there's at least one node in the graph. @@ -581,8 +595,7 @@ mod tests { assert!(response.data.success); // Verify the node was actually updated. - let designer_state = designer_state_arc.read().unwrap(); - let graphs_cache = designer_state.graphs_cache.read().await; + let graphs_cache = designer_state_arc.graphs_cache.read().await; let graph_info = graphs_cache.get(&graph_id).unwrap(); let updated_node = graph_info .graph diff --git a/core/src/ten_manager/tests/test_case/designer/graphs/update.rs b/core/src/ten_manager/tests/test_case/designer/graphs/update.rs index 8df668efc..9216264d6 100644 --- a/core/src/ten_manager/tests/test_case/designer/graphs/update.rs +++ b/core/src/ten_manager/tests/test_case/designer/graphs/update.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ graphs::update::{ update_graph_endpoint, GraphNodeForUpdate, @@ -43,8 +40,12 @@ mod tests { async fn test_update_graph_success() { // Create a designer state with an empty graphs cache. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -94,7 +95,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Create a test app with the update_graph_endpoint. let app = test::init_service( @@ -200,13 +201,17 @@ mod tests { #[actix_web::test] async fn test_update_graph_not_found() { // Create a designer state with an empty graphs cache. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create a test app with the update_graph_endpoint. let app = test::init_service( @@ -254,8 +259,12 @@ mod tests { async fn test_update_graph_empty_connections() { // Create a designer state with an empty graphs cache. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -305,7 +314,7 @@ mod tests { graph_id_clone = *graph_id; } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Create a test app with the update_graph_endpoint. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/help_text/mod.rs b/core/src/ten_manager/tests/test_case/designer/help_text/mod.rs index 5d14b6346..ab6c4a695 100644 --- a/core/src/ten_manager/tests/test_case/designer/help_text/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/help_text/mod.rs @@ -4,15 +4,12 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ help_text::{ get_help_text_endpoint, GetHelpTextRequestPayload, @@ -35,13 +32,15 @@ async fn test_get_help_text_success() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( @@ -83,13 +82,15 @@ async fn test_get_help_text_chinese() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( @@ -133,13 +134,15 @@ async fn test_get_help_text_language_fallback() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( @@ -181,13 +184,15 @@ async fn test_get_help_text_not_found() { // Get mock state. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); // Create app with the endpoint. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/internal_config/mod.rs b/core/src/ten_manager/tests/test_case/designer/internal_config/mod.rs deleted file mode 100644 index 0dc352a17..000000000 --- a/core/src/ten_manager/tests/test_case/designer/internal_config/mod.rs +++ /dev/null @@ -1,372 +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. -// -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; - -use actix_web::{http::StatusCode, test, web}; -use uuid::Uuid; - -use ten_manager::{ - config::{ - internal::{ - GraphGeometry, GraphUiConfig, NodeGeometry, TmanInternalConfig, - }, - TmanConfig, - }, - designer::{ - internal_config::graph_ui::{ - get::{ - get_graph_ui_endpoint, GetGraphUiRequestPayload, - GetGraphUiResponseData, - }, - set::{ - set_graph_ui_endpoint, SetGraphUiRequestPayload, - SetGraphUiResponseData, - }, - }, - response::ApiResponse, - DesignerState, - }, - output::TmanOutputCli, -}; - -#[actix_web::test] -async fn test_get_graph_ui_empty() { - // Generate a random graph_id for testing. - let graph_id = Uuid::new_v4(); - - // Create the request payload. - let payload = GetGraphUiRequestPayload { graph_id }; - - // Create a clean state with empty config. - let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), - out: Arc::new(Box::new(TmanOutputCli)), - pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), - graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); - - // Create app with the endpoint. - let app = test::init_service( - actix_web::App::new() - .app_data(state.clone()) - .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), - ) - .await; - - // Make the request. - let req = test::TestRequest::post() - .uri("/graph-ui/get") - .set_json(&payload) - .to_request(); - - let resp = test::call_service(&app, req).await; - - // Assert status code is OK. - assert_eq!(resp.status(), StatusCode::OK); - - // Extract and check the response body. - let body = test::read_body(resp).await; - let result: ApiResponse = - serde_json::from_slice(&body).unwrap(); - - // Assert that graph_geometry is None since we haven't set it yet. - assert!(result.data.graph_geometry.is_none()); -} - -#[actix_web::test] -async fn test_set_and_get_graph_ui() { - // Generate a random graph_id for testing. - let graph_id = Uuid::new_v4(); - - // Create test geometry data. - let node_geometry = NodeGeometry { - app: Some("test_app".to_string()), - extension: "test_extension".to_string(), - x: 100, - y: 200, - }; - - let graph_geometry = GraphGeometry { - nodes_geometry: vec![node_geometry], - }; - - // Create the set request payload. - let set_payload = SetGraphUiRequestPayload { - graph_id, - graph_geometry: graph_geometry.clone(), - }; - - // Create a clean state with empty config. - let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), - out: Arc::new(Box::new(TmanOutputCli)), - pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), - graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); - - // Create app with both endpoints. - let app = test::init_service( - actix_web::App::new() - .app_data(state.clone()) - .route("/graph-ui/set", web::post().to(set_graph_ui_endpoint)) - .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), - ) - .await; - - // Make the set request. - let set_req = test::TestRequest::post() - .uri("/graph-ui/set") - .set_json(&set_payload) - .to_request(); - - let set_resp = test::call_service(&app, set_req).await; - - // Assert status code for set is OK. - assert_eq!(set_resp.status(), StatusCode::OK); - - // Extract and check the set response. - let set_body = test::read_body(set_resp).await; - let set_result: ApiResponse = - serde_json::from_slice(&set_body).unwrap(); - - // Assert that set was successful. - assert!(set_result.data.success); - - // Now create and make the get request for the same graph_id. - let get_payload = GetGraphUiRequestPayload { graph_id }; - - let get_req = test::TestRequest::post() - .uri("/graph-ui/get") - .set_json(&get_payload) - .to_request(); - - let get_resp = test::call_service(&app, get_req).await; - - // Assert status code for get is OK. - assert_eq!(get_resp.status(), StatusCode::OK); - - // Extract and check the get response. - let get_body = test::read_body(get_resp).await; - let get_result: ApiResponse = - serde_json::from_slice(&get_body).unwrap(); - - // Assert that graph_geometry is now present and matches what we set. - assert!(get_result.data.graph_geometry.is_some()); - - let returned_geometry = get_result.data.graph_geometry.unwrap(); - assert_eq!(returned_geometry.nodes_geometry.len(), 1); - assert_eq!(returned_geometry.nodes_geometry[0].x, 100); - assert_eq!(returned_geometry.nodes_geometry[0].y, 200); - assert_eq!( - returned_geometry.nodes_geometry[0].extension, - "test_extension" - ); - assert_eq!( - returned_geometry.nodes_geometry[0].app, - Some("test_app".to_string()) - ); -} - -#[actix_web::test] -async fn test_update_graph_ui() { - // Generate a random graph_id for testing. - let graph_id = Uuid::new_v4(); - - // Create initial geometry data. - let initial_node_geometry = NodeGeometry { - app: Some("initial_app".to_string()), - extension: "initial_extension".to_string(), - x: 10, - y: 20, - }; - - let initial_graph_geometry = GraphGeometry { - nodes_geometry: vec![initial_node_geometry], - }; - - // Create updated geometry data. - let updated_node_geometry = NodeGeometry { - app: Some("updated_app".to_string()), - extension: "updated_extension".to_string(), - x: 30, - y: 40, - }; - - let updated_graph_geometry = GraphGeometry { - nodes_geometry: vec![updated_node_geometry], - }; - - // Create a designer state with pre-filled graph_ui config. - let mut graph_ui_config = GraphUiConfig::default(); - graph_ui_config - .graphs_geometry - .insert(graph_id, initial_graph_geometry); - - let tman_internal_config = TmanInternalConfig { - graph_ui: graph_ui_config, - }; - - let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(tman_internal_config), - out: Arc::new(Box::new(TmanOutputCli)), - pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), - graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); - - // Create app with both endpoints. - let app = test::init_service( - actix_web::App::new() - .app_data(state.clone()) - .route("/graph-ui/set", web::post().to(set_graph_ui_endpoint)) - .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), - ) - .await; - - // Check initial state with get. - let get_payload = GetGraphUiRequestPayload { graph_id }; - let get_req = test::TestRequest::post() - .uri("/graph-ui/get") - .set_json(&get_payload) - .to_request(); - - let get_resp = test::call_service(&app, get_req).await; - assert_eq!(get_resp.status(), StatusCode::OK); - - let get_body = test::read_body(get_resp).await; - let get_result: ApiResponse = - serde_json::from_slice(&get_body).unwrap(); - - let initial_geo = get_result.data.graph_geometry.unwrap(); - assert_eq!(initial_geo.nodes_geometry[0].x, 10); - assert_eq!(initial_geo.nodes_geometry[0].y, 20); - - // Now update with new geometry. - let set_payload = SetGraphUiRequestPayload { - graph_id, - graph_geometry: updated_graph_geometry, - }; - - let set_req = test::TestRequest::post() - .uri("/graph-ui/set") - .set_json(&set_payload) - .to_request(); - - let set_resp = test::call_service(&app, set_req).await; - assert_eq!(set_resp.status(), StatusCode::OK); - - // Verify updated geometry. - let get_req = test::TestRequest::post() - .uri("/graph-ui/get") - .set_json(&get_payload) - .to_request(); - - let get_resp = test::call_service(&app, get_req).await; - let get_body = test::read_body(get_resp).await; - let get_result: ApiResponse = - serde_json::from_slice(&get_body).unwrap(); - - let updated_geo = get_result.data.graph_geometry.unwrap(); - assert_eq!(updated_geo.nodes_geometry[0].x, 30); - assert_eq!(updated_geo.nodes_geometry[0].y, 40); - assert_eq!(updated_geo.nodes_geometry[0].extension, "updated_extension"); - assert_eq!( - updated_geo.nodes_geometry[0].app, - Some("updated_app".to_string()) - ); -} - -#[actix_web::test] -async fn test_get_nonexistent_graph_ui() { - // Generate two random graph_ids for testing. - let existing_graph_id = Uuid::new_v4(); - let nonexistent_graph_id = Uuid::new_v4(); - - // Create test geometry data. - let node_geometry = NodeGeometry { - app: Some("test_app".to_string()), - extension: "test_extension".to_string(), - x: 100, - y: 200, - }; - - let graph_geometry = GraphGeometry { - nodes_geometry: vec![node_geometry], - }; - - // Create a designer state with pre-filled graph_ui config for only one - // graph. - let mut graph_ui_config = GraphUiConfig::default(); - graph_ui_config - .graphs_geometry - .insert(existing_graph_id, graph_geometry); - - let tman_internal_config = TmanInternalConfig { - graph_ui: graph_ui_config, - }; - - let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(tman_internal_config), - out: Arc::new(Box::new(TmanOutputCli)), - pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), - graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); - - // Create app with the get endpoint. - let app = test::init_service( - actix_web::App::new() - .app_data(state.clone()) - .route("/graph-ui/get", web::post().to(get_graph_ui_endpoint)), - ) - .await; - - // Make request for the nonexistent graph. - let get_payload = GetGraphUiRequestPayload { - graph_id: nonexistent_graph_id, - }; - let get_req = test::TestRequest::post() - .uri("/graph-ui/get") - .set_json(&get_payload) - .to_request(); - - let get_resp = test::call_service(&app, get_req).await; - assert_eq!(get_resp.status(), StatusCode::OK); - - let get_body = test::read_body(get_resp).await; - let get_result: ApiResponse = - serde_json::from_slice(&get_body).unwrap(); - - // Should return None for nonexistent graph. - assert!(get_result.data.graph_geometry.is_none()); - - // Now check the existing graph. - let get_payload = GetGraphUiRequestPayload { - graph_id: existing_graph_id, - }; - let get_req = test::TestRequest::post() - .uri("/graph-ui/get") - .set_json(&get_payload) - .to_request(); - - let get_resp = test::call_service(&app, get_req).await; - let get_body = test::read_body(get_resp).await; - let get_result: ApiResponse = - serde_json::from_slice(&get_body).unwrap(); - - // Should return Some for existing graph. - assert!(get_result.data.graph_geometry.is_some()); -} diff --git a/core/src/ten_manager/tests/test_case/designer/load_apps.rs b/core/src/ten_manager/tests/test_case/designer/load_apps.rs index fb07bfc8d..967add009 100644 --- a/core/src/ten_manager/tests/test_case/designer/load_apps.rs +++ b/core/src/ten_manager/tests/test_case/designer/load_apps.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ apps::load::{ load_app_endpoint, LoadAppRequestPayload, LoadAppResponseData, @@ -33,14 +30,16 @@ mod tests { }; let designer_state = DesignerState { - tman_config: Arc::new(tman_config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(tman_config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -90,14 +89,18 @@ mod tests { async fn test_load_app_success_without_app_uri() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/manifest/validate.rs b/core/src/ten_manager/tests/test_case/designer/manifest/validate.rs index 69c0efe83..6208f9deb 100644 --- a/core/src/ten_manager/tests/test_case/designer/manifest/validate.rs +++ b/core/src/ten_manager/tests/test_case/designer/manifest/validate.rs @@ -4,12 +4,12 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ manifest::validate::{ validate_manifest_endpoint, ValidateManifestRequestPayload, @@ -24,13 +24,15 @@ use ten_manager::{ #[actix_rt::test] async fn test_validate_manifest_valid() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -79,13 +81,15 @@ async fn test_validate_manifest_valid() { #[actix_rt::test] async fn test_validate_manifest_with_api() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -168,13 +172,15 @@ async fn test_validate_manifest_with_api() { #[actix_rt::test] async fn test_validate_app_manifest_with_incorrect_api() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -259,13 +265,15 @@ async fn test_validate_app_manifest_with_incorrect_api() { #[actix_rt::test] async fn test_validate_app_manifest_with_correct_api() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -321,13 +329,15 @@ async fn test_validate_app_manifest_with_correct_api() { #[actix_rt::test] async fn test_validate_manifest_missing_required_fields() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -378,13 +388,15 @@ async fn test_validate_manifest_missing_required_fields() { #[actix_rt::test] async fn test_validate_manifest_invalid_type() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -437,13 +449,15 @@ async fn test_validate_manifest_invalid_type() { #[actix_rt::test] async fn test_validate_manifest_invalid_version_format() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( @@ -496,13 +510,15 @@ async fn test_validate_manifest_invalid_version_format() { #[actix_rt::test] async fn test_validate_manifest_invalid_json_syntax() { // Create the application state. - let designer_state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let designer_state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: Default::default(), graphs_cache: Default::default(), - })); + }); // Initialize test application with the endpoint. let app = test::init_service( diff --git a/core/src/ten_manager/tests/test_case/designer/messages/compatible.rs b/core/src/ten_manager/tests/test_case/designer/messages/compatible.rs index abc0eeebe..8900b5687 100644 --- a/core/src/ten_manager/tests/test_case/designer/messages/compatible.rs +++ b/core/src/ten_manager/tests/test_case/designer/messages/compatible.rs @@ -5,13 +5,13 @@ // Refer to the "LICENSE" file in the root directory for more information. // use std::collections::HashMap; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use actix_web::{test, web, App}; use serde_json::json; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::TEST_DIR, designer::{ messages::compatible::{ @@ -30,8 +30,10 @@ use crate::test_case::common::mock::inject_all_pkgs_for_mock; #[actix_web::test] async fn test_get_compatible_messages_success() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -99,7 +101,7 @@ async fn test_get_compatible_messages_success() { graph_id.expect("Default graph should exist") }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -154,8 +156,10 @@ async fn test_get_compatible_messages_success() { #[actix_web::test] async fn test_get_compatible_messages_fail() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -220,7 +224,7 @@ async fn test_get_compatible_messages_fail() { .expect("Default graph should exist") }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -255,8 +259,10 @@ async fn test_get_compatible_messages_fail() { #[actix_web::test] async fn test_get_compatible_messages_cmd_has_required_success_1() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -321,7 +327,7 @@ async fn test_get_compatible_messages_cmd_has_required_success_1() { .expect("Default graph should exist") }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -379,8 +385,10 @@ async fn test_get_compatible_messages_cmd_has_required_success_1() { #[actix_web::test] async fn test_get_compatible_messages_cmd_has_required_success_2() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -445,7 +453,7 @@ async fn test_get_compatible_messages_cmd_has_required_success_2() { .expect("Default graph should exist") }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -503,8 +511,10 @@ async fn test_get_compatible_messages_cmd_has_required_success_2() { #[actix_web::test] async fn test_get_compatible_messages_cmd_has_required_success_3() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -569,7 +579,7 @@ async fn test_get_compatible_messages_cmd_has_required_success_3() { .expect("Default graph should exist") }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( @@ -627,8 +637,10 @@ async fn test_get_compatible_messages_cmd_has_required_success_3() { #[actix_web::test] async fn test_get_compatible_messages_cmd_has_required_success_4() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -693,7 +705,7 @@ async fn test_get_compatible_messages_cmd_has_required_success_4() { .expect("Default graph should exist") }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new().app_data(web::Data::new(designer_state)).route( diff --git a/core/src/ten_manager/tests/test_case/designer/mod.rs b/core/src/ten_manager/tests/test_case/designer/mod.rs index d63a2602c..d158adb9c 100644 --- a/core/src/ten_manager/tests/test_case/designer/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/mod.rs @@ -17,10 +17,10 @@ mod get_packages_scripts; mod get_registry_packages; mod graphs; mod help_text; -mod internal_config; mod load_apps; mod manifest; mod messages; +mod metadata; mod preferences; mod property; mod reload_apps; diff --git a/core/src/ten_manager/tests/test_case/designer/preferences/mod.rs b/core/src/ten_manager/tests/test_case/designer/preferences/mod.rs index ebea1de85..35daf8803 100644 --- a/core/src/ten_manager/tests/test_case/designer/preferences/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/preferences/mod.rs @@ -10,7 +10,7 @@ use std::sync::{Arc, RwLock}; use actix_web::{test, web, App}; use serde_json::{self, json}; -use ten_manager::config::internal::TmanInternalConfig; +use ten_manager::config::metadata::TmanMetadata; use ten_manager::{ config::TmanConfig, designer::{ @@ -36,13 +36,15 @@ use ten_manager::{ #[actix_web::test] async fn test_get_preferences_success() { // Create test state. - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = test::init_service( @@ -85,8 +87,10 @@ async fn test_get_preferences_success() { async fn test_get_preferences_invalid_path() { // Create test state. let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -180,13 +184,15 @@ async fn test_update_preferences_success() { ..TmanConfig::default() }; - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = test::init_service( @@ -226,19 +232,12 @@ async fn test_update_preferences_success() { // Verify config was updated (though we're not actually writing to file // in test). - let state_read = state - .read() - .map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - }) - .expect("Failed to acquire read lock"); - - assert_eq!(state_read.tman_config.designer.logviewer_line_size, 2000); + assert_eq!( + state.tman_config.read().await.designer.logviewer_line_size, + 2000 + ); assert!(matches!( - state_read.tman_config.designer.locale, + state.tman_config.read().await.designer.locale, Locale::EnUs )); } @@ -251,13 +250,15 @@ async fn test_update_preferences_invalid_schema() { ..TmanConfig::default() }; - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = @@ -299,13 +300,15 @@ async fn test_update_preferences_field_success() { ..TmanConfig::default() }; - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = test::init_service( @@ -343,17 +346,10 @@ async fn test_update_preferences_field_success() { // Verify config was updated (though we're not actually writing to file // in test). - let state_read = state - .read() - .map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - }) - .expect("Failed to acquire read lock"); - - assert_eq!(state_read.tman_config.designer.logviewer_line_size, 2000); + assert_eq!( + state.tman_config.read().await.designer.logviewer_line_size, + 2000 + ); } #[actix_web::test] @@ -364,13 +360,15 @@ async fn test_update_preferences_field_invalid_value() { ..TmanConfig::default() }; - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = @@ -408,13 +406,15 @@ async fn test_update_preferences_field_invalid_field() { ..TmanConfig::default() }; - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = @@ -457,13 +457,15 @@ async fn test_update_preferences_field_locale() { ..TmanConfig::default() }; - let state = Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(config), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new(config)), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - })); + }); // Create test app. let app = test::init_service( @@ -501,18 +503,8 @@ async fn test_update_preferences_field_locale() { // Verify config was updated (though we're not actually writing to file // in test). - let state_read = state - .read() - .map_err(|e| { - actix_web::error::ErrorInternalServerError(format!( - "Failed to acquire read lock: {}", - e - )) - }) - .expect("Failed to acquire read lock"); - assert!(matches!( - state_read.tman_config.designer.locale, + state.tman_config.read().await.designer.locale, Locale::ZhCn )); } diff --git a/core/src/ten_manager/tests/test_case/designer/property/validate.rs b/core/src/ten_manager/tests/test_case/designer/property/validate.rs index 1a2402f1b..f8fa648cf 100644 --- a/core/src/ten_manager/tests/test_case/designer/property/validate.rs +++ b/core/src/ten_manager/tests/test_case/designer/property/validate.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ property::validate::{ validate_property_endpoint, ValidatePropertyRequestPayload, @@ -27,13 +24,17 @@ mod tests { async fn test_validate_property_valid_empty() { // Setup. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -67,13 +68,17 @@ mod tests { async fn test_validate_property_valid_with_basic_fields() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -117,13 +122,17 @@ mod tests { async fn test_validate_property_valid_with_ten_field() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -170,13 +179,17 @@ mod tests { async fn test_validate_property_valid_with_predefined_graphs() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -229,13 +242,17 @@ mod tests { async fn test_validate_property_invalid_json_syntax() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -276,13 +293,17 @@ mod tests { async fn test_validate_property_invalid_additional_properties() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -336,13 +357,17 @@ mod tests { async fn test_validate_property_invalid_non_alphanumeric_field() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( @@ -408,13 +433,17 @@ mod tests { async fn test_validate_property_invalid_missing_required_fields() { // Setup let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let state = web::Data::new(Arc::new(RwLock::new(designer_state))); + let state = web::Data::new(Arc::new(designer_state)); let app = test::init_service( App::new().app_data(state.clone()).service( diff --git a/core/src/ten_manager/tests/test_case/designer/reload_apps.rs b/core/src/ten_manager/tests/test_case/designer/reload_apps.rs index 5a70f4488..4f26bb2c9 100644 --- a/core/src/ten_manager/tests/test_case/designer/reload_apps.rs +++ b/core/src/ten_manager/tests/test_case/designer/reload_apps.rs @@ -6,14 +6,11 @@ // #[cfg(test)] mod tests { - use std::{ - collections::HashMap, - sync::{Arc, RwLock}, - }; + use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, designer::{ apps::reload::{reload_app_endpoint, ReloadPkgsRequestPayload}, response::{ApiResponse, Status}, @@ -28,8 +25,12 @@ mod tests { async fn test_reload_app_success_with_base_dir() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -54,7 +55,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -93,8 +94,7 @@ mod tests { // Verify that the package cache still contains the base_dir entry // (it was reloaded, not removed). - let state_read = designer_state.read().unwrap(); - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = designer_state.pkgs_cache.read().await; assert!(pkgs_cache.contains_key("tests/test_data/app_with_uri")); } @@ -104,8 +104,12 @@ mod tests { async fn test_reload_app_success_without_base_dir() { // Set up the designer state with initial data. let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), @@ -130,7 +134,7 @@ mod tests { ); } - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); // Set up the test service. let app = test::init_service( @@ -166,8 +170,7 @@ mod tests { assert_eq!(api_response.data, "Packages reloaded successfully"); // Verify that the package cache still contains the base_dir entry. - let state_read = designer_state.read().unwrap(); - let pkgs_cache = state_read.pkgs_cache.read().await; + let pkgs_cache = designer_state.pkgs_cache.read().await; assert!(pkgs_cache.contains_key("tests/test_data/app_with_uri")); } } diff --git a/core/src/ten_manager/tests/test_case/designer/template_pkgs/mod.rs b/core/src/ten_manager/tests/test_case/designer/template_pkgs/mod.rs index b26e96a2d..de2ce1a6d 100644 --- a/core/src/ten_manager/tests/test_case/designer/template_pkgs/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/template_pkgs/mod.rs @@ -4,15 +4,12 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; +use std::{collections::HashMap, sync::Arc}; use actix_web::{http::StatusCode, test, web, App}; use ten_manager::{ - config::{internal::TmanInternalConfig, TmanConfig}, + config::{metadata::TmanMetadata, TmanConfig}, constants::{DEFAULT_APP_NODEJS, DEFAULT_EXTENSION_CPP}, designer::{ response::{ApiResponse, Status}, @@ -29,13 +26,15 @@ use ten_rust::pkg_info::pkg_type::PkgType; #[actix_web::test] async fn test_get_template_app_typescript() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -70,13 +69,15 @@ async fn test_get_template_app_typescript() { #[actix_web::test] async fn test_get_template_extension_cpp() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() @@ -111,13 +112,15 @@ async fn test_get_template_extension_cpp() { #[actix_web::test] async fn test_get_template_unsupported() { let designer_state = DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + tman_config: Arc::new(tokio::sync::RwLock::new(TmanConfig::default())), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), }; - let designer_state = Arc::new(RwLock::new(designer_state)); + let designer_state = Arc::new(designer_state); let app = test::init_service( App::new() diff --git a/core/src/ten_manager/tests/test_case/designer/version/mod.rs b/core/src/ten_manager/tests/test_case/designer/version/mod.rs index 5d0a1a165..0043b79b4 100644 --- a/core/src/ten_manager/tests/test_case/designer/version/mod.rs +++ b/core/src/ten_manager/tests/test_case/designer/version/mod.rs @@ -7,12 +7,12 @@ #[cfg(test)] mod tests { use std::collections::HashMap; - use std::sync::{Arc, RwLock}; + use std::sync::Arc; use actix_web::{http::StatusCode, test, web, App}; use serde::{Deserialize, Serialize}; - use ten_manager::config::internal::TmanInternalConfig; + use ten_manager::config::metadata::TmanMetadata; use ten_manager::{ config::TmanConfig, designer::{ @@ -30,13 +30,17 @@ mod tests { #[actix_web::test] async fn test_get_version() { // Initialize the DesignerState. - let state = web::Data::new(Arc::new(RwLock::new(DesignerState { - tman_config: Arc::new(TmanConfig::default()), - tman_internal_config: Arc::new(TmanInternalConfig::default()), + let state = web::Data::new(Arc::new(DesignerState { + tman_config: Arc::new(tokio::sync::RwLock::new( + TmanConfig::default(), + )), + tman_metadata: Arc::new(tokio::sync::RwLock::new( + TmanMetadata::default(), + )), out: Arc::new(Box::new(TmanOutputCli)), pkgs_cache: tokio::sync::RwLock::new(HashMap::new()), graphs_cache: tokio::sync::RwLock::new(HashMap::new()), - }))); + })); // Create the App with the routes configured. let app = test::init_service(App::new().app_data(state.clone()).route( From 4b485b9aa91c4cf1cbd0e8e3a784766cef255f93 Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 20:45:03 +0800 Subject: [PATCH 3/8] fix: refine codes --- .../src/ten_manager/src/graph/connections/mod.rs | 9 +++++++-- core/src/ten_manager/src/graph/mod.rs | 5 ++++- core/src/ten_manager/src/graph/nodes/mod.rs | 6 ++++-- core/src/ten_rust/src/_0_8_compatible.rs | 16 ++++++++++++++++ core/src/ten_rust/src/lib.rs | 1 + core/src/ten_rust/src/pkg_info/constants.rs | 2 ++ core/src/ten_rust/src/pkg_info/property/mod.rs | 12 ++++++++---- 7 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 core/src/ten_rust/src/_0_8_compatible.rs diff --git a/core/src/ten_manager/src/graph/connections/mod.rs b/core/src/ten_manager/src/graph/connections/mod.rs index b2faf53aa..fff9ac156 100644 --- a/core/src/ten_manager/src/graph/connections/mod.rs +++ b/core/src/ten_manager/src/graph/connections/mod.rs @@ -10,7 +10,10 @@ pub mod validate; use anyhow::Result; use serde_json::Value; -use ten_rust::graph::connection::{GraphConnection, GraphMessageFlow}; +use ten_rust::{ + _0_8_compatible::get_ten_field_string, + graph::connection::{GraphConnection, GraphMessageFlow}, +}; use crate::json::write_property_json_file; @@ -30,7 +33,9 @@ pub fn update_graph_connections_all_fields( connections_to_modify_msg_conversion: Option<&[GraphConnection]>, ) -> Result<()> { // Get ten object if it exists. - let ten_obj = match property_all_fields.get_mut("ten") { + let ten_field_str = get_ten_field_string(); + + let ten_obj = match property_all_fields.get_mut(&ten_field_str) { Some(Value::Object(obj)) => obj, _ => return write_property_json_file(pkg_url, property_all_fields), }; diff --git a/core/src/ten_manager/src/graph/mod.rs b/core/src/ten_manager/src/graph/mod.rs index 5f761d5ea..f2996171c 100644 --- a/core/src/ten_manager/src/graph/mod.rs +++ b/core/src/ten_manager/src/graph/mod.rs @@ -12,6 +12,7 @@ pub mod nodes; use std::collections::HashMap; use anyhow::{anyhow, Result}; +use ten_rust::_0_8_compatible::get_ten_field_string; use uuid::Uuid; pub use connections::update_graph_connections_all_fields; @@ -135,7 +136,9 @@ pub fn update_graph_all_fields( connections: &[GraphConnection], ) -> Result<()> { // Get ten object if it exists. - let ten_obj = match property_all_fields.get_mut("ten") { + let ten_field_str = get_ten_field_string(); + + let ten_obj = match property_all_fields.get_mut(&ten_field_str) { Some(serde_json::Value::Object(obj)) => obj, _ => return write_property_json_file(pkg_url, property_all_fields), }; diff --git a/core/src/ten_manager/src/graph/nodes/mod.rs b/core/src/ten_manager/src/graph/nodes/mod.rs index 7b5f51909..57c9a73b0 100644 --- a/core/src/ten_manager/src/graph/nodes/mod.rs +++ b/core/src/ten_manager/src/graph/nodes/mod.rs @@ -12,7 +12,7 @@ use std::str::FromStr; use anyhow::Result; use serde_json::Value; -use ten_rust::graph::node::GraphNode; +use ten_rust::{_0_8_compatible::get_ten_field_string, graph::node::GraphNode}; use crate::json::write_property_json_file; @@ -35,7 +35,9 @@ pub fn update_graph_node_all_fields( nodes_to_modify: Option<&[GraphNode]>, ) -> Result<()> { // Get the ten object from property_all_fields. - let ten_obj = match property_all_fields.get_mut("ten") { + let ten_field_str = get_ten_field_string(); + + let ten_obj = match property_all_fields.get_mut(&ten_field_str) { Some(Value::Object(obj)) => obj, _ => { // Write back the unchanged property and return diff --git a/core/src/ten_rust/src/_0_8_compatible.rs b/core/src/ten_rust/src/_0_8_compatible.rs new file mode 100644 index 000000000..7da86d3e0 --- /dev/null +++ b/core/src/ten_rust/src/_0_8_compatible.rs @@ -0,0 +1,16 @@ +// +// 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. +// +use std::env; + +use crate::pkg_info::constants::TEN_FIELD_IN_PROPERTY; + +pub fn get_ten_field_string() -> String { + match env::var("TMAN_08_COMPATIBLE") { + Ok(val) if val == "true" => "_ten".to_string(), + _ => TEN_FIELD_IN_PROPERTY.to_string(), + } +} diff --git a/core/src/ten_rust/src/lib.rs b/core/src/ten_rust/src/lib.rs index 498b43495..f702171b0 100644 --- a/core/src/ten_rust/src/lib.rs +++ b/core/src/ten_rust/src/lib.rs @@ -4,6 +4,7 @@ // Licensed under the Apache License, Version 2.0, with certain conditions. // Refer to the "LICENSE" file in the root directory for more information. // +pub mod _0_8_compatible; pub mod base_dir_pkg_info; mod bindings; pub mod constants; diff --git a/core/src/ten_rust/src/pkg_info/constants.rs b/core/src/ten_rust/src/pkg_info/constants.rs index 737af2e47..90edd910f 100644 --- a/core/src/ten_rust/src/pkg_info/constants.rs +++ b/core/src/ten_rust/src/pkg_info/constants.rs @@ -15,3 +15,5 @@ pub const EXTENSION_DIR: &str = "extension"; pub const PROTOCOL_DIR: &str = "protocol"; pub const ADDON_LOADER_DIR: &str = "addon_loader"; pub const SYSTEM_DIR: &str = "system"; + +pub const TEN_STR_PREDEFINED_GRAPHS: &str = "predefined_graphs"; diff --git a/core/src/ten_rust/src/pkg_info/property/mod.rs b/core/src/ten_rust/src/pkg_info/property/mod.rs index cd1ffa884..a19acbea4 100644 --- a/core/src/ten_rust/src/pkg_info/property/mod.rs +++ b/core/src/ten_rust/src/pkg_info/property/mod.rs @@ -16,10 +16,12 @@ use serde_json::{Map, Value}; use uuid::Uuid; use super::{ - constants::{PROPERTY_JSON_FILENAME, TEN_FIELD_IN_PROPERTY}, + constants::{PROPERTY_JSON_FILENAME, TEN_STR_PREDEFINED_GRAPHS}, pkg_type::PkgType, }; -use crate::{fs::read_file_to_string, json_schema}; +use crate::{ + _0_8_compatible::get_ten_field_string, fs::read_file_to_string, json_schema, +}; use crate::{ graph::{graph_info::GraphInfo, is_app_default_loc_or_none}, json_schema::ten_validate_property_json_string, @@ -66,8 +68,10 @@ pub fn parse_property_from_str( let mut property: Property = serde_json::from_str(s)?; + let ten_field_str = get_ten_field_string(); + // Extract ten field from all_fields if it exists. - if let Some(ten_value) = property.all_fields.get(TEN_FIELD_IN_PROPERTY) { + if let Some(ten_value) = property.all_fields.get(&ten_field_str) { // Process the ten field manually instead of using // serde_json::from_value directly. Create a TenInProperty with empty // predefined_graphs. @@ -80,7 +84,7 @@ pub fn parse_property_from_str( if let Value::Object(map) = ten_value { // Extract and process predefined_graphs specially. if let Some(Value::Array(graphs_array)) = - map.get("predefined_graphs") + map.get(TEN_STR_PREDEFINED_GRAPHS) { let mut graph_infos = Vec::new(); From c98a643f79a436daa4beb990719cc134bdb6071a Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 21:08:51 +0800 Subject: [PATCH 4/8] fix: refine codes --- core/src/ten_manager/src/cmd/cmd_install.rs | 2 -- .../ten_manager/src/designer/builtin_function/install_all.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/ten_manager/src/cmd/cmd_install.rs b/core/src/ten_manager/src/cmd/cmd_install.rs index f9050a1e8..554d8adc2 100644 --- a/core/src/ten_manager/src/cmd/cmd_install.rs +++ b/core/src/ten_manager/src/cmd/cmd_install.rs @@ -363,8 +363,6 @@ pub async fn execute_cmd( ) -> Result<()> { if is_verbose(tman_config.clone()).await { out.normal_line("Executing install command"); - out.normal_line(&format!("command_data: {:?}", command_data)); - out.normal_line(&format!("tman_config: {:?}", tman_config)); } let started = Instant::now(); diff --git a/core/src/ten_manager/src/designer/builtin_function/install_all.rs b/core/src/ten_manager/src/designer/builtin_function/install_all.rs index ad0b7a6c3..642039e08 100644 --- a/core/src/ten_manager/src/designer/builtin_function/install_all.rs +++ b/core/src/ten_manager/src/designer/builtin_function/install_all.rs @@ -39,7 +39,7 @@ impl WsBuiltinFunction { let addr = addr.clone(); - // Clone the tman_config to avoid borrowing self in the async task. + // Clone the config and metadata before the async block. let tman_config = self.tman_config.clone(); let tman_metadata = self.tman_metadata.clone(); From 858d306c3e555b0356598d464799c3c6c8896dee Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 21:18:04 +0800 Subject: [PATCH 5/8] fix: refine codes --- core/src/ten_manager/src/designer/exec/mod.rs | 117 ++++++++++++++---- 1 file changed, 96 insertions(+), 21 deletions(-) diff --git a/core/src/ten_manager/src/designer/exec/mod.rs b/core/src/ten_manager/src/designer/exec/mod.rs index 832bab6e3..542dcc96c 100644 --- a/core/src/ten_manager/src/designer/exec/mod.rs +++ b/core/src/ten_manager/src/designer/exec/mod.rs @@ -11,7 +11,7 @@ mod run_script; use std::process::Child; use std::sync::Arc; -use actix::{Actor, Handler, Message, StreamHandler}; +use actix::{Actor, AsyncContext, Handler, Message, StreamHandler}; use actix_web::{web, Error, HttpRequest, HttpResponse}; use actix_web_actors::ws; use anyhow::Context; @@ -34,8 +34,18 @@ pub enum RunCmdOutput { /// `CmdParser` returns a tuple: the 1st element is the command string, and /// the 2nd is an optional working directory. -pub type CmdParser = - Box Result<(String, Option)> + Send + Sync>; +pub type CmdParser = Box< + dyn Fn( + &str, + ) -> std::pin::Pin< + Box< + dyn std::future::Future< + Output = Result<(String, Option)>, + > + Send, + >, + > + Send + + Sync, +>; pub struct WsRunCmd { child: Option, @@ -124,21 +134,29 @@ impl StreamHandler> for WsRunCmd { ctx: &mut Self::Context, ) { match item { - Ok(ws::Message::Text(text)) => match (self.cmd_parser)(&text) { - Ok((cmd, working_directory)) => { - if let Some(dir) = working_directory { - self.working_directory = Some(dir); - } + Ok(ws::Message::Text(text)) => { + let fut = (self.cmd_parser)(&text); + let actor_addr = ctx.address(); - self.cmd_run(&cmd, ctx); - } - Err(e) => { - let err_out = OutboundMsg::Error { msg: e.to_string() }; - let out_str = serde_json::to_string(&err_out).unwrap(); - ctx.text(out_str); - ctx.close(None); - } - }, + actix::spawn(async move { + match fut.await { + Ok((cmd, working_directory)) => { + actor_addr.do_send(ProcessCommand { + cmd, + working_directory, + }); + } + Err(e) => { + let err_out = + OutboundMsg::Error { msg: e.to_string() }; + let out_str = + serde_json::to_string(&err_out).unwrap(); + actor_addr.do_send(SendText(out_str)); + actor_addr.do_send(CloseConnection); + } + } + }); + } Ok(ws::Message::Ping(msg)) => ctx.pong(&msg), Ok(ws::Message::Close(_)) => { ctx.close(None); @@ -149,6 +167,62 @@ impl StreamHandler> for WsRunCmd { } } +// New message types for async communication. +#[derive(Message)] +#[rtype(result = "()")] +struct ProcessCommand { + cmd: String, + working_directory: Option, +} + +#[derive(Message)] +#[rtype(result = "()")] +struct SendText(String); + +#[derive(Message)] +#[rtype(result = "()")] +struct CloseConnection; + +impl Handler for WsRunCmd { + type Result = (); + + fn handle( + &mut self, + msg: SendText, + ctx: &mut Self::Context, + ) -> Self::Result { + ctx.text(msg.0); + } +} + +impl Handler for WsRunCmd { + type Result = (); + + fn handle( + &mut self, + _: CloseConnection, + ctx: &mut Self::Context, + ) -> Self::Result { + ctx.close(None); + } +} + +impl Handler for WsRunCmd { + type Result = (); + + fn handle( + &mut self, + msg: ProcessCommand, + ctx: &mut Self::Context, + ) -> Self::Result { + if let Some(dir) = msg.working_directory { + self.working_directory = Some(dir); + } + + self.cmd_run(&msg.cmd, ctx); + } +} + pub async fn exec_endpoint( req: HttpRequest, stream: web::Payload, @@ -161,12 +235,13 @@ pub async fn exec_endpoint( let default_parser: CmdParser = Box::new(move |text: &str| { let state_clone_inner = state_clone.clone(); - let rt = tokio::runtime::Runtime::new().unwrap(); - rt.block_on(async { + let text_owned = text.to_owned(); + + Box::pin(async move { // Attempt to parse the JSON text from client. - let inbound = serde_json::from_str::(text) + let inbound = serde_json::from_str::(&text_owned) .with_context(|| { - format!("Failed to parse {} into JSON", text) + format!("Failed to parse {} into JSON", text_owned) })?; match inbound { From b9d2993ec8e5153e9d77c150891ff30a52e805ec Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 21:21:12 +0800 Subject: [PATCH 6/8] fix: refine codes --- core/src/ten_manager/src/main.rs | 36 +++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/core/src/ten_manager/src/main.rs b/core/src/ten_manager/src/main.rs index cd240a4aa..94d641651 100644 --- a/core/src/ten_manager/src/main.rs +++ b/core/src/ten_manager/src/main.rs @@ -7,6 +7,7 @@ use std::process; use std::sync::Arc; +use anyhow::Result; use console::Emoji; use ten_manager::cmd::execute_cmd; use ten_manager::config::metadata::TmanMetadata; @@ -18,10 +19,11 @@ use ten_manager::output::{TmanOutput, TmanOutputCli}; use ten_manager::version::VERSION; use ten_manager::version_utils::check_update; -fn check_update_from_cmdline(out: Arc>) { +fn check_update_from_cmdline(out: Arc>) -> Result<()> { out.normal_line("Checking for new version..."); - let rt = Runtime::new().unwrap(); + let rt = Runtime::new()?; + match rt.block_on(check_update()) { Ok((true, latest)) => { out.normal_line(&format!( @@ -36,6 +38,8 @@ fn check_update_from_cmdline(out: Arc>) { out.normal_line(&err_msg.to_string()); } } + + Ok(()) } fn main() { @@ -53,13 +57,31 @@ fn main() { out.normal_line(&format!("TEN Framework version: {}", VERSION)); // Call the update check function - check_update_from_cmdline(out.clone()); - - // If `--version` is passed, ignore other parameters and exit directly. - std::process::exit(0); + match check_update_from_cmdline(out.clone()) { + Ok(_) => { + // If `--version` is passed, ignore other parameters and exit + // directly. + process::exit(0); + } + Err(e) => { + out.error_line(&format!( + "{} Error: {}", + Emoji("🔴", ":-("), + e + )); + process::exit(1); + } + } } - let rt = Runtime::new().unwrap(); + let rt = match Runtime::new() { + Ok(rt) => rt, + Err(e) => { + out.error_line(&format!("{} Error: {}", Emoji("🔴", ":-("), e)); + process::exit(1); + } + }; + let result = rt.block_on(execute_cmd( parsed_cmd.tman_config, Arc::new(tokio::sync::RwLock::new(TmanMetadata::default())), From d170cfe614827f2d350d5fb96d01253ef4cc2e4c Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 21:31:57 +0800 Subject: [PATCH 7/8] fix: refine codes --- .../src/designer/builtin_function/install_all.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/ten_manager/src/designer/builtin_function/install_all.rs b/core/src/ten_manager/src/designer/builtin_function/install_all.rs index 642039e08..66dd4b11a 100644 --- a/core/src/ten_manager/src/designer/builtin_function/install_all.rs +++ b/core/src/ten_manager/src/designer/builtin_function/install_all.rs @@ -43,8 +43,9 @@ impl WsBuiltinFunction { let tman_config = self.tman_config.clone(); let tman_metadata = self.tman_metadata.clone(); - // Call `execute_cmd()` in an async task. + // Use tokio::task::spawn_local to handle the non-Send clingo parts. tokio::task::spawn_local(async move { + // Now perform the actual work. let result = crate::cmd::cmd_install::execute_cmd( tman_config, tman_metadata, @@ -53,8 +54,7 @@ impl WsBuiltinFunction { ) .await; - // Notify the WebSocket client that the task is complete, and - // determine the exit code based on the result. + // Notify the WebSocket client that the task is complete. let exit_code = if result.is_ok() { 0 } else { -1 }; let error_message = if let Err(err) = result { Some(err.to_string()) From 5f781a102d777ffcf50d5302bf484ded410ef12b Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sat, 19 Apr 2025 21:48:49 +0800 Subject: [PATCH 8/8] fix: refine codes --- .../src/designer/builtin_function/install.rs | 13 +++++++++++-- .../src/designer/builtin_function/install_all.rs | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/core/src/ten_manager/src/designer/builtin_function/install.rs b/core/src/ten_manager/src/designer/builtin_function/install.rs index 3bb256cc1..4b42c4831 100644 --- a/core/src/ten_manager/src/designer/builtin_function/install.rs +++ b/core/src/ten_manager/src/designer/builtin_function/install.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use actix::AsyncContext; use actix_web_actors::ws::WebsocketContext; +use tokio::task::LocalSet; use ten_rust::pkg_info::manifest::support::ManifestSupport; @@ -52,8 +53,11 @@ impl WsBuiltinFunction { let tman_config = self.tman_config.clone(); let tman_metadata = self.tman_metadata.clone(); - // Call `execute_cmd()` in an async task. - tokio::task::spawn_local(async move { + // Create a LocalSet to ensure spawn_local runs on this thread. + let local = LocalSet::new(); + + // Spawn the task within the LocalSet context. + local.spawn_local(async move { let result = crate::cmd::cmd_install::execute_cmd( tman_config, tman_metadata, @@ -75,5 +79,10 @@ impl WsBuiltinFunction { error_message, }); }); + + // Use spawn to run the LocalSet in the background. + actix_web::rt::spawn(async move { + local.await; + }); } } diff --git a/core/src/ten_manager/src/designer/builtin_function/install_all.rs b/core/src/ten_manager/src/designer/builtin_function/install_all.rs index 66dd4b11a..b6bf4c512 100644 --- a/core/src/ten_manager/src/designer/builtin_function/install_all.rs +++ b/core/src/ten_manager/src/designer/builtin_function/install_all.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use actix::AsyncContext; use actix_web_actors::ws::WebsocketContext; +use tokio::task::LocalSet; use ten_rust::pkg_info::manifest::support::ManifestSupport; @@ -43,8 +44,11 @@ impl WsBuiltinFunction { let tman_config = self.tman_config.clone(); let tman_metadata = self.tman_metadata.clone(); - // Use tokio::task::spawn_local to handle the non-Send clingo parts. - tokio::task::spawn_local(async move { + // Create a LocalSet to ensure spawn_local runs on this thread. + let local = LocalSet::new(); + + // Spawn the task within the LocalSet context. + local.spawn_local(async move { // Now perform the actual work. let result = crate::cmd::cmd_install::execute_cmd( tman_config, @@ -66,5 +70,10 @@ impl WsBuiltinFunction { error_message, }); }); + + // Use spawn to run the LocalSet in the background. + actix_web::rt::spawn(async move { + local.await; + }); } }