From cedb1b3abda12866d384c444fe6a48ab54d5eb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 23 Aug 2023 20:33:43 +0200 Subject: [PATCH 01/24] begining with test server_initializer_collected_params_combine_vlcs_properly --- .../node_configurator_standard.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 1094f7f18..1fbca988f 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -737,6 +737,47 @@ mod tests { assert_eq!(config.crash_point, CrashPoint::Panic); } + #[test] + fn server_initializer_collected_params_combine_vlcs_properly () { + running_test(); + let home_dir = PathBuf::from("/unexisting_home/unexisting_alice"); + let data_dir = home_dir.join("data_dir"); + vec![ + ("MASQ_BLOCKCHAIN_SERVICE_URL", "https://example3.com"), + ("MASQ_CHAIN", TEST_DEFAULT_CHAIN.rec().literal_identifier), + ("MASQ_CLANDESTINE_PORT", "1234"), + ("MASQ_CONSUMING_PRIVATE_KEY", "0011223344556677001122334455667700112233445566770011223344556677"), + ("MASQ_CRASH_POINT", "Error"), + ("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), + ("MASQ_DB_PASSWORD", "password"), + ("MASQ_DNS_SERVERS", "8.8.8.8"), + ("MASQ_EARNING_WALLET", "0x0123456789012345678901234567890123456789"), + ("MASQ_GAS_PRICE", "50"), + ("MASQ_IP", "4.3.2.1"), + ("MASQ_LOG_LEVEL", "error"), + ("MASQ_MAPPING_PROTOCOL", "pmp"), + ("MASQ_MIN_HOPS", "2"), + ("MASQ_NEIGHBORHOOD_MODE", "originate-only"), + ("MASQ_NEIGHBORS", "masq://eth-ropsten:MTIzNDU2Nzg5MTEyMzQ1Njc4OTIxMjM0NTY3ODkzMTI@1.2.3.4:1234,masq://eth-ropsten:MTIzNDU2Nzg5MTEyMzQ1Njc4OTIxMjM0NTY3ODkzMTI@5.6.7.8:5678"), + ("MASQ_PAYMENT_THRESHOLDS","12345|50000|1000|1234|19000|20000"), + ("MASQ_RATE_PACK","1|3|3|8"), + #[cfg(not(target_os = "windows"))] + ("MASQ_REAL_USER", "9999:9999:booga"), + ("MASQ_SCANS", "off"), + ("MASQ_SCAN_INTERVALS","133|133|111") + ].into_iter() + .for_each (|(name, value)| std::env::set_var (name, value)); + let args = ArgsBuilder::new() + .param("--chain", "polygon-mainnet"); + let args_vec: Vec = args.into(); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(home_dir)) + .data_dir_result(Some(data_dir)); + let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + println!("full_multi_config: {:#?}",result.unwrap().multi_config); + + } + #[test] fn server_initializer_collected_params_senses_when_user_specifies_config_file() { running_test(); From 32dd2cbe99aa52a65d3ced0698e2e54f5513a9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Mon, 28 Aug 2023 18:09:16 +0200 Subject: [PATCH 02/24] removed GatheredParams from server_initializer_collected_params, added bools for data_dir, config_file and real_user to MultiConfig, fixing the test --- .../node_configurator_standard.rs | 175 +++++++++++++----- node/src/server_initializer.rs | 18 +- node/src/test_utils/mod.rs | 2 +- 3 files changed, 140 insertions(+), 55 deletions(-) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 1fbca988f..227467f83 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -10,7 +10,6 @@ use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; use std::net::{IpAddr, Ipv4Addr}; -use std::path::PathBuf; use clap::value_t; use log::LevelFilter; @@ -26,7 +25,6 @@ use crate::node_configurator::unprivileged_parse_args_configuration::{ use crate::node_configurator::{ data_directory_from_context, determine_fundamentals, real_user_data_directory_path_and_chain, }; -use crate::server_initializer::GatheredParams; use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::utils::make_new_multi_config; @@ -139,10 +137,10 @@ fn collect_externals_from_multi_config( pub fn server_initializer_collected_params<'a>( dirs_wrapper: &dyn DirsWrapper, args: &[String], -) -> Result, ConfiguratorError> { +) -> Result, ConfiguratorError> { let app = app_node(); - let (config_file_path, user_specified, data_directory, real_user) = + let (config_file_path, user_specified, data_directory, _real_user) = determine_fundamentals(dirs_wrapper, &app, args)?; let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { @@ -152,19 +150,15 @@ pub fn server_initializer_collected_params<'a>( let full_multi_config = make_new_multi_config( &app, vec![ - Box::new(CommandLineVcl::new(args.to_vec())), Box::new(EnvironmentVcl::new(&app)), config_file_vcl, + Box::new(CommandLineVcl::new(args.to_vec())), + Box::new(CommandLineVcl::new(vec![ + "--data-directory ".to_string() + data_directory.to_str().unwrap(), + ])), ], )?; - let config_file_path = - value_m!(full_multi_config, "config-file", PathBuf).expect("defaulted param"); - Ok(GatheredParams::new( - full_multi_config, - config_file_path, - real_user, - data_directory, - )) + Ok(full_multi_config) } pub fn establish_port_configurations(config: &mut BootstrapperConfig) { @@ -313,7 +307,7 @@ mod tests { use masq_lib::utils::{running_test, slice_of_strs_to_vec_of_strings}; use rustc_hex::FromHex; use std::convert::TryFrom; - use std::fs::File; + use std::fs::{create_dir_all, File}; use std::io::Write; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; @@ -473,13 +467,12 @@ mod tests { } let directory_wrapper = make_pre_populated_mocked_directory_wrapper(); - let gathered_params = server_initializer_collected_params( + let multi_config = server_initializer_collected_params( &directory_wrapper, &slice_of_strs_to_vec_of_strings(&["", "--data-directory", home_dir.to_str().unwrap()]), ) .unwrap(); - let multi_config = gathered_params.multi_config; assert_eq!( value_m!(multi_config, "dns-servers", String).unwrap(), "111.111.111.111,222.222.222.222".to_string() @@ -737,45 +730,133 @@ mod tests { assert_eq!(config.crash_point, CrashPoint::Panic); } + fn fill_up_config_file(mut config_file: File) { + { + config_file + .write_all(b"blockchain-service-url = \"https://www.mainnet.com\"\n") + .unwrap(); + config_file + .write_all(b"clandestine-port = \"7788\"\n") + .unwrap(); + config_file.write_all(b"consuming-private-key = \"00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF\"\n").unwrap(); + config_file.write_all(b"crash-point = \"None\"\n").unwrap(); + config_file + .write_all(b"dns-servers = \"5.6.7.8\"\n") + .unwrap(); + config_file + .write_all(b"earning-wallet = \"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n") + .unwrap(); + config_file.write_all(b"gas-price = \"77\"\n").unwrap(); + config_file.write_all(b"log-level = \"trace\"\n").unwrap(); + config_file + .write_all(b"mapping-protocol = \"pcp\"\n") + .unwrap(); + config_file.write_all(b"min-hops = \"6\"\n").unwrap(); + config_file + .write_all(b"neighborhood-mode = \"zero-hop\"\n") + .unwrap(); + config_file.write_all(b"scans = \"off\"\n").unwrap(); + config_file.write_all(b"rate-pack = \"2|2|2|2\"\n").unwrap(); + config_file + .write_all(b"payment-thresholds = \"3333|55|33|646|999|999\"\n") + .unwrap(); + config_file + .write_all(b"scan-intervals = \"111|100|99\"\n") + .unwrap() + } + } + #[test] fn server_initializer_collected_params_combine_vlcs_properly () { running_test(); - let home_dir = PathBuf::from("/unexisting_home/unexisting_alice"); - let data_dir = home_dir.join("data_dir"); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); + let data_dir = &home_dir.join("data_dir"); + let config_file = File::create(home_dir.join("config.toml")).unwrap(); + let data_dir_vcl = create_dir_all(PathBuf::from("/tmp/cooga/masqhome")); + { + fill_up_config_file(config_file); + match data_dir_vcl { + Ok(..) => { + let config_file_vcl = File::create(PathBuf::from("/tmp/cooga/masqhome").join("config.toml")).unwrap(); + fill_up_config_file(config_file_vcl); + } + Err(e) => panic!("unable to create directory {}", e) + } + } + vec![ - ("MASQ_BLOCKCHAIN_SERVICE_URL", "https://example3.com"), - ("MASQ_CHAIN", TEST_DEFAULT_CHAIN.rec().literal_identifier), - ("MASQ_CLANDESTINE_PORT", "1234"), - ("MASQ_CONSUMING_PRIVATE_KEY", "0011223344556677001122334455667700112233445566770011223344556677"), - ("MASQ_CRASH_POINT", "Error"), + ("MASQ_CONFIG_FILE", "config.toml"), ("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), - ("MASQ_DB_PASSWORD", "password"), - ("MASQ_DNS_SERVERS", "8.8.8.8"), - ("MASQ_EARNING_WALLET", "0x0123456789012345678901234567890123456789"), - ("MASQ_GAS_PRICE", "50"), - ("MASQ_IP", "4.3.2.1"), - ("MASQ_LOG_LEVEL", "error"), - ("MASQ_MAPPING_PROTOCOL", "pmp"), - ("MASQ_MIN_HOPS", "2"), - ("MASQ_NEIGHBORHOOD_MODE", "originate-only"), - ("MASQ_NEIGHBORS", "masq://eth-ropsten:MTIzNDU2Nzg5MTEyMzQ1Njc4OTIxMjM0NTY3ODkzMTI@1.2.3.4:1234,masq://eth-ropsten:MTIzNDU2Nzg5MTEyMzQ1Njc4OTIxMjM0NTY3ODkzMTI@5.6.7.8:5678"), - ("MASQ_PAYMENT_THRESHOLDS","12345|50000|1000|1234|19000|20000"), - ("MASQ_RATE_PACK","1|3|3|8"), #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), - ("MASQ_SCANS", "off"), - ("MASQ_SCAN_INTERVALS","133|133|111") ].into_iter() .for_each (|(name, value)| std::env::set_var (name, value)); - let args = ArgsBuilder::new() - .param("--chain", "polygon-mainnet"); + let args = ArgsBuilder::new(); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() - .home_dir_result(Some(home_dir)) - .data_dir_result(Some(data_dir)); + .home_dir_result(Some(home_dir.clone())) + .data_dir_result(Some(data_dir.to_path_buf())); let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - println!("full_multi_config: {:#?}",result.unwrap().multi_config); + let env_multicnfig = result.unwrap(); + + let args = ArgsBuilder::new() + .param("--config-file", "config.toml") + .param("--data-directory", "/tmp/cooga/masqhome") + .param("--real-user", "1001:1001:cooga"); + let args_vec: Vec = args.into(); + let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + let result = params.as_ref().expect("REASON"); + let vcl_multicnfig = result; + + //println!("env_multicnfig: {:#?}", env_multicnfig); + assert_eq!( + value_m!(env_multicnfig, "config-file", String).unwrap(), + "config.toml".to_string() + );/* + assert_eq!( + value_m!(env_multicnfig, "data-directory", String).unwrap(), + "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() + );*/ + #[cfg(not(target_os = "windows"))] + match env_multicnfig.real_user_specified { + true => { + assert_eq!( + value_m!(env_multicnfig, "real-user", String).unwrap(), + "9999:9999:booga".to_string() + ) + } + false => { + println!("real-user is not user specified"); + () + } + } + //println!("env_multicnfig: {:#?}", vcl_multicnfig); + #[cfg(not(target_os = "windows"))] + assert_eq!( + value_m!(vcl_multicnfig, "real-user", String).unwrap(), + "1001:1001:cooga".to_string() + ); + match vcl_multicnfig.data_directory_user_specified { + true => { + assert_eq!( + value_m!(vcl_multicnfig, "data-directory", String).unwrap(), + "/tmp/cooga/masqhome".to_string() + ) + } + false => { + println!("data-directory is not user specified"); + () + } + } + assert_eq!( + value_m!(vcl_multicnfig, "config-file", String).unwrap(), + "config.toml".to_string() + ); + assert_eq!( + value_m!(vcl_multicnfig, "real-user", String).unwrap(), + "1001:1001:cooga".to_string() + ); } #[test] @@ -1097,12 +1178,12 @@ mod tests { }; let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()) - .unwrap() - .data_directory - .to_string_lossy() - .to_string(); + .unwrap(); - assert_eq!(result, expected.unwrap()); + assert_eq!( + value_m!(result, "data-directory", String).unwrap(), + expected.unwrap() + ); } #[test] diff --git a/node/src/server_initializer.rs b/node/src/server_initializer.rs index 76a4c97d5..eac4a5ac0 100644 --- a/node/src/server_initializer.rs +++ b/node/src/server_initializer.rs @@ -8,6 +8,7 @@ use crate::node_configurator::{DirsWrapper, DirsWrapperReal}; use crate::run_modes_factories::{RunModeResult, ServerInitializer}; use crate::sub_lib::socket_server::ConfiguredByPrivilege; use backtrace::Backtrace; +use clap::value_t; use flexi_logger::{ Cleanup, Criterion, DeferredNow, Duplicate, LevelFilter, LogSpecBuilder, Logger, Naming, Record, }; @@ -37,34 +38,36 @@ pub struct ServerInitializerReal { impl ServerInitializer for ServerInitializerReal { fn go(&mut self, streams: &mut StdStreams<'_>, args: &[String]) -> RunModeResult { let params = server_initializer_collected_params(self.dirs_wrapper.as_ref(), args)?; + let real_user = value_m!(params, "real-user", RealUser).unwrap(); + let data_directory = value_m!(params, "data-directory", String).unwrap(); let result: RunModeResult = Ok(()) .combine_results( self.dns_socket_server .as_mut() - .initialize_as_privileged(¶ms.multi_config), + .initialize_as_privileged(¶ms), ) .combine_results( self.bootstrapper .as_mut() - .initialize_as_privileged(¶ms.multi_config), + .initialize_as_privileged(¶ms), ); self.privilege_dropper - .chown(¶ms.data_directory, ¶ms.real_user); + .chown(Path::new(data_directory.as_str()), &real_user); - self.privilege_dropper.drop_privileges(¶ms.real_user); + self.privilege_dropper.drop_privileges(&real_user); - result + result .combine_results( self.dns_socket_server .as_mut() - .initialize_as_unprivileged(¶ms.multi_config, streams), + .initialize_as_unprivileged(¶ms, streams), ) .combine_results( self.bootstrapper .as_mut() - .initialize_as_unprivileged(¶ms.multi_config, streams), + .initialize_as_unprivileged(¶ms, streams), ) } implement_as_any!(); @@ -115,6 +118,7 @@ impl ResultsCombiner for RunModeResult { } } +#[derive(Debug)] pub struct GatheredParams<'a> { pub multi_config: MultiConfig<'a>, pub config_file_path: PathBuf, diff --git a/node/src/test_utils/mod.rs b/node/src/test_utils/mod.rs index 3dfd8839e..0a382f353 100644 --- a/node/src/test_utils/mod.rs +++ b/node/src/test_utils/mod.rs @@ -643,7 +643,7 @@ pub mod unshared_test_utils { let mut app_args = vec!["MASQNode".to_string()]; app_args.append(&mut slice_of_strs_to_vec_of_strings(&args)); let arg_matches = app_node().get_matches_from_safe(app_args).unwrap(); - MultiConfig::new_test_only(arg_matches) + MultiConfig::new_test_only(arg_matches, false, false, false) } pub const ZERO: u32 = 0b0; From 690b099ef05ac16a42f82ba940a13388e080b6bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Tue, 29 Aug 2023 21:56:57 +0200 Subject: [PATCH 03/24] add ComputedVcl struct and its implementation, add VclType enum, to be able to push into Vcl Vector, add processing in MultiConfig, add processing in server_initializer_collected_params --- node/src/daemon/setup_reporter.rs | 6 +- node/src/node_configurator/mod.rs | 16 +++-- .../node_configurator_standard.rs | 67 ++++++++++++------- node/src/sub_lib/utils.rs | 3 +- node/src/test_utils/mod.rs | 4 +- 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/node/src/daemon/setup_reporter.rs b/node/src/daemon/setup_reporter.rs index f336864e9..287897738 100644 --- a/node/src/daemon/setup_reporter.rs +++ b/node/src/daemon/setup_reporter.rs @@ -18,7 +18,7 @@ use crate::node_configurator::unprivileged_parse_args_configuration::{ UnprivilegedParseArgsConfigurationDaoReal, }; use crate::node_configurator::{ - data_directory_from_context, determine_fundamentals, DirsWrapper, DirsWrapperReal, + data_directory_from_context, determine_user_specific_data, DirsWrapperReal, DirsWrapper }; use crate::sub_lib::accountant::PaymentThresholds as PaymentThresholdsFromAccountant; use crate::sub_lib::accountant::DEFAULT_SCAN_INTERVALS; @@ -495,8 +495,8 @@ impl SetupReporterReal { Some(command_line) => command_line, None => vec![], }; - let (config_file_path, user_specified, _data_directory, _real_user) = - determine_fundamentals(dirs_wrapper, &app, &command_line)?; + let (config_file_path, user_specified, _data_directory, _data_directory_specified, _real_user, _real_user_specified) = + determine_user_specific_data(dirs_wrapper, &app, &command_line)?; let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { Ok(cfv) => cfv, Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index e2baff293..a72ce5f97 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -29,11 +29,11 @@ pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } -pub fn determine_fundamentals( +pub fn determine_user_specific_data ( dirs_wrapper: &dyn DirsWrapper, app: &App, args: &[String], -) -> Result<(PathBuf, bool, PathBuf, RealUser), ConfiguratorError> { +) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool), ConfiguratorError> { let orientation_schema = App::new("MASQNode") .arg(chain_arg()) .arg(real_user_arg()) @@ -57,7 +57,9 @@ pub fn determine_fundamentals( let multi_config = make_new_multi_config(&orientation_schema, vec![Box::new(orientation_vcl)])?; let config_file_path = value_m!(multi_config, "config-file", PathBuf) .expect("config-file parameter is not properly defaulted by clap"); - let user_specified = multi_config.occurrences_of("config-file") > 0; + let config_user_specified = multi_config.occurrences_of("config-file") > 0; + let data_directory_specified = multi_config.occurrences_of("data-directory") > 0; + let real_user_specified = multi_config.occurrences_of("real-user") > 0; let (real_user, data_directory_path, chain) = real_user_data_directory_path_and_chain(dirs_wrapper, &multi_config); let data_directory = match data_directory_path { @@ -70,7 +72,7 @@ pub fn determine_fundamentals( config_file_path }; - Ok((config_file_path, user_specified, data_directory, real_user)) + Ok((config_file_path, config_user_specified, data_directory, data_directory_specified, real_user, real_user_specified)) } pub fn initialize_database( @@ -211,7 +213,7 @@ mod tests { .param("--config-file", "booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified) = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -240,7 +242,7 @@ mod tests { ); std::env::set_var("MASQ_CONFIG_FILE", "booga.toml"); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified) = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -263,7 +265,7 @@ mod tests { .param("--config-file", "/tmp/booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified) = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 227467f83..3b71b8eb3 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -5,7 +5,7 @@ use crate::node_configurator::DirsWrapperReal; use crate::node_configurator::{initialize_database, DirsWrapper, NodeConfigurator}; use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; -use masq_lib::multi_config::MultiConfig; +use masq_lib::multi_config::{ComputedVcl, MultiConfig}; use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; @@ -23,7 +23,7 @@ use crate::node_configurator::unprivileged_parse_args_configuration::{ UnprivilegedParseArgsConfiguration, UnprivilegedParseArgsConfigurationDaoReal, }; use crate::node_configurator::{ - data_directory_from_context, determine_fundamentals, real_user_data_directory_path_and_chain, + data_directory_from_context, determine_user_specific_data, real_user_data_directory_path_and_chain, }; use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::cryptde_null::CryptDENull; @@ -134,29 +134,47 @@ fn collect_externals_from_multi_config( ) } +#[derive(Clone)] +pub enum VclType { + Environment(EnvironmentVcl), + ConfigFile(ConfigFileVcl), + CommandLine(CommandLineVcl), + Computed(ComputedVcl), +} + pub fn server_initializer_collected_params<'a>( dirs_wrapper: &dyn DirsWrapper, args: &[String], ) -> Result, ConfiguratorError> { let app = app_node(); - let (config_file_path, user_specified, data_directory, _real_user) = - determine_fundamentals(dirs_wrapper, &app, args)?; - - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { - Ok(cfv) => Box::new(cfv), + let (config_file_path, config_user_specified, data_directory, data_directory_specified, real_user, real_user_specified) = + determine_user_specific_data(dirs_wrapper, &app, args)?; + println!("determine_user_specific_data data-dir: {}", data_directory.to_string_lossy()); + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, real_user_specified) { + Ok(cfv) => Box::new(VclType::ConfigFile(cfv)), Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; + + // let config_file_path_from_multiconfig = + // value_m!(multi_config, "config-file", PathBuf).expect("defaulted param"); + let mut vcl_vec: Vec> = vec![]; + vcl_vec.push(Box::new(VclType::Environment(EnvironmentVcl::new(&app)))); + vcl_vec.push(config_file_vcl); + vcl_vec.push(Box::new(VclType::CommandLine(CommandLineVcl::new(args.to_vec())))); + if data_directory_specified { + vcl_vec.push(Box::new(VclType::CommandLine(CommandLineVcl::new(vec![ + "--data-directory ".to_string() + data_directory.to_str().unwrap(), + ])))); + } else { + vcl_vec.push(Box::new(VclType::Computed(ComputedVcl::new(vec![ + "--data-directory ".to_string() + data_directory.to_str().unwrap(), + ])))); + + } let full_multi_config = make_new_multi_config( &app, - vec![ - Box::new(EnvironmentVcl::new(&app)), - config_file_vcl, - Box::new(CommandLineVcl::new(args.to_vec())), - Box::new(CommandLineVcl::new(vec![ - "--data-directory ".to_string() + data_directory.to_str().unwrap(), - ])), - ], + vcl_vec )?; Ok(full_multi_config) } @@ -767,17 +785,17 @@ mod tests { } #[test] - fn server_initializer_collected_params_combine_vlcs_properly () { + fn server_initializer_collected_params_combine_vlcs_properly() { running_test(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); let data_dir = &home_dir.join("data_dir"); let config_file = File::create(home_dir.join("config.toml")).unwrap(); - let data_dir_vcl = create_dir_all(PathBuf::from("/tmp/cooga/masqhome")); + let data_dir_vcl = create_dir_all(PathBuf::from("booga/data_dir/MASQ/polygon-mainnet")); { fill_up_config_file(config_file); match data_dir_vcl { Ok(..) => { - let config_file_vcl = File::create(PathBuf::from("/tmp/cooga/masqhome").join("config.toml")).unwrap(); + let config_file_vcl = File::create(PathBuf::from("booga/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); fill_up_config_file(config_file_vcl); } Err(e) => panic!("unable to create directory {}", e) @@ -785,8 +803,8 @@ mod tests { } vec![ - ("MASQ_CONFIG_FILE", "config.toml"), - ("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), + //("MASQ_CONFIG_FILE", "config.toml"), + //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), ].into_iter() @@ -800,8 +818,8 @@ mod tests { let env_multicnfig = result.unwrap(); let args = ArgsBuilder::new() - .param("--config-file", "config.toml") - .param("--data-directory", "/tmp/cooga/masqhome") + //.param("--config-file", "config.toml") + //.param("--data-directory", "/tmp/cooga/masqhome") .param("--real-user", "1001:1001:cooga"); let args_vec: Vec = args.into(); let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); @@ -818,7 +836,8 @@ mod tests { "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() );*/ #[cfg(not(target_os = "windows"))] - match env_multicnfig.real_user_specified { + //let real_user = value_m!(env_multicnfig, "real-user", String).unwrap(); + match env_multicnfig.is_user_specified("real-user") { true => { assert_eq!( value_m!(env_multicnfig, "real-user", String).unwrap(), @@ -837,7 +856,7 @@ mod tests { value_m!(vcl_multicnfig, "real-user", String).unwrap(), "1001:1001:cooga".to_string() ); - match vcl_multicnfig.data_directory_user_specified { + match vcl_multicnfig.is_user_specified("data-directory") { true => { assert_eq!( value_m!(vcl_multicnfig, "data-directory", String).unwrap(), diff --git a/node/src/sub_lib/utils.rs b/node/src/sub_lib/utils.rs index cad371e09..6e056eb6e 100644 --- a/node/src/sub_lib/utils.rs +++ b/node/src/sub_lib/utils.rs @@ -15,6 +15,7 @@ use std::io::ErrorKind; use std::marker::PhantomData; use std::path::Path; use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use crate::node_configurator::node_configurator_standard::VclType; static DEAD_STREAM_ERRORS: [ErrorKind; 5] = [ ErrorKind::BrokenPipe, @@ -93,7 +94,7 @@ pub fn to_string_s(data: &[u8]) -> String { pub fn make_new_multi_config<'a>( schema: &App<'a, 'a>, - vcls: Vec>, + vcls: Vec>, ) -> Result, ConfiguratorError> { MultiConfig::try_new(schema, vcls) } diff --git a/node/src/test_utils/mod.rs b/node/src/test_utils/mod.rs index 0a382f353..f8bf58b02 100644 --- a/node/src/test_utils/mod.rs +++ b/node/src/test_utils/mod.rs @@ -573,7 +573,7 @@ pub mod unshared_test_utils { use masq_lib::utils::slice_of_strs_to_vec_of_strings; use std::any::TypeId; use std::cell::RefCell; - use std::collections::HashMap; + use std::collections::{HashMap, HashSet}; use std::num::ParseIntError; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::path::{Path, PathBuf}; @@ -643,7 +643,7 @@ pub mod unshared_test_utils { let mut app_args = vec!["MASQNode".to_string()]; app_args.append(&mut slice_of_strs_to_vec_of_strings(&args)); let arg_matches = app_node().get_matches_from_safe(app_args).unwrap(); - MultiConfig::new_test_only(arg_matches, false, false, false) + MultiConfig::new_test_only(arg_matches, HashSet::new()) } pub const ZERO: u32 = 0b0; From 0d7427b59ea92ca4de9b0ba4e6a092fdce7f5117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 30 Aug 2023 18:14:23 +0200 Subject: [PATCH 04/24] back to VirtualCommandLine type without enum, passing different types to MultiConfig and selecting them to computed_value_names on behalf of their type --- .../node_configurator_standard.rs | 120 +++++++++--------- node/src/sub_lib/utils.rs | 3 +- 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 3b71b8eb3..b672f5d65 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -5,7 +5,7 @@ use crate::node_configurator::DirsWrapperReal; use crate::node_configurator::{initialize_database, DirsWrapper, NodeConfigurator}; use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; -use masq_lib::multi_config::{ComputedVcl, MultiConfig}; +use masq_lib::multi_config::{ComputedVcl, MultiConfig, VirtualCommandLine}; use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; @@ -134,48 +134,48 @@ fn collect_externals_from_multi_config( ) } -#[derive(Clone)] -pub enum VclType { - Environment(EnvironmentVcl), - ConfigFile(ConfigFileVcl), - CommandLine(CommandLineVcl), - Computed(ComputedVcl), -} - pub fn server_initializer_collected_params<'a>( dirs_wrapper: &dyn DirsWrapper, args: &[String], ) -> Result, ConfiguratorError> { let app = app_node(); - let (config_file_path, config_user_specified, data_directory, data_directory_specified, real_user, real_user_specified) = determine_user_specific_data(dirs_wrapper, &app, args)?; - println!("determine_user_specific_data data-dir: {}", data_directory.to_string_lossy()); - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, real_user_specified) { - Ok(cfv) => Box::new(VclType::ConfigFile(cfv)), + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, config_user_specified) { + Ok(cfv) => Box::new(cfv), Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; // let config_file_path_from_multiconfig = // value_m!(multi_config, "config-file", PathBuf).expect("defaulted param"); - let mut vcl_vec: Vec> = vec![]; - vcl_vec.push(Box::new(VclType::Environment(EnvironmentVcl::new(&app)))); - vcl_vec.push(config_file_vcl); - vcl_vec.push(Box::new(VclType::CommandLine(CommandLineVcl::new(args.to_vec())))); - if data_directory_specified { - vcl_vec.push(Box::new(VclType::CommandLine(CommandLineVcl::new(vec![ - "--data-directory ".to_string() + data_directory.to_str().unwrap(), - ])))); - } else { - vcl_vec.push(Box::new(VclType::Computed(ComputedVcl::new(vec![ - "--data-directory ".to_string() + data_directory.to_str().unwrap(), - ])))); + let mut full_multi_config_vec: Vec> = vec![ + Box::new(EnvironmentVcl::new(&app)), + config_file_vcl, + Box::new(CommandLineVcl::new(args.to_vec())), + ]; - } - let full_multi_config = make_new_multi_config( - &app, - vcl_vec - )?; + let data_directory_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ + "".to_string(), "--data-directory".to_string(), data_directory.to_string_lossy().to_string(), + ])); + let data_directory_unspcified_box: Box = Box::new(ComputedVcl::new(vec![ + "".to_string(), "--data-directory".to_string(), data_directory.to_string_lossy().to_string(), + ])); + match data_directory_specified { + true => full_multi_config_vec.push(data_directory_spcified_box), + false => full_multi_config_vec.push(data_directory_unspcified_box) + }; + let real_user_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ + "".to_string(), "--real-user".to_string(), real_user.to_string(), + ])); + let real_user_unspcified_box: Box = Box::new(ComputedVcl::new(vec![ + "".to_string(), "--real-user".to_string(), real_user.to_string(), + ])); + match real_user_specified { + true => full_multi_config_vec.push(real_user_spcified_box), + false => full_multi_config_vec.push(real_user_unspcified_box) + }; + let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; + //println!("full_multi_config: {:#?}", full_multi_config); Ok(full_multi_config) } @@ -789,13 +789,13 @@ mod tests { running_test(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); let data_dir = &home_dir.join("data_dir"); - let config_file = File::create(home_dir.join("config.toml")).unwrap(); - let data_dir_vcl = create_dir_all(PathBuf::from("booga/data_dir/MASQ/polygon-mainnet")); + let config_file = File::create(&home_dir.join("config.toml")).unwrap(); + let data_dir_vcl = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); { fill_up_config_file(config_file); match data_dir_vcl { Ok(..) => { - let config_file_vcl = File::create(PathBuf::from("booga/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); + let config_file_vcl = File::create(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); fill_up_config_file(config_file_vcl); } Err(e) => panic!("unable to create directory {}", e) @@ -805,8 +805,9 @@ mod tests { vec![ //("MASQ_CONFIG_FILE", "config.toml"), //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), - #[cfg(not(target_os = "windows"))] - ("MASQ_REAL_USER", "9999:9999:booga"), + //#[cfg(not(target_os = "windows"))] + //("MASQ_REAL_USER", "9999:9999:booga"), + ("MASQ_MIN_HOPS", "3"), ].into_iter() .for_each (|(name, value)| std::env::set_var (name, value)); let args = ArgsBuilder::new(); @@ -817,27 +818,21 @@ mod tests { let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let env_multicnfig = result.unwrap(); - let args = ArgsBuilder::new() + let args = ArgsBuilder::new(); //.param("--config-file", "config.toml") //.param("--data-directory", "/tmp/cooga/masqhome") - .param("--real-user", "1001:1001:cooga"); + //.param("--real-user", "1001:1001:cooga"); let args_vec: Vec = args.into(); let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let result = params.as_ref().expect("REASON"); - let vcl_multicnfig = result; - - //println!("env_multicnfig: {:#?}", env_multicnfig); + let vcl_multiconfig = result; + assert_eq!( value_m!(env_multicnfig, "config-file", String).unwrap(), "config.toml".to_string() - );/* - assert_eq!( - value_m!(env_multicnfig, "data-directory", String).unwrap(), - "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() - );*/ + ); #[cfg(not(target_os = "windows"))] - //let real_user = value_m!(env_multicnfig, "real-user", String).unwrap(); - match env_multicnfig.is_user_specified("real-user") { + match env_multicnfig.is_user_specified("--real-user") { true => { assert_eq!( value_m!(env_multicnfig, "real-user", String).unwrap(), @@ -845,37 +840,40 @@ mod tests { ) } false => { - println!("real-user is not user specified"); + println!("real-user is not user specified in Environment"); () } } - //println!("env_multicnfig: {:#?}", vcl_multicnfig); #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(vcl_multicnfig, "real-user", String).unwrap(), - "1001:1001:cooga".to_string() - ); - match vcl_multicnfig.is_user_specified("data-directory") { + match vcl_multiconfig.is_user_specified("--real-user") { + true => { + assert_eq!( + value_m!(vcl_multiconfig, "real-user", String).unwrap(), + "9999:9999:booga".to_string() + ) + } + false => { + println!("real-user is not user specified in Command-line"); + () + } + } + match vcl_multiconfig.is_user_specified("--data-directory") { true => { assert_eq!( - value_m!(vcl_multicnfig, "data-directory", String).unwrap(), + value_m!(vcl_multiconfig, "data-directory", String).unwrap(), "/tmp/cooga/masqhome".to_string() ) } false => { - println!("data-directory is not user specified"); + println!("data-directory is not user specified in Command-line"); () } } assert_eq!( - value_m!(vcl_multicnfig, "config-file", String).unwrap(), + value_m!(vcl_multiconfig, "config-file", String).unwrap(), "config.toml".to_string() ); - assert_eq!( - value_m!(vcl_multicnfig, "real-user", String).unwrap(), - "1001:1001:cooga".to_string() - ); } #[test] diff --git a/node/src/sub_lib/utils.rs b/node/src/sub_lib/utils.rs index 6e056eb6e..cad371e09 100644 --- a/node/src/sub_lib/utils.rs +++ b/node/src/sub_lib/utils.rs @@ -15,7 +15,6 @@ use std::io::ErrorKind; use std::marker::PhantomData; use std::path::Path; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use crate::node_configurator::node_configurator_standard::VclType; static DEAD_STREAM_ERRORS: [ErrorKind; 5] = [ ErrorKind::BrokenPipe, @@ -94,7 +93,7 @@ pub fn to_string_s(data: &[u8]) -> String { pub fn make_new_multi_config<'a>( schema: &App<'a, 'a>, - vcls: Vec>, + vcls: Vec>, ) -> Result, ConfiguratorError> { MultiConfig::try_new(schema, vcls) } From 22e607b6e23f7a737be4748d5f97e768eb27afb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Thu, 31 Aug 2023 17:40:50 +0200 Subject: [PATCH 05/24] fixed data flow with Evironment and Command line arguments, need to fix config file arguments data --- node/src/node_configurator/mod.rs | 1 + .../node_configurator_standard.rs | 71 +++++++++++++++---- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index a72ce5f97..a98097bd7 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -54,6 +54,7 @@ pub fn determine_user_specific_data ( .map(|vcl_arg| vcl_arg.dup()) .collect(); let orientation_vcl = CommandLineVcl::from(orientation_args); + println!("determine_user_specific_data"); let multi_config = make_new_multi_config(&orientation_schema, vec![Box::new(orientation_vcl)])?; let config_file_path = value_m!(multi_config, "config-file", PathBuf) .expect("config-file parameter is not properly defaulted by clap"); diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index b672f5d65..614673d83 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -145,9 +145,11 @@ pub fn server_initializer_collected_params<'a>( Ok(cfv) => Box::new(cfv), Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; - + println!("config_file_path: {} {:#?}", config_user_specified, &config_file_path); + println!("config_file_vcl: {:#?}", config_file_vcl); // let config_file_path_from_multiconfig = // value_m!(multi_config, "config-file", PathBuf).expect("defaulted param"); + //let multi_config_vec = create_multi_config_vec(dirs_wrapper, &app, args); let mut full_multi_config_vec: Vec> = vec![ Box::new(EnvironmentVcl::new(&app)), config_file_vcl, @@ -174,6 +176,7 @@ pub fn server_initializer_collected_params<'a>( true => full_multi_config_vec.push(real_user_spcified_box), false => full_multi_config_vec.push(real_user_unspcified_box) }; + println!("full_multi_config_vec: {:#?}", full_multi_config_vec); let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; //println!("full_multi_config: {:#?}", full_multi_config); Ok(full_multi_config) @@ -751,7 +754,10 @@ mod tests { fn fill_up_config_file(mut config_file: File) { { config_file - .write_all(b"blockchain-service-url = \"https://www.mainnet.com\"\n") + .write_all(b"real-user = \"1002:1002:wooga\"\n") + .unwrap(); + config_file + .write_all(b"blockchain-service-url = \"https://www.mainnet2.com\"\n") .unwrap(); config_file .write_all(b"clandestine-port = \"7788\"\n") @@ -803,7 +809,7 @@ mod tests { } vec![ - //("MASQ_CONFIG_FILE", "config.toml"), + ("MASQ_CONFIG_FILE", "config.toml"), //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), //#[cfg(not(target_os = "windows"))] //("MASQ_REAL_USER", "9999:9999:booga"), @@ -816,7 +822,7 @@ mod tests { .home_dir_result(Some(home_dir.clone())) .data_dir_result(Some(data_dir.to_path_buf())); let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - let env_multicnfig = result.unwrap(); + let env_multiconfig = result.unwrap(); let args = ArgsBuilder::new(); //.param("--config-file", "config.toml") @@ -828,14 +834,27 @@ mod tests { let vcl_multiconfig = result; assert_eq!( - value_m!(env_multicnfig, "config-file", String).unwrap(), + value_m!(env_multiconfig, "config-file", String).unwrap(), "config.toml".to_string() ); + match env_multiconfig.is_user_specified("--data-directory") { + true => { + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() + ) + } + false => { + println!("data-directory is not user specified in Environment"); + () + } + } + println!("env_multiconfig: {:#?}", env_multiconfig); #[cfg(not(target_os = "windows"))] - match env_multicnfig.is_user_specified("--real-user") { + match env_multiconfig.is_user_specified("--real-user") { true => { assert_eq!( - value_m!(env_multicnfig, "real-user", String).unwrap(), + value_m!(env_multiconfig, "real-user", String).unwrap(), "9999:9999:booga".to_string() ) } @@ -848,10 +867,21 @@ mod tests { #[cfg(not(target_os = "windows"))] match vcl_multiconfig.is_user_specified("--real-user") { true => { - assert_eq!( - value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "9999:9999:booga".to_string() - ) + match env_multiconfig.is_user_specified("--real-user") { + true => { + println!("real-user is inherited from Environment {}", value_m!(vcl_multiconfig, "real-user", String).unwrap()); + assert_eq!( + value_m!(vcl_multiconfig, "real-user", String).unwrap(), + "9999:9999:booga".to_string() + ) + } + false => { + assert_eq!( + value_m!(vcl_multiconfig, "real-user", String).unwrap(), + "1001:1001:cooga".to_string() + ) + } + } } false => { println!("real-user is not user specified in Command-line"); @@ -860,10 +890,21 @@ mod tests { } match vcl_multiconfig.is_user_specified("--data-directory") { true => { - assert_eq!( - value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - "/tmp/cooga/masqhome".to_string() - ) + match env_multiconfig.is_user_specified("--data-directory") { + true => { + println!("data-directory is inherited from Environment"); + assert_eq!( + value_m!(vcl_multiconfig, "data-directory", String).unwrap(), + "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() + ) + } + false => { + assert_eq!( + value_m!(vcl_multiconfig, "data-directory", String).unwrap(), + "/tmp/cooga/masqhome".to_string() + ) + } + } } false => { println!("data-directory is not user specified in Command-line"); From b9a6e85c4f85e47114bea933cb65745c8bd0de31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Mon, 4 Sep 2023 23:10:35 +0200 Subject: [PATCH 06/24] changes in test to access config.file for various scenarios, add machinery to determine if real-user is specified in config-file --- node/src/node_configurator/mod.rs | 47 +++++++++++- .../node_configurator_standard.rs | 75 ++++++++++++------- 2 files changed, 93 insertions(+), 29 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index a98097bd7..ed8da956b 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -16,7 +16,7 @@ use clap::{value_t, App}; use dirs::{data_local_dir, home_dir}; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::DEFAULT_CHAIN; -use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg}; +use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg, VirtualCommandLine, ConfigFileVcl}; use masq_lib::shared_schema::{ chain_arg, config_file_arg, data_directory_arg, real_user_arg, ConfiguratorError, DATA_DIRECTORY_HELP, @@ -29,19 +29,58 @@ pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } +fn config_file_and_data_dir_from_enumerate(configs: Vec) -> (String, String) { + let mut config_match = "".to_string(); + let mut datadir_match = "".to_string(); + for (i, arg) in configs.iter().enumerate() { + if arg.as_str() == "--config-file" { + config_match = configs[i + 1].to_string() + } + if arg.as_str() == "--data-directory".to_string() { + datadir_match = configs[i + 1].to_string() + } + }; + (config_match, datadir_match) +} + pub fn determine_user_specific_data ( dirs_wrapper: &dyn DirsWrapper, app: &App, args: &[String], -) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool), ConfiguratorError> { +) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool), ConfiguratorError> { //, Box let orientation_schema = App::new("MASQNode") .arg(chain_arg()) .arg(real_user_arg()) .arg(data_directory_arg(DATA_DIRECTORY_HELP)) .arg(config_file_arg()); - let orientation_args: Vec> = merge( + println!("ENV"); + let configargs = Box::new(EnvironmentVcl::new(&app)).args(); + let (env_config_file, env_data_dir) = config_file_and_data_dir_from_enumerate(configargs); + println!("ENV configargs: {} - {}", env_config_file, env_data_dir); + println!("CMD"); + let argstovec = args.to_vec(); + //println!("args to vec: {:#?}", argstovec); + let (cmd_config_file, cmd_data_dir) = config_file_and_data_dir_from_enumerate(argstovec); + println!("CMD configargs: {} - {}", cmd_config_file, cmd_data_dir); + + let mut combined_vcl = vec![]; + if !cmd_data_dir.is_empty() {combined_vcl.push(cmd_data_dir); } + else if !env_data_dir.is_empty() { combined_vcl.push(env_data_dir); } + if !cmd_config_file.is_empty() { combined_vcl.push(cmd_config_file); } + else if !env_config_file.is_empty() { combined_vcl.push(env_config_file); } + + let config_file_path = Path::new(&combined_vcl[0].to_string()).join(Path::new(&combined_vcl[1].to_string())); + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, true) { + Ok(cfv) => Box::new(cfv), + Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), + }; + let preorientation_args: Box = merge( Box::new(EnvironmentVcl::new(app)), - Box::new(CommandLineVcl::new(args.to_vec())), + config_file_vcl, + ); + let orientation_args: Vec> = merge( + preorientation_args, + Box::new(CommandLineVcl::new(args.to_vec())) ) .vcl_args() .into_iter() diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 614673d83..36cacf2ac 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -141,18 +141,15 @@ pub fn server_initializer_collected_params<'a>( let app = app_node(); let (config_file_path, config_user_specified, data_directory, data_directory_specified, real_user, real_user_specified) = determine_user_specific_data(dirs_wrapper, &app, args)?; - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, config_user_specified) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), - }; + println!("config_file_path: {} {:#?}", config_user_specified, &config_file_path); - println!("config_file_vcl: {:#?}", config_file_vcl); + //println!("config_file_vcl: {:#?}", config_file_vcl); // let config_file_path_from_multiconfig = // value_m!(multi_config, "config-file", PathBuf).expect("defaulted param"); //let multi_config_vec = create_multi_config_vec(dirs_wrapper, &app, args); let mut full_multi_config_vec: Vec> = vec![ Box::new(EnvironmentVcl::new(&app)), - config_file_vcl, + //config_file_vcl, Box::new(CommandLineVcl::new(args.to_vec())), ]; @@ -176,7 +173,7 @@ pub fn server_initializer_collected_params<'a>( true => full_multi_config_vec.push(real_user_spcified_box), false => full_multi_config_vec.push(real_user_unspcified_box) }; - println!("full_multi_config_vec: {:#?}", full_multi_config_vec); + //println!("full_multi_config_vec: {:#?}", full_multi_config_vec); let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; //println!("full_multi_config: {:#?}", full_multi_config); Ok(full_multi_config) @@ -796,10 +793,18 @@ mod tests { let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); let data_dir = &home_dir.join("data_dir"); let config_file = File::create(&home_dir.join("config.toml")).unwrap(); - let data_dir_vcl = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); + let data_dir_vcl = create_dir_all(PathBuf::from("/tmp/cooga/masqhome")); + let data_dir_sys = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); { fill_up_config_file(config_file); match data_dir_vcl { + Ok(..) => { + let config_file_vcl = File::create(PathBuf::from("/tmp/cooga/masqhome").join("config.toml")).unwrap(); + fill_up_config_file(config_file_vcl); + } + Err(e) => panic!("unable to create directory {}", e) + } + match data_dir_sys { Ok(..) => { let config_file_vcl = File::create(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); fill_up_config_file(config_file_vcl); @@ -808,31 +813,41 @@ mod tests { } } - vec![ + let env_vec_array = vec![ ("MASQ_CONFIG_FILE", "config.toml"), - //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), + ("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), //#[cfg(not(target_os = "windows"))] //("MASQ_REAL_USER", "9999:9999:booga"), ("MASQ_MIN_HOPS", "3"), - ].into_iter() + ]; + env_vec_array.clone().into_iter() .for_each (|(name, value)| std::env::set_var (name, value)); let args = ArgsBuilder::new(); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() .home_dir_result(Some(home_dir.clone())) .data_dir_result(Some(data_dir.to_path_buf())); + let mut env_data_directory = false; + for (item, _vaue) in env_vec_array.to_vec().as_slice() { + if item == &"MASQ_DATA_DIRECTORY" { env_data_directory = true; } + } + println!("env_multiconfig creation"); let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let env_multiconfig = result.unwrap(); - let args = ArgsBuilder::new(); + let args = ArgsBuilder::new() //.param("--config-file", "config.toml") - //.param("--data-directory", "/tmp/cooga/masqhome") + .param("--data-directory", "/tmp/cooga/masqhome"); //.param("--real-user", "1001:1001:cooga"); let args_vec: Vec = args.into(); + let mut cmd_data_directory = false; + for item in args_vec.clone().as_slice() { + if item == &"--data-directory".to_string() { cmd_data_directory = true; } + } let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - let result = params.as_ref().expect("REASON"); - let vcl_multiconfig = result; - + let result2 = params.as_ref().expect("REASON"); + let vcl_multiconfig = result2; + assert_eq!( value_m!(env_multiconfig, "config-file", String).unwrap(), "config.toml".to_string() @@ -849,13 +864,13 @@ mod tests { () } } - println!("env_multiconfig: {:#?}", env_multiconfig); + //println!("env_multiconfig: {:#?}", env_multiconfig); #[cfg(not(target_os = "windows"))] match env_multiconfig.is_user_specified("--real-user") { true => { assert_eq!( value_m!(env_multiconfig, "real-user", String).unwrap(), - "9999:9999:booga".to_string() + "1002:1002:wooga".to_string() ) } false => { @@ -872,7 +887,7 @@ mod tests { println!("real-user is inherited from Environment {}", value_m!(vcl_multiconfig, "real-user", String).unwrap()); assert_eq!( value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "9999:9999:booga".to_string() + "1002:1002:wooga".to_string() ) } false => { @@ -888,9 +903,10 @@ mod tests { () } } + println!("env_data_directory {:#?}", env_data_directory); match vcl_multiconfig.is_user_specified("--data-directory") { true => { - match env_multiconfig.is_user_specified("--data-directory") { + match env_data_directory && !cmd_data_directory { true => { println!("data-directory is inherited from Environment"); assert_eq!( @@ -899,12 +915,21 @@ mod tests { ) } false => { - assert_eq!( - value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - "/tmp/cooga/masqhome".to_string() - ) + match cmd_data_directory { + true => { + assert_eq!( + value_m!(vcl_multiconfig, "data-directory", String).unwrap(), + "/tmp/cooga/masqhome".to_string() + ) + } + false => { + println!("data-directory is not user specified in ENV") + } + } + } - } + }; + } false => { println!("data-directory is not user specified in Command-line"); From 08349e2f19e2c78bb29463cbc2da7febb5be6391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Thu, 14 Sep 2023 00:54:08 +0200 Subject: [PATCH 07/24] try to get rid of redundant MultiConfig construction in determine_user_specific_data --- node/src/daemon/setup_reporter.rs | 2 +- node/src/node_configurator/mod.rs | 192 ++++++++++++------ .../node_configurator_standard.rs | 176 ++++++++++++---- 3 files changed, 276 insertions(+), 94 deletions(-) diff --git a/node/src/daemon/setup_reporter.rs b/node/src/daemon/setup_reporter.rs index 287897738..79b4a34b8 100644 --- a/node/src/daemon/setup_reporter.rs +++ b/node/src/daemon/setup_reporter.rs @@ -495,7 +495,7 @@ impl SetupReporterReal { Some(command_line) => command_line, None => vec![], }; - let (config_file_path, user_specified, _data_directory, _data_directory_specified, _real_user, _real_user_specified) = + let (config_file_path, user_specified, _data_directory, _data_directory_specified, _real_user, _real_user_specified, _preorientation_args) = determine_user_specific_data(dirs_wrapper, &app, &command_line)?; let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { Ok(cfv) => cfv, diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index ed8da956b..b2aefcd7d 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -5,18 +5,19 @@ pub mod node_configurator_initialization; pub mod node_configurator_standard; pub mod unprivileged_parse_args_configuration; +use std::env::{current_dir}; use crate::bootstrapper::RealUser; use crate::database::db_initializer::DbInitializationConfig; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::persistent_configuration::{ PersistentConfiguration, PersistentConfigurationReal, }; -use crate::sub_lib::utils::{db_connection_launch_panic, make_new_multi_config}; +use crate::sub_lib::utils::db_connection_launch_panic; use clap::{value_t, App}; use dirs::{data_local_dir, home_dir}; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::DEFAULT_CHAIN; -use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg, VirtualCommandLine, ConfigFileVcl}; +use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg, VirtualCommandLine, ConfigFileVcl, ConfigFileVclError}; use masq_lib::shared_schema::{ chain_arg, config_file_arg, data_directory_arg, real_user_arg, ConfiguratorError, DATA_DIRECTORY_HELP, @@ -29,58 +30,42 @@ pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } -fn config_file_and_data_dir_from_enumerate(configs: Vec) -> (String, String) { - let mut config_match = "".to_string(); - let mut datadir_match = "".to_string(); +fn config_file_and_data_dir_from_enumerate(configs: Vec) -> (String, String, String) { + let config_match = argument_from_enumerate(configs.clone(), "--config-file".to_string()).unwrap_or("".to_string()); + let data_dir_match = argument_from_enumerate(configs.clone(), "--data-directory".to_string()).unwrap_or("".to_string()); + let real_user_match = argument_from_enumerate(configs, "--real-user".to_string()).unwrap_or("".to_string()); + (config_match, data_dir_match, real_user_match) +} + +fn argument_from_enumerate(configs: Vec, needle: String) -> Option { + let mut arg_match = None; for (i, arg) in configs.iter().enumerate() { - if arg.as_str() == "--config-file" { - config_match = configs[i + 1].to_string() - } - if arg.as_str() == "--data-directory".to_string() { - datadir_match = configs[i + 1].to_string() + if arg.as_str() == needle { + arg_match = Some(configs[i + 1].to_string()) } }; - (config_match, datadir_match) + arg_match } pub fn determine_user_specific_data ( dirs_wrapper: &dyn DirsWrapper, app: &App, args: &[String], -) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool), ConfiguratorError> { //, Box +) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool, Box), ConfiguratorError> { //, Box let orientation_schema = App::new("MASQNode") .arg(chain_arg()) .arg(real_user_arg()) .arg(data_directory_arg(DATA_DIRECTORY_HELP)) .arg(config_file_arg()); - println!("ENV"); - let configargs = Box::new(EnvironmentVcl::new(&app)).args(); - let (env_config_file, env_data_dir) = config_file_and_data_dir_from_enumerate(configargs); - println!("ENV configargs: {} - {}", env_config_file, env_data_dir); - println!("CMD"); - let argstovec = args.to_vec(); - //println!("args to vec: {:#?}", argstovec); - let (cmd_config_file, cmd_data_dir) = config_file_and_data_dir_from_enumerate(argstovec); - println!("CMD configargs: {} - {}", cmd_config_file, cmd_data_dir); - - let mut combined_vcl = vec![]; - if !cmd_data_dir.is_empty() {combined_vcl.push(cmd_data_dir); } - else if !env_data_dir.is_empty() { combined_vcl.push(env_data_dir); } - if !cmd_config_file.is_empty() { combined_vcl.push(cmd_config_file); } - else if !env_config_file.is_empty() { combined_vcl.push(env_config_file); } - - let config_file_path = Path::new(&combined_vcl[0].to_string()).join(Path::new(&combined_vcl[1].to_string())); - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, true) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), + let env_args = Box::new(EnvironmentVcl::new(&app)).args(); + let args_to_vec = args.to_vec(); + let pre_orientation_args = match create_preorientation_args(env_args, args_to_vec.clone(), &app) { + Ok(pre_orientation_args) => pre_orientation_args, + Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())) }; - let preorientation_args: Box = merge( - Box::new(EnvironmentVcl::new(app)), - config_file_vcl, - ); let orientation_args: Vec> = merge( - preorientation_args, - Box::new(CommandLineVcl::new(args.to_vec())) + pre_orientation_args, + Box::new(CommandLineVcl::new(args_to_vec)) ) .vcl_args() .into_iter() @@ -93,26 +78,117 @@ pub fn determine_user_specific_data ( .map(|vcl_arg| vcl_arg.dup()) .collect(); let orientation_vcl = CommandLineVcl::from(orientation_args); - println!("determine_user_specific_data"); - let multi_config = make_new_multi_config(&orientation_schema, vec![Box::new(orientation_vcl)])?; - let config_file_path = value_m!(multi_config, "config-file", PathBuf) - .expect("config-file parameter is not properly defaulted by clap"); - let config_user_specified = multi_config.occurrences_of("config-file") > 0; - let data_directory_specified = multi_config.occurrences_of("data-directory") > 0; - let real_user_specified = multi_config.occurrences_of("real-user") > 0; - let (real_user, data_directory_path, chain) = - real_user_data_directory_path_and_chain(dirs_wrapper, &multi_config); - let data_directory = match data_directory_path { - Some(data_dir) => data_dir, - None => data_directory_from_context(dirs_wrapper, &real_user, chain), + let (config_file, data_dir, mut real_user) = config_file_and_data_dir_from_enumerate(orientation_vcl.args()); + let config_user_specified = !config_file.is_empty(); + let data_directory_specified = !data_dir.is_empty(); + let real_user_specified = !real_user.is_empty(); + if real_user.is_empty() { + let multi_config = MultiConfig::try_new(&orientation_schema, vec![]); + match multi_config { + Ok(multi_config) => { + real_user = real_user_from_multi_config_or_populate(&multi_config, dirs_wrapper).to_string(); + } + Err(e) => return Err(e) + } + + } + let chain = match argument_from_enumerate(orientation_vcl.args(), "--chain".to_string()) { + Some(chain) => { + Chain::from(chain.as_str()) + }, + None => DEFAULT_CHAIN }; - let config_file_path = if config_file_path.is_relative() { - data_directory.join(config_file_path) - } else { - config_file_path + let real_user_split: Vec<&str> = real_user.split(":").collect(); + let real_user_obj = RealUser::new( + Some(real_user_split[0].parse::().expect("expected user id")), + Some(real_user_split[1].parse::().expect("expected user group")), + Some(PathBuf::from(real_user_split[2]))); + let data_directory = match data_dir.is_empty() { + false => PathBuf::from(data_dir), + true => data_directory_from_context(dirs_wrapper, &real_user_obj, chain), + }; + Ok(( + PathBuf::from(config_file), + config_user_specified, + data_directory, + data_directory_specified, + real_user_obj, + real_user_specified, + Box::new(orientation_vcl))) +} + +struct CombinedVcl { + content: Vec +} + +impl CombinedVcl { + fn len(&self) -> u32 { + *&self.content.as_slice().iter().count() as u32 + } +} + +fn create_preorientation_args(envargs: Vec, argstovec: Vec, app: &App) -> Result, ConfigFileVclError> { + let (env_config_file, env_data_dir, env_real_user) = config_file_and_data_dir_from_enumerate(envargs); + let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_and_data_dir_from_enumerate(argstovec); + let mut combined_vcl: CombinedVcl = CombinedVcl { content: vec![] }; + let combine_vcl = | name: String, vcl: &mut CombinedVcl, cmd_str: &String, env_str: &String | { + if !cmd_str.is_empty() { + vcl.content.push(name); + vcl.content.push(cmd_str.to_string()); + } + else if !env_str.is_empty() { + vcl.content.push(name); + vcl.content.push(env_str.to_string()); + } + else { + vcl.content.push(name); + vcl.content.push("".to_string()); + } }; + combine_vcl("--data-directory".to_string(), &mut combined_vcl, &cmd_data_dir, &env_data_dir); + combine_vcl("--config-file".to_string(), &mut combined_vcl, &cmd_config_file, &env_config_file); + combine_vcl("--real-user".to_string(), &mut combined_vcl, &cmd_real_user, &env_real_user); + if combined_vcl.len() > 0 { + let (mut config_file, data_directory, _real_user) = config_file_and_data_dir_from_enumerate(combined_vcl.content); + if !config_file.is_empty() && + (!config_file.starts_with("/") && !config_file.starts_with("./") && !config_file.starts_with("../")) + && data_directory.is_empty() { + return Err(ConfigFileVclError::InvalidConfig( + PathBuf::from(&config_file), + "Config file defined in Environment with relative path needs data-directory to be defined too".to_string() + )); + } - Ok((config_file_path, config_user_specified, data_directory, data_directory_specified, real_user, real_user_specified)) + if config_file.starts_with("./") { + let pwd = current_dir().expect("expected current directory"); + config_file = config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); + } + + let mut config_file_path = PathBuf::from(&config_file.to_string()); + let user_specified = !config_file.is_empty(); + if config_file_path.is_relative() && !data_directory.is_empty() { + config_file_path = PathBuf::from(data_directory.to_string()).join(config_file_path); + } + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { + Ok(cfv) => Box::new(cfv), + Err(e) => return Err(e), + }; + let args = merge( + Box::new(EnvironmentVcl::new(app)), + config_file_vcl, + ); + let args = merge( + args, + Box::new(CommandLineVcl::new( + vec!["".to_string(), + "--config-file".to_string(), + config_file_path.to_string_lossy().to_string()] + )) + ); + Ok(args) + } else { + Ok(Box::new(EnvironmentVcl::new(app))) + } } pub fn initialize_database( @@ -253,7 +329,7 @@ mod tests { .param("--config-file", "booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified) = determine_user_specific_data( + let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified, _preorientation) = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -282,7 +358,7 @@ mod tests { ); std::env::set_var("MASQ_CONFIG_FILE", "booga.toml"); - let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified) = determine_user_specific_data( + let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified, _preorientation_args) = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -305,7 +381,7 @@ mod tests { .param("--config-file", "/tmp/booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified) = determine_user_specific_data( + let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified, _preorientation_args) = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 36cacf2ac..95faebd3b 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -139,20 +139,28 @@ pub fn server_initializer_collected_params<'a>( args: &[String], ) -> Result, ConfiguratorError> { let app = app_node(); - let (config_file_path, config_user_specified, data_directory, data_directory_specified, real_user, real_user_specified) = - determine_user_specific_data(dirs_wrapper, &app, args)?; - - println!("config_file_path: {} {:#?}", config_user_specified, &config_file_path); - //println!("config_file_vcl: {:#?}", config_file_vcl); - // let config_file_path_from_multiconfig = - // value_m!(multi_config, "config-file", PathBuf).expect("defaulted param"); - //let multi_config_vec = create_multi_config_vec(dirs_wrapper, &app, args); + let (config_file_path, + config_user_specified, + data_directory, + data_directory_specified, + real_user, + real_user_specified, + preorientation_args) = determine_user_specific_data(dirs_wrapper, &app, args)?; let mut full_multi_config_vec: Vec> = vec![ Box::new(EnvironmentVcl::new(&app)), - //config_file_vcl, - Box::new(CommandLineVcl::new(args.to_vec())), + preorientation_args ]; + let config_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ + "".to_string(), "--config-file".to_string(), config_file_path.to_string_lossy().to_string(), + ])); + let config_unspcified_box: Box = Box::new(ComputedVcl::new(vec![ + "".to_string(), "--config-file".to_string(), config_file_path.to_string_lossy().to_string(), + ])); + match config_user_specified { + true => full_multi_config_vec.push(config_spcified_box), + false => full_multi_config_vec.push(config_unspcified_box) + }; let data_directory_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ "".to_string(), "--data-directory".to_string(), data_directory.to_string_lossy().to_string(), ])); @@ -173,9 +181,9 @@ pub fn server_initializer_collected_params<'a>( true => full_multi_config_vec.push(real_user_spcified_box), false => full_multi_config_vec.push(real_user_unspcified_box) }; - //println!("full_multi_config_vec: {:#?}", full_multi_config_vec); + let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; - //println!("full_multi_config: {:#?}", full_multi_config); + Ok(full_multi_config) } @@ -325,6 +333,7 @@ mod tests { use masq_lib::utils::{running_test, slice_of_strs_to_vec_of_strings}; use rustc_hex::FromHex; use std::convert::TryFrom; + use std::env::current_dir; use std::fs::{create_dir_all, File}; use std::io::Write; use std::path::{Path, PathBuf}; @@ -787,37 +796,138 @@ mod tests { } } + #[test] + fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot() { + running_test(); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + let data_dir = &home_dir.join("data_dir"); + let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); + fill_up_config_file(config_file_relative); + let env_vec_array = vec![ + ("MASQ_CONFIG_FILE", "./generated/config.toml"), + #[cfg(not(target_os = "windows"))] + ("MASQ_REAL_USER", "9999:9999:booga"), + ]; + env_vec_array.clone().into_iter() + .for_each (|(name, value)| std::env::set_var (name, value)); + let args = ArgsBuilder::new(); + let args_vec: Vec = args.into(); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(home_dir.clone())) + .data_dir_result(Some(data_dir.to_path_buf())); + + let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + let env_multiconfig = result.unwrap(); + + match env_multiconfig.is_user_specified("--data-directory") { + true => (), + false => { + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "wooga/data_dir/MASQ/polygon-mainnet".to_string() + ) + } + } + + match (env_multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { + (true, true) => { + let pwd = PathBuf::from( value_m!(env_multiconfig, "data-directory", String).unwrap()); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() + ) + }, + (true, false) => { + let pwd = current_dir().unwrap(); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() + ) + }, + (_, _) => () + } + } + + #[test] + fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_directory() { + running_test(); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + let data_dir = &home_dir.join("data_dir"); + let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); + fill_up_config_file(config_file_relative); + let current_directory = current_dir().unwrap(); + vec![ + ("MASQ_CONFIG_FILE", "./generated/config.toml"), + ("MASQ_DATA_DIRECTORY", ¤t_directory.display().to_string().as_str()), + #[cfg(not(target_os = "windows"))] + ("MASQ_REAL_USER", "9999:9999:booga"), + ].into_iter() + .for_each (|(name, value)| std::env::set_var (name, value)); + let args = ArgsBuilder::new(); + let args_vec: Vec = args.into(); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(home_dir.clone())) + .data_dir_result(Some(data_dir.to_path_buf())); + + let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + let env_multiconfig = result.unwrap(); + + match env_multiconfig.is_user_specified("--data-directory") { + true => { + assert_eq!( + &value_m!(env_multiconfig, "data-directory", String).unwrap(), + ¤t_directory.to_string_lossy().to_string() + ) + }, + false => () + } + + match env_multiconfig.is_user_specified("--real-user") { + true => { + assert_eq!( + &value_m!(env_multiconfig, "real-user", String).unwrap(), + "1002:1002:wooga" + ) + }, + false => () + } + + match (env_multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { + (true, true) => { + let pwd = PathBuf::from( value_m!(env_multiconfig, "data-directory", String).unwrap()); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() + ) + }, + (_, _) => () + } + } + #[test] fn server_initializer_collected_params_combine_vlcs_properly() { running_test(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); let data_dir = &home_dir.join("data_dir"); let config_file = File::create(&home_dir.join("config.toml")).unwrap(); - let data_dir_vcl = create_dir_all(PathBuf::from("/tmp/cooga/masqhome")); + let current_directory = current_dir().unwrap(); let data_dir_sys = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); { fill_up_config_file(config_file); - match data_dir_vcl { - Ok(..) => { - let config_file_vcl = File::create(PathBuf::from("/tmp/cooga/masqhome").join("config.toml")).unwrap(); - fill_up_config_file(config_file_vcl); - } - Err(e) => panic!("unable to create directory {}", e) - } match data_dir_sys { Ok(..) => { let config_file_vcl = File::create(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); fill_up_config_file(config_file_vcl); } - Err(e) => panic!("unable to create directory {}", e) + Err(e) => panic!("unable to create config file: {}", e) } } let env_vec_array = vec![ - ("MASQ_CONFIG_FILE", "config.toml"), - ("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), + ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml"), + //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), //#[cfg(not(target_os = "windows"))] - //("MASQ_REAL_USER", "9999:9999:booga"), + ("MASQ_REAL_USER", "9999:9999:booga"), ("MASQ_MIN_HOPS", "3"), ]; env_vec_array.clone().into_iter() @@ -831,14 +941,14 @@ mod tests { for (item, _vaue) in env_vec_array.to_vec().as_slice() { if item == &"MASQ_DATA_DIRECTORY" { env_data_directory = true; } } - println!("env_multiconfig creation"); + let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let env_multiconfig = result.unwrap(); let args = ArgsBuilder::new() //.param("--config-file", "config.toml") - .param("--data-directory", "/tmp/cooga/masqhome"); - //.param("--real-user", "1001:1001:cooga"); + .param("--data-directory", current_directory.join(Path::new("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home")).to_string_lossy().to_string().as_str()) + .param("--real-user", "1001:1001:cooga"); let args_vec: Vec = args.into(); let mut cmd_data_directory = false; for item in args_vec.clone().as_slice() { @@ -850,7 +960,7 @@ mod tests { assert_eq!( value_m!(env_multiconfig, "config-file", String).unwrap(), - "config.toml".to_string() + current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() ); match env_multiconfig.is_user_specified("--data-directory") { true => { @@ -887,13 +997,13 @@ mod tests { println!("real-user is inherited from Environment {}", value_m!(vcl_multiconfig, "real-user", String).unwrap()); assert_eq!( value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "1002:1002:wooga".to_string() + "1001:1001:cooga".to_string() ) } false => { assert_eq!( value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "1001:1001:cooga".to_string() + "1002:1002:wooga".to_string() ) } } @@ -919,7 +1029,7 @@ mod tests { true => { assert_eq!( value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - "/tmp/cooga/masqhome".to_string() + current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home").to_string_lossy().to_string() ) } false => { @@ -936,10 +1046,6 @@ mod tests { () } } - assert_eq!( - value_m!(vcl_multiconfig, "config-file", String).unwrap(), - "config.toml".to_string() - ); } #[test] From 8aead2a44240a2d83d12928b84fb57cada3c1961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Fri, 15 Sep 2023 12:22:24 +0200 Subject: [PATCH 08/24] handle computed arguments in multiconfig, closure for server_initializer_collected_params, closure for keeping in node_configurator, final removal of redundant construction of multiconfig --- masq_lib/src/multi_config.rs | 110 ++++++++++++++++-- node/src/node_configurator/mod.rs | 36 +++--- .../node_configurator_standard.rs | 57 +++------ 3 files changed, 129 insertions(+), 74 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index 8cc6574f5..c389bb23d 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -50,6 +50,7 @@ macro_rules! values_m { #[derive(Debug)] pub struct MultiConfig<'a> { arg_matches: ArgMatches<'a>, + computed_value_names: HashSet } impl<'a> MultiConfig<'a> { @@ -61,24 +62,41 @@ impl<'a> MultiConfig<'a> { schema: &App<'a, 'a>, vcls: Vec>, ) -> Result, ConfiguratorError> { + let mut computed_value_names = HashSet::new(); let initial: Box = Box::new(CommandLineVcl::new(vec![String::new()])); - let merged: Box = vcls - .into_iter() - .fold(initial, |so_far, vcl| merge(so_far, vcl)); + let vlc_copy = &vcls; + { + vlc_copy.into_iter().for_each(|vcl| { + vcl.vcl_args().iter().for_each(|vcl_arg| { + match vcl.is_computed() { + true => computed_value_names.insert(vcl_arg.name().to_string()), + false => computed_value_names.remove(&vcl_arg.name().to_string()) + }; + }) + }); + } + let merged: Box = vcls.into_iter().fold(initial, |so_far, vcl | -> Box { + merge(so_far, vcl) + }); + let arg_matches = match schema .clone() .get_matches_from_safe(merged.args().into_iter()) { - Ok(matches) => matches, - Err(e) => match e.kind { - clap::ErrorKind::HelpDisplayed | clap::ErrorKind::VersionDisplayed => { - unreachable!("The program's entry check failed to catch this.") + Ok(matches) => { + matches + }, + Err(e) => { + match e.kind { + clap::ErrorKind::HelpDisplayed | clap::ErrorKind::VersionDisplayed => { + unreachable!("The program's entry check failed to catch this.") + } + _ => return Err(Self::make_configurator_error(e)), } - _ => return Err(Self::make_configurator_error(e)), }, }; - Ok(MultiConfig { arg_matches }) + Ok(MultiConfig { arg_matches, computed_value_names }) } fn check_for_invalid_value_err( @@ -139,6 +157,13 @@ impl<'a> MultiConfig<'a> { ConfiguratorError::required("", &format!("Unfamiliar message: {}", e.message)) } + pub fn is_user_specified(&self, value_name: &str) -> bool { + match self.computed_value_names.contains(value_name) { + true => false, + false => true + } + } + pub fn occurrences_of(&self, parameter: &str) -> u64 { self.arg_matches.occurrences_of(parameter) } @@ -224,6 +249,7 @@ impl NameOnlyVclArg { pub trait VirtualCommandLine { fn vcl_args(&self) -> Vec<&dyn VclArg>; fn args(&self) -> Vec; + fn is_computed(&self) -> bool { false } } impl Debug for dyn VirtualCommandLine { @@ -263,6 +289,24 @@ pub fn merge( }) } +pub struct ComputedVcl { + vcl_args: Vec>, +} + +impl VirtualCommandLine for ComputedVcl { + fn vcl_args(&self) -> Vec<&dyn VclArg> { + vcl_args_to_vcl_args(&self.vcl_args) + } + + fn args(&self) -> Vec { + vcl_args_to_args(&self.vcl_args) + } + + fn is_computed(&self) -> bool { + true + } +} + pub struct CommandLineVcl { vcl_args: Vec>, } @@ -283,6 +327,33 @@ impl From>> for CommandLineVcl { } } +impl ComputedVcl { + pub fn new(mut args: Vec) -> ComputedVcl { + args.remove(0); // remove command + let mut vcl_args = vec![]; + while let Some(vcl_arg) = Self::next_vcl_arg(&mut args) { + vcl_args.push(vcl_arg); + } + ComputedVcl { vcl_args } + } + + fn next_vcl_arg(args: &mut Vec) -> Option> { + if args.is_empty() { + return None; + } + let name = args.remove(0); + if !name.starts_with("--") { + panic!("Expected option beginning with '--', not {}", name) + } + if args.is_empty() || args[0].starts_with("--") { + Some(Box::new(NameOnlyVclArg::new(&name))) + } else { + let value = args.remove(0); + Some(Box::new(NameValueVclArg::new(&name, &value))) + } + } +} + impl CommandLineVcl { pub fn new(mut args: Vec) -> CommandLineVcl { args.remove(0); // remove command @@ -347,6 +418,7 @@ impl EnvironmentVcl { } } +#[derive(Debug)] pub struct ConfigFileVcl { vcl_args: Vec>, } @@ -360,6 +432,16 @@ impl VirtualCommandLine for ConfigFileVcl { vcl_args_to_args(&self.vcl_args) } } +/* +impl VirtualCommandLine for dyn VclArg { + fn vcl_args(&self) -> Vec<&dyn VclArg> { + vcl_args_to_vcl_args(&[Box::new(self.vcl_args().as_slice())]) + } + + fn args(&self) -> Vec { + vcl_args_to_args(&[Box::new(self.vcl_args().as_slice())]) + } +}*/ #[derive(Debug)] pub enum ConfigFileVclError { @@ -491,8 +573,14 @@ fn append(ts: Vec, t: T) -> Vec { #[cfg(not(feature = "no_test_share"))] impl<'a> MultiConfig<'a> { - pub fn new_test_only(arg_matches: ArgMatches<'a>) -> Self { - Self { arg_matches } + pub fn new_test_only( + arg_matches: ArgMatches<'a>, + computed_value_names: HashSet + ) -> Self { + Self { + arg_matches, + computed_value_names + } } } diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index b2aefcd7d..0513c70ff 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -18,10 +18,7 @@ use dirs::{data_local_dir, home_dir}; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg, VirtualCommandLine, ConfigFileVcl, ConfigFileVclError}; -use masq_lib::shared_schema::{ - chain_arg, config_file_arg, data_directory_arg, real_user_arg, ConfiguratorError, - DATA_DIRECTORY_HELP, -}; +use masq_lib::shared_schema::{config_file_arg, data_directory_arg, ConfiguratorError,DATA_DIRECTORY_HELP}; use masq_lib::utils::{add_masq_and_chain_directories, localhost}; use std::net::{SocketAddr, TcpListener}; use std::path::{Path, PathBuf}; @@ -30,7 +27,7 @@ pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } -fn config_file_and_data_dir_from_enumerate(configs: Vec) -> (String, String, String) { +fn config_file_real_user_data_dir_from_enumerate(configs: Vec) -> (String, String, String) { let config_match = argument_from_enumerate(configs.clone(), "--config-file".to_string()).unwrap_or("".to_string()); let data_dir_match = argument_from_enumerate(configs.clone(), "--data-directory".to_string()).unwrap_or("".to_string()); let real_user_match = argument_from_enumerate(configs, "--real-user".to_string()).unwrap_or("".to_string()); @@ -51,12 +48,7 @@ pub fn determine_user_specific_data ( dirs_wrapper: &dyn DirsWrapper, app: &App, args: &[String], -) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool, Box), ConfiguratorError> { //, Box - let orientation_schema = App::new("MASQNode") - .arg(chain_arg()) - .arg(real_user_arg()) - .arg(data_directory_arg(DATA_DIRECTORY_HELP)) - .arg(config_file_arg()); +) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool, Box), ConfiguratorError> { let env_args = Box::new(EnvironmentVcl::new(&app)).args(); let args_to_vec = args.to_vec(); let pre_orientation_args = match create_preorientation_args(env_args, args_to_vec.clone(), &app) { @@ -78,19 +70,12 @@ pub fn determine_user_specific_data ( .map(|vcl_arg| vcl_arg.dup()) .collect(); let orientation_vcl = CommandLineVcl::from(orientation_args); - let (config_file, data_dir, mut real_user) = config_file_and_data_dir_from_enumerate(orientation_vcl.args()); + let (config_file, data_dir, mut real_user) = config_file_real_user_data_dir_from_enumerate(orientation_vcl.args()); let config_user_specified = !config_file.is_empty(); let data_directory_specified = !data_dir.is_empty(); let real_user_specified = !real_user.is_empty(); if real_user.is_empty() { - let multi_config = MultiConfig::try_new(&orientation_schema, vec![]); - match multi_config { - Ok(multi_config) => { - real_user = real_user_from_multi_config_or_populate(&multi_config, dirs_wrapper).to_string(); - } - Err(e) => return Err(e) - } - + real_user = RealUser::new(None, None, None).populate(dirs_wrapper).to_string(); } let chain = match argument_from_enumerate(orientation_vcl.args(), "--chain".to_string()) { Some(chain) => { @@ -128,8 +113,8 @@ impl CombinedVcl { } fn create_preorientation_args(envargs: Vec, argstovec: Vec, app: &App) -> Result, ConfigFileVclError> { - let (env_config_file, env_data_dir, env_real_user) = config_file_and_data_dir_from_enumerate(envargs); - let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_and_data_dir_from_enumerate(argstovec); + let (env_config_file, env_data_dir, env_real_user) = config_file_real_user_data_dir_from_enumerate(envargs); + let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_real_user_data_dir_from_enumerate(argstovec); let mut combined_vcl: CombinedVcl = CombinedVcl { content: vec![] }; let combine_vcl = | name: String, vcl: &mut CombinedVcl, cmd_str: &String, env_str: &String | { if !cmd_str.is_empty() { @@ -148,8 +133,13 @@ fn create_preorientation_args(envargs: Vec, argstovec: Vec, app: combine_vcl("--data-directory".to_string(), &mut combined_vcl, &cmd_data_dir, &env_data_dir); combine_vcl("--config-file".to_string(), &mut combined_vcl, &cmd_config_file, &env_config_file); combine_vcl("--real-user".to_string(), &mut combined_vcl, &cmd_real_user, &env_real_user); + + // In case we define config file in ENV and we can find real-user in that file, therefore we need + // to specify also data-directory in Environment or Command line, to be Node able figure out the + // config file location, when config file is specified without absolute path or current directory eg.: "./" or "../" + if combined_vcl.len() > 0 { - let (mut config_file, data_directory, _real_user) = config_file_and_data_dir_from_enumerate(combined_vcl.content); + let (mut config_file, data_directory, _real_user) = config_file_real_user_data_dir_from_enumerate(combined_vcl.content); if !config_file.is_empty() && (!config_file.starts_with("/") && !config_file.starts_with("./") && !config_file.starts_with("../")) && data_directory.is_empty() { diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 95faebd3b..ef1a18e5b 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -145,42 +145,21 @@ pub fn server_initializer_collected_params<'a>( data_directory_specified, real_user, real_user_specified, - preorientation_args) = determine_user_specific_data(dirs_wrapper, &app, args)?; + pre_orientation_args) = determine_user_specific_data(dirs_wrapper, &app, args)?; let mut full_multi_config_vec: Vec> = vec![ Box::new(EnvironmentVcl::new(&app)), - preorientation_args + pre_orientation_args ]; - let config_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ - "".to_string(), "--config-file".to_string(), config_file_path.to_string_lossy().to_string(), - ])); - let config_unspcified_box: Box = Box::new(ComputedVcl::new(vec![ - "".to_string(), "--config-file".to_string(), config_file_path.to_string_lossy().to_string(), - ])); - match config_user_specified { - true => full_multi_config_vec.push(config_spcified_box), - false => full_multi_config_vec.push(config_unspcified_box) - }; - let data_directory_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ - "".to_string(), "--data-directory".to_string(), data_directory.to_string_lossy().to_string(), - ])); - let data_directory_unspcified_box: Box = Box::new(ComputedVcl::new(vec![ - "".to_string(), "--data-directory".to_string(), data_directory.to_string_lossy().to_string(), - ])); - match data_directory_specified { - true => full_multi_config_vec.push(data_directory_spcified_box), - false => full_multi_config_vec.push(data_directory_unspcified_box) - }; - let real_user_spcified_box: Box = Box::new(CommandLineVcl::new(vec![ - "".to_string(), "--real-user".to_string(), real_user.to_string(), - ])); - let real_user_unspcified_box: Box = Box::new(ComputedVcl::new(vec![ - "".to_string(), "--real-user".to_string(), real_user.to_string(), - ])); - match real_user_specified { - true => full_multi_config_vec.push(real_user_spcified_box), - false => full_multi_config_vec.push(real_user_unspcified_box) + let mut fill_specified_or_unspecified_box = |key: String, value: String, specified: bool | { + match specified { + true => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec!["".to_string(), key, value,]))), + false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec!["".to_string(), key, value,]))) + }; }; + fill_specified_or_unspecified_box("--config-file".to_string(), config_file_path.to_string_lossy().to_string(), config_user_specified); + fill_specified_or_unspecified_box("--data-directory".to_string(), data_directory.to_string_lossy().to_string(), data_directory_specified); + fill_specified_or_unspecified_box("--real-user".to_string(), real_user.to_string(), real_user_specified); let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; @@ -760,7 +739,7 @@ mod tests { fn fill_up_config_file(mut config_file: File) { { config_file - .write_all(b"real-user = \"1002:1002:wooga\"\n") + .write_all(b"real-user = \"1002:1002:/home/wooga\"\n") .unwrap(); config_file .write_all(b"blockchain-service-url = \"https://www.mainnet2.com\"\n") @@ -824,7 +803,7 @@ mod tests { false => { assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), - "wooga/data_dir/MASQ/polygon-mainnet".to_string() + "/home/wooga/data_dir/MASQ/polygon-mainnet".to_string() ) } } @@ -886,7 +865,7 @@ mod tests { true => { assert_eq!( &value_m!(env_multiconfig, "real-user", String).unwrap(), - "1002:1002:wooga" + "1002:1002:/home/wooga" ) }, false => () @@ -926,9 +905,8 @@ mod tests { let env_vec_array = vec![ ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml"), //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), - //#[cfg(not(target_os = "windows"))] + #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), - ("MASQ_MIN_HOPS", "3"), ]; env_vec_array.clone().into_iter() .for_each (|(name, value)| std::env::set_var (name, value)); @@ -946,7 +924,6 @@ mod tests { let env_multiconfig = result.unwrap(); let args = ArgsBuilder::new() - //.param("--config-file", "config.toml") .param("--data-directory", current_directory.join(Path::new("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home")).to_string_lossy().to_string().as_str()) .param("--real-user", "1001:1001:cooga"); let args_vec: Vec = args.into(); @@ -974,13 +951,13 @@ mod tests { () } } - //println!("env_multiconfig: {:#?}", env_multiconfig); + #[cfg(not(target_os = "windows"))] match env_multiconfig.is_user_specified("--real-user") { true => { assert_eq!( value_m!(env_multiconfig, "real-user", String).unwrap(), - "1002:1002:wooga".to_string() + "1002:1002:/home/wooga".to_string() ) } false => { @@ -1003,7 +980,7 @@ mod tests { false => { assert_eq!( value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "1002:1002:wooga".to_string() + "1002:1002:/home/wooga".to_string() ) } } From 61678568c6d87b05fd8e4c3f9b66dde5c7216be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Thu, 21 Sep 2023 14:41:12 +0200 Subject: [PATCH 09/24] computing env_args and cmd_args in create_preorientation_args fn! --- masq_lib/src/multi_config.rs | 33 +-- node/src/daemon/setup_reporter.rs | 4 +- node/src/node_configurator/mod.rs | 212 +++++++++++------- .../node_configurator_standard.rs | 72 +++++- 4 files changed, 209 insertions(+), 112 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index c389bb23d..0540710ed 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -62,21 +62,18 @@ impl<'a> MultiConfig<'a> { schema: &App<'a, 'a>, vcls: Vec>, ) -> Result, ConfiguratorError> { - let mut computed_value_names = HashSet::new(); let initial: Box = Box::new(CommandLineVcl::new(vec![String::new()])); - let vlc_copy = &vcls; - { - vlc_copy.into_iter().for_each(|vcl| { - vcl.vcl_args().iter().for_each(|vcl_arg| { - match vcl.is_computed() { - true => computed_value_names.insert(vcl_arg.name().to_string()), - false => computed_value_names.remove(&vcl_arg.name().to_string()) - }; - }) - }); - } - let merged: Box = vcls.into_iter().fold(initial, |so_far, vcl | -> Box { + let mut computed_value_names = HashSet::new(); + vcls.iter().for_each(|vcl| { + vcl.vcl_args().iter().for_each(|vcl_arg| { + match vcl.is_computed() { + true => computed_value_names.insert(vcl_arg.name().to_string()), + false => computed_value_names.remove(&vcl_arg.name().to_string()) + }; + }) + }); + let merged = vcls.into_iter().fold(initial, |so_far, vcl | { merge(so_far, vcl) }); @@ -432,16 +429,6 @@ impl VirtualCommandLine for ConfigFileVcl { vcl_args_to_args(&self.vcl_args) } } -/* -impl VirtualCommandLine for dyn VclArg { - fn vcl_args(&self) -> Vec<&dyn VclArg> { - vcl_args_to_vcl_args(&[Box::new(self.vcl_args().as_slice())]) - } - - fn args(&self) -> Vec { - vcl_args_to_args(&[Box::new(self.vcl_args().as_slice())]) - } -}*/ #[derive(Debug)] pub enum ConfigFileVclError { diff --git a/node/src/daemon/setup_reporter.rs b/node/src/daemon/setup_reporter.rs index 79b4a34b8..fd060b145 100644 --- a/node/src/daemon/setup_reporter.rs +++ b/node/src/daemon/setup_reporter.rs @@ -495,9 +495,9 @@ impl SetupReporterReal { Some(command_line) => command_line, None => vec![], }; - let (config_file_path, user_specified, _data_directory, _data_directory_specified, _real_user, _real_user_specified, _preorientation_args) = + let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, &command_line)?; - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { + let config_file_vcl = match ConfigFileVcl::new(&user_specific_data.config_file, user_specific_data.config_file_specified) { Ok(cfv) => cfv, Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 0513c70ff..8ab7f9d23 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -27,14 +27,14 @@ pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } -fn config_file_real_user_data_dir_from_enumerate(configs: Vec) -> (String, String, String) { - let config_match = argument_from_enumerate(configs.clone(), "--config-file".to_string()).unwrap_or("".to_string()); - let data_dir_match = argument_from_enumerate(configs.clone(), "--data-directory".to_string()).unwrap_or("".to_string()); - let real_user_match = argument_from_enumerate(configs, "--real-user".to_string()).unwrap_or("".to_string()); +fn config_file_data_dir_real_user_from_enumerate(configs: &Vec) -> (String, String, String) { + let config_match = argument_from_enumerate(&configs, "--config-file").unwrap_or("".to_string()); + let data_dir_match = argument_from_enumerate(&configs, "--data-directory").unwrap_or("".to_string()); + let real_user_match = argument_from_enumerate(configs, "--real-user").unwrap_or("".to_string()); (config_match, data_dir_match, real_user_match) } -fn argument_from_enumerate(configs: Vec, needle: String) -> Option { +fn argument_from_enumerate(configs: &Vec, needle: &str) -> Option { let mut arg_match = None; for (i, arg) in configs.iter().enumerate() { if arg.as_str() == needle { @@ -44,21 +44,27 @@ fn argument_from_enumerate(configs: Vec, needle: String) -> Option +} + pub fn determine_user_specific_data ( dirs_wrapper: &dyn DirsWrapper, app: &App, args: &[String], -) -> Result<(PathBuf, bool, PathBuf, bool, RealUser, bool, Box), ConfiguratorError> { - let env_args = Box::new(EnvironmentVcl::new(&app)).args(); - let args_to_vec = args.to_vec(); - let pre_orientation_args = match create_preorientation_args(env_args, args_to_vec.clone(), &app) { +) -> Result { + + let pre_orientation_args = match create_preorientation_args(args, &app, dirs_wrapper) { Ok(pre_orientation_args) => pre_orientation_args, Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())) }; - let orientation_args: Vec> = merge( - pre_orientation_args, - Box::new(CommandLineVcl::new(args_to_vec)) - ) + let orientation_args: Vec> = pre_orientation_args .vcl_args() .into_iter() .filter(|vcl_arg| { @@ -70,14 +76,14 @@ pub fn determine_user_specific_data ( .map(|vcl_arg| vcl_arg.dup()) .collect(); let orientation_vcl = CommandLineVcl::from(orientation_args); - let (config_file, data_dir, mut real_user) = config_file_real_user_data_dir_from_enumerate(orientation_vcl.args()); + let (mut config_file, data_dir, mut real_user) = config_file_data_dir_real_user_from_enumerate(&orientation_vcl.args()); let config_user_specified = !config_file.is_empty(); let data_directory_specified = !data_dir.is_empty(); let real_user_specified = !real_user.is_empty(); if real_user.is_empty() { real_user = RealUser::new(None, None, None).populate(dirs_wrapper).to_string(); } - let chain = match argument_from_enumerate(orientation_vcl.args(), "--chain".to_string()) { + let chain = match argument_from_enumerate(&orientation_vcl.args(), "--chain") { Some(chain) => { Chain::from(chain.as_str()) }, @@ -92,14 +98,27 @@ pub fn determine_user_specific_data ( false => PathBuf::from(data_dir), true => data_directory_from_context(dirs_wrapper, &real_user_obj, chain), }; - Ok(( - PathBuf::from(config_file), - config_user_specified, + // let final_orientation_args; + // if !config_user_specified { + // config_file = data_directory.join("config.toml").to_string_lossy().to_string(); + // final_orientation_args = merge( + // Box::new(orientation_vcl), + // Box::new(CommandLineVcl::new(vec!["".to_string(), "--config-file".to_string(), config_file.clone()])) + // ); + // } else { + // final_orientation_args = Box::new(orientation_vcl); + // } + + Ok( UserSpecificData { + config_file: PathBuf::from(config_file), + config_file_specified: config_user_specified, data_directory, data_directory_specified, - real_user_obj, + real_user: real_user_obj, real_user_specified, - Box::new(orientation_vcl))) + pre_orientation_args: Box::new(orientation_vcl) + } + ) } struct CombinedVcl { @@ -112,9 +131,11 @@ impl CombinedVcl { } } -fn create_preorientation_args(envargs: Vec, argstovec: Vec, app: &App) -> Result, ConfigFileVclError> { - let (env_config_file, env_data_dir, env_real_user) = config_file_real_user_data_dir_from_enumerate(envargs); - let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_real_user_data_dir_from_enumerate(argstovec); +fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn DirsWrapper,) -> Result, ConfigFileVclError> { + let env_args = Box::new(EnvironmentVcl::new(&app)).args(); + let cmd_args = cmd_args.to_vec(); + let (env_config_file, env_data_dir, env_real_user) = config_file_data_dir_real_user_from_enumerate(&env_args); + let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_data_dir_real_user_from_enumerate(&cmd_args); let mut combined_vcl: CombinedVcl = CombinedVcl { content: vec![] }; let combine_vcl = | name: String, vcl: &mut CombinedVcl, cmd_str: &String, env_str: &String | { if !cmd_str.is_empty() { @@ -139,36 +160,79 @@ fn create_preorientation_args(envargs: Vec, argstovec: Vec, app: // config file location, when config file is specified without absolute path or current directory eg.: "./" or "../" if combined_vcl.len() > 0 { - let (mut config_file, data_directory, _real_user) = config_file_real_user_data_dir_from_enumerate(combined_vcl.content); - if !config_file.is_empty() && - (!config_file.starts_with("/") && !config_file.starts_with("./") && !config_file.starts_with("../")) - && data_directory.is_empty() { - return Err(ConfigFileVclError::InvalidConfig( - PathBuf::from(&config_file), - "Config file defined in Environment with relative path needs data-directory to be defined too".to_string() - )); + let (mut config_file, data_directory, real_user) = config_file_data_dir_real_user_from_enumerate(&combined_vcl.content); + if !config_file.is_empty() { + if (!config_file.starts_with("/") && !config_file.starts_with("./") && !config_file.starts_with("../")) + && data_directory.is_empty() { + return Err(ConfigFileVclError::InvalidConfig( + PathBuf::from(&config_file), + "Config file defined in Environment with relative path needs data-directory to be defined too".to_string() + )); + } + + if config_file.starts_with("./") { + let pwd = current_dir().expect("expected current directory"); + config_file = config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); + } + + let mut config_file_path = PathBuf::from(&config_file.to_string()); + let user_specified = !config_file.is_empty(); + if config_file_path.is_relative() && !data_directory.is_empty() { + config_file_path = PathBuf::from(data_directory.to_string()).join(config_file_path); + } + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { + Ok(cfv) => Box::new(cfv), + Err(e) => return Err(e), + }; + let args = merge( + Box::new(EnvironmentVcl::new(app)), + config_file_vcl, + ); + let args = merge( + args, + Box::new(CommandLineVcl::new( + vec!["".to_string(), + "--config-file".to_string(), + config_file_path.to_string_lossy().to_string()] + )) + ); + Ok(args) + } else { + let config_file = PathBuf::from("config.toml"); + let config_file_path = match data_directory.as_str() { + "" => PathBuf::from().join(config_file), + _ => + }; + let args = merge( + Box::new(EnvironmentVcl::new(app)), + Box::new(CommandLineVcl::new( + vec!["".to_string(), + "--config-file".to_string(), + config_file_path.to_string_lossy().to_string()] + )) + ); + Ok(args) } - if config_file.starts_with("./") { - let pwd = current_dir().expect("expected current directory"); - config_file = config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); - } - - let mut config_file_path = PathBuf::from(&config_file.to_string()); - let user_specified = !config_file.is_empty(); - if config_file_path.is_relative() && !data_directory.is_empty() { - config_file_path = PathBuf::from(data_directory.to_string()).join(config_file_path); - } - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(e), + } else { + //Ok(Box::new(EnvironmentVcl::new(app))) + let config_file = PathBuf::from("config.toml"); + let real_user = &RealUser::new(None, None, None).populate(dirs_wrapper); + let cmd_chain = argument_from_enumerate(&cmd_args, "--chain").expect("expected chain"); + let env_chain = argument_from_enumerate(&env_args, "--chain").expect("expected chain"); + let chain = match cmd_chain.is_empty() { + true => { + match env_chain.is_empty() { + true => DEFAULT_CHAIN.rec().literal_identifier, + false => env_chain.as_str() + } + } + false => cmd_chain.as_str() }; + let data_dir = data_directory_from_context(dirs_wrapper, real_user, Chain::from(chain)); + let config_file_path = PathBuf::from(data_dir).join(config_file); let args = merge( Box::new(EnvironmentVcl::new(app)), - config_file_vcl, - ); - let args = merge( - args, Box::new(CommandLineVcl::new( vec!["".to_string(), "--config-file".to_string(), @@ -176,8 +240,6 @@ fn create_preorientation_args(envargs: Vec, argstovec: Vec, app: )) ); Ok(args) - } else { - Ok(Box::new(EnvironmentVcl::new(app))) } } @@ -319,18 +381,18 @@ mod tests { .param("--config-file", "booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified, _preorientation) = determine_user_specific_data( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), ) .unwrap(); assert_eq!( - &format!("{}", config_file_path.parent().unwrap().display()), - &data_directory.to_string_lossy().to_string(), + &format!("{}", user_specific_data.config_file.parent().unwrap().display()), + &user_specific_data.data_directory.to_string_lossy().to_string(), ); - assert_eq!("booga.toml", config_file_path.file_name().unwrap()); - assert_eq!(true, user_specified); + assert_eq!("booga.toml", user_specific_data.config_file.file_name().unwrap()); + assert_eq!(true, user_specific_data.real_user_specified); } #[test] @@ -348,18 +410,18 @@ mod tests { ); std::env::set_var("MASQ_CONFIG_FILE", "booga.toml"); - let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified, _preorientation_args) = determine_user_specific_data( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), ) .unwrap(); assert_eq!( - format!("{}", config_file_path.parent().unwrap().display()), - data_directory.to_string_lossy().to_string(), + format!("{}", user_specific_data.config_file.parent().unwrap().display()), + user_specific_data.data_directory.to_string_lossy().to_string(), ); - assert_eq!("booga.toml", config_file_path.file_name().unwrap()); - assert_eq!(true, user_specified); + assert_eq!("booga.toml", user_specific_data.config_file.file_name().unwrap()); + assert_eq!(true, user_specific_data.real_user_specified); } #[cfg(not(target_os = "windows"))] @@ -371,7 +433,7 @@ mod tests { .param("--config-file", "/tmp/booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _data_dir_specified, _real_user, _real_user_specified, _preorientation_args) = determine_user_specific_data( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -380,9 +442,9 @@ mod tests { assert_eq!( "/tmp/booga.toml", - &format!("{}", config_file_path.display()) + &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specified); + assert_eq!(true, user_specific_data.real_user_specified); } #[cfg(target_os = "windows")] @@ -394,7 +456,7 @@ mod tests { .param("--config-file", r"\tmp\booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -403,9 +465,9 @@ mod tests { assert_eq!( r"\tmp\booga.toml", - &format!("{}", config_file_path.display()) + &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specified); + assert_eq!(true, user_specific_data.real_user_specified); } #[cfg(target_os = "windows")] @@ -417,7 +479,7 @@ mod tests { .param("--config-file", r"c:\tmp\booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -426,9 +488,9 @@ mod tests { assert_eq!( r"c:\tmp\booga.toml", - &format!("{}", config_file_path.display()) + &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specified); + assert_eq!(true, user_specific_data.real_user_specified); } #[cfg(target_os = "windows")] @@ -440,7 +502,7 @@ mod tests { .param("--config-file", r"\\TMP\booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -449,9 +511,9 @@ mod tests { assert_eq!( r"\\TMP\booga.toml", - &format!("{}", config_file_path.display()) + &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specified); + assert_eq!(true, user_specific_data.real_user_specified); } #[cfg(target_os = "windows")] @@ -464,7 +526,7 @@ mod tests { .param("--config-file", r"c:tmp\booga.toml"); let args_vec: Vec = args.into(); - let (config_file_path, user_specified, _data_dir, _real_user) = determine_fundamentals( + let user_specific_data = determine_user_specific_data( &DirsWrapperReal {}, &determine_config_file_path_app(), args_vec.as_slice(), @@ -473,9 +535,9 @@ mod tests { assert_eq!( r"c:tmp\booga.toml", - &format!("{}", config_file_path.display()) + &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specified); + assert_eq!(true, user_specific_data.real_user_specified); } #[test] diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index ef1a18e5b..3bfb68ad1 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -139,16 +139,10 @@ pub fn server_initializer_collected_params<'a>( args: &[String], ) -> Result, ConfiguratorError> { let app = app_node(); - let (config_file_path, - config_user_specified, - data_directory, - data_directory_specified, - real_user, - real_user_specified, - pre_orientation_args) = determine_user_specific_data(dirs_wrapper, &app, args)?; + let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, args)?; let mut full_multi_config_vec: Vec> = vec![ Box::new(EnvironmentVcl::new(&app)), - pre_orientation_args + user_specific_data.pre_orientation_args ]; let mut fill_specified_or_unspecified_box = |key: String, value: String, specified: bool | { @@ -157,9 +151,9 @@ pub fn server_initializer_collected_params<'a>( false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec!["".to_string(), key, value,]))) }; }; - fill_specified_or_unspecified_box("--config-file".to_string(), config_file_path.to_string_lossy().to_string(), config_user_specified); - fill_specified_or_unspecified_box("--data-directory".to_string(), data_directory.to_string_lossy().to_string(), data_directory_specified); - fill_specified_or_unspecified_box("--real-user".to_string(), real_user.to_string(), real_user_specified); + fill_specified_or_unspecified_box("--config-file".to_string(), user_specific_data.config_file.to_string_lossy().to_string(), user_specific_data.config_file_specified); + fill_specified_or_unspecified_box("--data-directory".to_string(), user_specific_data.data_directory.to_string_lossy().to_string(), user_specific_data.data_directory_specified); + fill_specified_or_unspecified_box("--real-user".to_string(), user_specific_data.real_user.to_string(), user_specific_data.real_user_specified); let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; @@ -477,8 +471,10 @@ mod tests { &directory_wrapper, &slice_of_strs_to_vec_of_strings(&["", "--data-directory", home_dir.to_str().unwrap()]), ) + // generated/test/node_configurator_standard/server_initializer_collected_params_can_read_parameters_from_config_file/home + // /Users/vojtechparkan/Projekty/Node/node/generated/test/node_configurator_standard/server_initializer_collected_params_can_read_parameters_from_config_file/home .unwrap(); - + println!("multiconfig: {:#?}", multi_config); assert_eq!( value_m!(multi_config, "dns-servers", String).unwrap(), "111.111.111.111,222.222.222.222".to_string() @@ -775,6 +771,58 @@ mod tests { } } + #[test] + fn multi_config_vcl_is_computed_do_right_job() { + running_test(); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + let data_dir = &home_dir.join("data_dir"); + let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); + fill_up_config_file(config_file_relative); + let env_vec_array = vec![ + ("MASQ_CONFIG_FILE", "./generated/config.toml"), + #[cfg(not(target_os = "windows"))] + ("MASQ_REAL_USER", "9999:9999:booga"), + ]; + env_vec_array.clone().into_iter() + .for_each (|(name, value)| std::env::set_var (name, value)); + let args = ArgsBuilder::new(); + let args_vec: Vec = args.into(); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(home_dir.clone())) + .data_dir_result(Some(data_dir.to_path_buf())); + + let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + let env_multiconfig = result.unwrap(); + + match env_multiconfig.is_user_specified("--data-directory") { + true => (), + false => { + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "/home/wooga/data_dir/MASQ/polygon-mainnet".to_string() + ) + } + } + + match (env_multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { + (true, true) => { + let pwd = PathBuf::from( value_m!(env_multiconfig, "data-directory", String).unwrap()); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() + ) + }, + (true, false) => { + let pwd = current_dir().unwrap(); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() + ) + }, + (_, _) => () + } + } + #[test] fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot() { running_test(); From 7286ee887657e8745ac61040cca40dde03c3fec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 4 Oct 2023 15:05:05 +0200 Subject: [PATCH 10/24] fix passing test server_initializer_collected_params_can_read_parameters_from_config_file, some optimization --- node/src/node_configurator/mod.rs | 97 ++++++++++++------- .../node_configurator_standard.rs | 15 +-- 2 files changed, 70 insertions(+), 42 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 8ab7f9d23..0464295e5 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -116,8 +116,8 @@ pub fn determine_user_specific_data ( data_directory_specified, real_user: real_user_obj, real_user_specified, - pre_orientation_args: Box::new(orientation_vcl) - } + pre_orientation_args + } ) } @@ -159,9 +159,13 @@ fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn // to specify also data-directory in Environment or Command line, to be Node able figure out the // config file location, when config file is specified without absolute path or current directory eg.: "./" or "../" + let computed_real_user = &RealUser::new(None, None, None).populate(dirs_wrapper); + let preargs: Box; + let mut config_file_path: PathBuf; if combined_vcl.len() > 0 { - let (mut config_file, data_directory, real_user) = config_file_data_dir_real_user_from_enumerate(&combined_vcl.content); + let (mut config_file, data_directory, _real_user) = config_file_data_dir_real_user_from_enumerate(&combined_vcl.content); if !config_file.is_empty() { + println!("if"); if (!config_file.starts_with("/") && !config_file.starts_with("./") && !config_file.starts_with("../")) && data_directory.is_empty() { return Err(ConfigFileVclError::InvalidConfig( @@ -175,7 +179,7 @@ fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn config_file = config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); } - let mut config_file_path = PathBuf::from(&config_file.to_string()); + config_file_path = PathBuf::from(&config_file.to_string()); let user_specified = !config_file.is_empty(); if config_file_path.is_relative() && !data_directory.is_empty() { config_file_path = PathBuf::from(data_directory.to_string()).join(config_file_path); @@ -184,40 +188,52 @@ fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn Ok(cfv) => Box::new(cfv), Err(e) => return Err(e), }; - let args = merge( - Box::new(EnvironmentVcl::new(app)), + preargs = merge( config_file_vcl, + Box::new(EnvironmentVcl::new(app)), ); - let args = merge( - args, - Box::new(CommandLineVcl::new( - vec!["".to_string(), - "--config-file".to_string(), - config_file_path.to_string_lossy().to_string()] - )) + } else if !data_directory.as_str().is_empty() { + println!("data dir not empty"); + let config_file = PathBuf::from("config.toml"); + config_file_path = PathBuf::from(data_directory).join(config_file); + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, false) { + Ok(cfv) => Box::new(cfv), + Err(e) => return Err(e), + }; + preargs = merge( + config_file_vcl, + Box::new(EnvironmentVcl::new(app)), ); - Ok(args) } else { + println!("data dir is empty"); let config_file = PathBuf::from("config.toml"); - let config_file_path = match data_directory.as_str() { - "" => PathBuf::from().join(config_file), - _ => + + let cmd_chain = argument_from_enumerate(&cmd_args, "--chain").expect("expected chain"); + let env_chain = argument_from_enumerate(&env_args, "--chain").expect("expected chain"); + let chain = match cmd_chain.is_empty() { + true => { + match env_chain.is_empty() { + true => DEFAULT_CHAIN.rec().literal_identifier, + false => env_chain.as_str() + } + } + false => cmd_chain.as_str() + }; + let data_dir = data_directory_from_context(dirs_wrapper, computed_real_user, Chain::from(chain)); + config_file_path = PathBuf::from(data_dir).join(config_file); + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, false) { + Ok(cfv) => Box::new(cfv), + Err(e) => return Err(e), }; - let args = merge( + preargs = merge( + config_file_vcl, Box::new(EnvironmentVcl::new(app)), - Box::new(CommandLineVcl::new( - vec!["".to_string(), - "--config-file".to_string(), - config_file_path.to_string_lossy().to_string()] - )) ); - Ok(args) } } else { - //Ok(Box::new(EnvironmentVcl::new(app))) let config_file = PathBuf::from("config.toml"); - let real_user = &RealUser::new(None, None, None).populate(dirs_wrapper); + // let real_user = &RealUser::new(None, None, None).populate(dirs_wrapper); let cmd_chain = argument_from_enumerate(&cmd_args, "--chain").expect("expected chain"); let env_chain = argument_from_enumerate(&env_args, "--chain").expect("expected chain"); let chain = match cmd_chain.is_empty() { @@ -229,18 +245,29 @@ fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn } false => cmd_chain.as_str() }; - let data_dir = data_directory_from_context(dirs_wrapper, real_user, Chain::from(chain)); - let config_file_path = PathBuf::from(data_dir).join(config_file); - let args = merge( + let data_dir = data_directory_from_context(dirs_wrapper, computed_real_user, Chain::from(chain)); + config_file_path = PathBuf::from(data_dir).join(config_file); + let config_file_vcl = match ConfigFileVcl::new(&config_file_path, false) { + Ok(cfv) => Box::new(cfv), + Err(e) => return Err(e), + }; + preargs = merge( + config_file_vcl, Box::new(EnvironmentVcl::new(app)), - Box::new(CommandLineVcl::new( - vec!["".to_string(), - "--config-file".to_string(), - config_file_path.to_string_lossy().to_string()] - )) ); - Ok(args) } + println!("completition"); + //Ok(Box::new(EnvironmentVcl::new(app))) + + let args = merge( + preargs, + Box::new(CommandLineVcl::new( + vec!["".to_string(), + "--config-file".to_string(), + config_file_path.to_string_lossy().to_string()] + )) + ); + Ok(args) } pub fn initialize_database( diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 3bfb68ad1..c98eb3801 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -140,21 +140,22 @@ pub fn server_initializer_collected_params<'a>( ) -> Result, ConfiguratorError> { let app = app_node(); let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, args)?; + println!("user_specific_data.pre_orientation_args: {:#?}", user_specific_data.pre_orientation_args); let mut full_multi_config_vec: Vec> = vec![ Box::new(EnvironmentVcl::new(&app)), user_specific_data.pre_orientation_args ]; - let mut fill_specified_or_unspecified_box = |key: String, value: String, specified: bool | { + let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool | { match specified { - true => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec!["".to_string(), key, value,]))), - false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec!["".to_string(), key, value,]))) + true => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec!["".to_string(), key.to_string(), value.to_string(),]))), + false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec!["".to_string(), key.to_string(), value.to_string(),]))) }; }; - fill_specified_or_unspecified_box("--config-file".to_string(), user_specific_data.config_file.to_string_lossy().to_string(), user_specific_data.config_file_specified); - fill_specified_or_unspecified_box("--data-directory".to_string(), user_specific_data.data_directory.to_string_lossy().to_string(), user_specific_data.data_directory_specified); - fill_specified_or_unspecified_box("--real-user".to_string(), user_specific_data.real_user.to_string(), user_specific_data.real_user_specified); - + fill_specified_or_unspecified_box("--config-file", user_specific_data.config_file.to_string_lossy().as_ref(), user_specific_data.config_file_specified); + fill_specified_or_unspecified_box("--data-directory", user_specific_data.data_directory.to_string_lossy().as_ref(), user_specific_data.data_directory_specified); + fill_specified_or_unspecified_box("--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_specified); + println!("full_multi_config_vec: {:#?}", full_multi_config_vec); let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; Ok(full_multi_config) From fce6fe10ab4ad50d704b2618ef7a71b1cfd0b455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 11 Oct 2023 19:11:51 +0200 Subject: [PATCH 11/24] fixed VclArg problem with withdrawing data from VirtualCommandline, sorted server_initializer_collected_params and determine_user_specific_data fncs, new fns value_opt for VclArg and tests for them --- masq_lib/src/multi_config.rs | 46 +- node/src/node_configurator/mod.rs | 465 ++++++++++-------- .../node_configurator_standard.rs | 380 +++++++------- 3 files changed, 504 insertions(+), 387 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index 0540710ed..8f1c51e49 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -172,6 +172,7 @@ impl<'a> MultiConfig<'a> { pub trait VclArg: Debug { fn name(&self) -> &str; + fn value_opt(&self) -> Option<&str>; fn to_args(&self) -> Vec; fn dup(&self) -> Box; } @@ -197,7 +198,9 @@ impl VclArg for NameValueVclArg { fn name(&self) -> &str { &self.name } - + fn value_opt(&self) -> Option<&str> { + Some(self.value.as_str()) + } fn to_args(&self) -> Vec { vec![self.name.clone(), self.value.clone()] } @@ -225,7 +228,9 @@ impl VclArg for NameOnlyVclArg { fn name(&self) -> &str { &self.name } - + fn value_opt(&self) -> Option<&str> { + None + } fn to_args(&self) -> Vec { vec![self.name.clone()] } @@ -579,6 +584,7 @@ pub mod tests { use clap::Arg; use std::fs::File; use std::io::Write; + use std::ops::Deref; #[test] fn config_file_vcl_error_displays_open_error() { @@ -1024,6 +1030,42 @@ pub mod tests { assert_eq!(subject.args(), command_line); } + #[test] + fn command_line_vcl_return_value_from_vcl_args_by_name() { + let command_line: Vec = vec![ + "", + "--first-value", + "/nonexistent/directory", + "--takes_no_value", + "--other_takes_no_value", + ] + .into_iter() + .map(|s| s.to_string()) + .collect(); + + let subject = CommandLineVcl::new(command_line.clone()); + let existing_value = match subject.vcl_args + .iter() + .find(|vcl_arg_box| vcl_arg_box.deref().name() == "--first-value" ) { + Some(vcl_arg_box) => vcl_arg_box.deref().value_opt(), + None => None + }; + let non_existing_value = match subject.vcl_args + .iter() + .find(|vcl_arg_box| vcl_arg_box.deref().name() == "--takes_no_value" ) { + Some(vcl_arg_box) => vcl_arg_box.deref().value_opt(), + None => None + }; + assert_eq!( + existing_value.unwrap(), + "/nonexistent/directory" + ); + assert_eq!( + non_existing_value, + None + ); + } + #[test] #[should_panic(expected = "Expected option beginning with '--', not value")] fn command_line_vcl_panics_when_given_value_without_name() { diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 0464295e5..801431e7b 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -7,6 +7,7 @@ pub mod unprivileged_parse_args_configuration; use std::env::{current_dir}; use crate::bootstrapper::RealUser; +use core::option::Option; use crate::database::db_initializer::DbInitializationConfig; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::persistent_configuration::{ @@ -18,40 +19,71 @@ use dirs::{data_local_dir, home_dir}; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg, VirtualCommandLine, ConfigFileVcl, ConfigFileVclError}; -use masq_lib::shared_schema::{config_file_arg, data_directory_arg, ConfiguratorError,DATA_DIRECTORY_HELP}; +use masq_lib::shared_schema::{config_file_arg, data_directory_arg, ConfiguratorError, DATA_DIRECTORY_HELP, chain_arg, real_user_arg}; use masq_lib::utils::{add_masq_and_chain_directories, localhost}; use std::net::{SocketAddr, TcpListener}; +use std::ops::Deref; use std::path::{Path, PathBuf}; +use libc::option; + pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } -fn config_file_data_dir_real_user_from_enumerate(configs: &Vec) -> (String, String, String) { - let config_match = argument_from_enumerate(&configs, "--config-file").unwrap_or("".to_string()); - let data_dir_match = argument_from_enumerate(&configs, "--data-directory").unwrap_or("".to_string()); - let real_user_match = argument_from_enumerate(configs, "--real-user").unwrap_or("".to_string()); - (config_match, data_dir_match, real_user_match) -} +fn config_file_data_dir_real_user_chain_from_enumerate(dirs_wrapper: &dyn DirsWrapper, configs: Vec>) + -> (Option, Option, Option, Option) { + let configs = configs.as_slice(); + let chain = match argument_from_enumerate(configs, "--chain") { + Some(chain) => Chain::from( chain), + None => DEFAULT_CHAIN + }; + let real_user = match argument_from_enumerate(configs, "--real-user") { + Some(user) => { + let real_user_split: Vec<&str> = user.split(":").collect(); + RealUser::new( + Some(real_user_split[0].parse::().expect("expected user id")), + Some(real_user_split[1].parse::().expect("expected user group")), + Some(PathBuf::from(real_user_split[2])) + ) -fn argument_from_enumerate(configs: &Vec, needle: &str) -> Option { - let mut arg_match = None; - for (i, arg) in configs.iter().enumerate() { - if arg.as_str() == needle { - arg_match = Some(configs[i + 1].to_string()) + }, + None => RealUser::new(None, None, None).populate(dirs_wrapper) + }; + let data_directory = match argument_from_enumerate(configs, "--data-directory") { + Some(data_dir) => PathBuf::from(&data_dir), + None => data_directory_from_context(dirs_wrapper, &real_user, chain) + }; + let config_match = match argument_from_enumerate(configs, "--config-file") { + Some(config_str) => { + match PathBuf::from(config_str).is_relative() { + true => current_dir().expect("expected curerrnt dir").join(PathBuf::from(config_str)), + false => PathBuf::from(config_str) + } } + None => PathBuf::from(&data_directory).join(PathBuf::from("config.toml")) }; - arg_match + (Some(config_match), Some(data_directory), Some(real_user), Some(chain)) +} + +fn argument_from_enumerate<'a>(configs: &'a [Box], needle: &'a str) -> Option<&'a str> { + match configs + .iter() + .find(|vcl_arg_box| vcl_arg_box.deref().name() == needle ) { + Some(vcl_arg_box) => vcl_arg_box.deref().value_opt(), + None => None + } } +#[derive(Debug)] pub struct UserSpecificData { pub(crate) config_file: PathBuf, pub(crate) config_file_specified: bool, - pub(crate) data_directory: PathBuf, + pub(crate) data_directory: Option, pub(crate) data_directory_specified: bool, - pub(crate) real_user: RealUser, + pub(crate) real_user: Option, pub(crate) real_user_specified: bool, - pub(crate) pre_orientation_args: Box + // pub config_file_vcl: Box, } pub fn determine_user_specific_data ( @@ -60,63 +92,97 @@ pub fn determine_user_specific_data ( args: &[String], ) -> Result { - let pre_orientation_args = match create_preorientation_args(args, &app, dirs_wrapper) { - Ok(pre_orientation_args) => pre_orientation_args, - Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())) - }; - let orientation_args: Vec> = pre_orientation_args - .vcl_args() - .into_iter() - .filter(|vcl_arg| { - (vcl_arg.name() == "--chain") - || (vcl_arg.name() == "--real-user") - || (vcl_arg.name() == "--data-directory") - || (vcl_arg.name() == "--config-file") - }) - .map(|vcl_arg| vcl_arg.dup()) - .collect(); - let orientation_vcl = CommandLineVcl::from(orientation_args); - let (mut config_file, data_dir, mut real_user) = config_file_data_dir_real_user_from_enumerate(&orientation_vcl.args()); - let config_user_specified = !config_file.is_empty(); - let data_directory_specified = !data_dir.is_empty(); - let real_user_specified = !real_user.is_empty(); - if real_user.is_empty() { - real_user = RealUser::new(None, None, None).populate(dirs_wrapper).to_string(); - } - let chain = match argument_from_enumerate(&orientation_vcl.args(), "--chain") { - Some(chain) => { - Chain::from(chain.as_str()) - }, - None => DEFAULT_CHAIN - }; - let real_user_split: Vec<&str> = real_user.split(":").collect(); - let real_user_obj = RealUser::new( - Some(real_user_split[0].parse::().expect("expected user id")), - Some(real_user_split[1].parse::().expect("expected user group")), - Some(PathBuf::from(real_user_split[2]))); - let data_directory = match data_dir.is_empty() { - false => PathBuf::from(data_dir), - true => data_directory_from_context(dirs_wrapper, &real_user_obj, chain), + // let pre_orientation_args = match create_preorientation_args(args, &app, dirs_wrapper); + let mut data_directory_specified: bool = false; + let mut real_user_specified: bool = false; + let mut config_file_specified: bool = false; + let config_file_path: PathBuf; + let orientation_schema = App::new("MASQNode") + .arg(chain_arg()) + .arg(real_user_arg()) + .arg(data_directory_arg(DATA_DIRECTORY_HELP)) + .arg(config_file_arg()); + let orientation_args: Vec> = merge( + Box::new(EnvironmentVcl::new(&orientation_schema)), + Box::new(CommandLineVcl::new(args.to_vec())), + ) + .vcl_args() + .into_iter() + .filter(|vcl_arg| { + (vcl_arg.name() == "--chain") + || (vcl_arg.name() == "--real-user") + || (vcl_arg.name() == "--data-directory") + || (vcl_arg.name() == "--config-file") + }) + .map(|vcl_arg| vcl_arg.dup()) + .collect(); + let (config_file,data_directory,real_user, chain) = + config_file_data_dir_real_user_chain_from_enumerate( dirs_wrapper, orientation_args); + match config_file { + Some(config_file_pth) => { + config_file_specified = true; + config_file_path = config_file_pth; + // match ConfigFileVcl::new(&config_file_path, config_file_specified) { + // Ok(cfv) => Box::new(cfv), + // Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), + // } + } + None => { + config_file_specified = false; + config_file_path = data_directory.clone().expect("expect data directory").join("config.toml"); + // match ConfigFileVcl::new(&config_file_path, config_file_specified) { + // Ok(cfv) => Box::new(cfv), + // Err(e) => e, + // } + } }; - // let final_orientation_args; - // if !config_user_specified { - // config_file = data_directory.join("config.toml").to_string_lossy().to_string(); - // final_orientation_args = merge( - // Box::new(orientation_vcl), - // Box::new(CommandLineVcl::new(vec!["".to_string(), "--config-file".to_string(), config_file.clone()])) - // ); - // } else { - // final_orientation_args = Box::new(orientation_vcl); - // } - + //println!("determine_user_specific_data orientation_args {:#?}", &orientation_args); + {// let config_file_vcl = match ConfigFileVcl::new(&config_file_path, config_file_specified) { + // Ok(cfv) => Box::new(cfv), + // Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), + // }; + + // let config_user_specified = !config_file.is_empty(); + // let data_directory_specified = !data_dir.is_empty(); + // let real_user_specified = !real_user.is_empty(); + // if real_user.is_empty() { + // real_user = RealUser::new(None, None, None).populate(dirs_wrapper).to_string(); + // } + // let chain = match argument_from_enumerate(&orientation_vcl.args(), "--chain") { + // Some(chain) => { + // Chain::from(chain.as_str()) + // }, + // None => DEFAULT_CHAIN + // }; + // let real_user_split: Vec<&str> = real_user.split(":").collect(); + // let real_user_obj = RealUser::new( + // Some(real_user_split[0].parse::().expect("expected user id")), + // Some(real_user_split[1].parse::().expect("expected user group")), + // Some(PathBuf::from(real_user_split[2]))); + // let data_directory = match data_dir.is_empty() { + // false => PathBuf::from(data_dir), + // true => data_directory_from_context(dirs_wrapper, &real_user_obj, chain), + // }; + // let final_orientation_args; + // if !config_user_specified { + // config_file = data_directory.join("config.toml").to_string_lossy().to_string(); + // final_orientation_args = merge( + // Box::new(orientation_vcl), + // Box::new(CommandLineVcl::new(vec!["".to_string(), "--config-file".to_string(), config_file.clone()])) + // ); + // } else { + // final_orientation_args = Box::new(orientation_vcl); + // } + // let final_orientation_args = Box::new(orientation_vcl); + } Ok( UserSpecificData { - config_file: PathBuf::from(config_file), - config_file_specified: config_user_specified, + config_file: config_file_path, + config_file_specified, data_directory, data_directory_specified, - real_user: real_user_obj, + real_user, real_user_specified, - pre_orientation_args + // config_file_vcl } ) } @@ -131,143 +197,136 @@ impl CombinedVcl { } } -fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn DirsWrapper,) -> Result, ConfigFileVclError> { - let env_args = Box::new(EnvironmentVcl::new(&app)).args(); - let cmd_args = cmd_args.to_vec(); - let (env_config_file, env_data_dir, env_real_user) = config_file_data_dir_real_user_from_enumerate(&env_args); - let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_data_dir_real_user_from_enumerate(&cmd_args); - let mut combined_vcl: CombinedVcl = CombinedVcl { content: vec![] }; - let combine_vcl = | name: String, vcl: &mut CombinedVcl, cmd_str: &String, env_str: &String | { - if !cmd_str.is_empty() { - vcl.content.push(name); - vcl.content.push(cmd_str.to_string()); - } - else if !env_str.is_empty() { - vcl.content.push(name); - vcl.content.push(env_str.to_string()); - } - else { - vcl.content.push(name); - vcl.content.push("".to_string()); - } - }; - combine_vcl("--data-directory".to_string(), &mut combined_vcl, &cmd_data_dir, &env_data_dir); - combine_vcl("--config-file".to_string(), &mut combined_vcl, &cmd_config_file, &env_config_file); - combine_vcl("--real-user".to_string(), &mut combined_vcl, &cmd_real_user, &env_real_user); - - // In case we define config file in ENV and we can find real-user in that file, therefore we need - // to specify also data-directory in Environment or Command line, to be Node able figure out the - // config file location, when config file is specified without absolute path or current directory eg.: "./" or "../" - - let computed_real_user = &RealUser::new(None, None, None).populate(dirs_wrapper); - let preargs: Box; - let mut config_file_path: PathBuf; - if combined_vcl.len() > 0 { - let (mut config_file, data_directory, _real_user) = config_file_data_dir_real_user_from_enumerate(&combined_vcl.content); - if !config_file.is_empty() { - println!("if"); - if (!config_file.starts_with("/") && !config_file.starts_with("./") && !config_file.starts_with("../")) - && data_directory.is_empty() { - return Err(ConfigFileVclError::InvalidConfig( - PathBuf::from(&config_file), - "Config file defined in Environment with relative path needs data-directory to be defined too".to_string() - )); - } +struct UserDefinedData { + real_user: String, + data_directory: String, + config_file: String, + real_user_type: RealUser, + data_directory_path: PathBuf, + config_file_path: PathBuf +} - if config_file.starts_with("./") { - let pwd = current_dir().expect("expected current directory"); - config_file = config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); - } +// fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn DirsWrapper,) -> Result, ConfigFileVclError> { +// let env_args = Box::new(EnvironmentVcl::new(&app)).args(); +// let cmd_args = cmd_args.to_vec(); +// let (env_config_file, env_data_dir, env_real_user) = config_file_data_dir_real_user_chain_from_enumerate(Box::new(dirs_wrapper), &env_args); +// let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_data_dir_real_user_chain_from_enumerate(Box::new(dirs_wrapper), &cmd_args); +// let mut combined_vcl: CombinedVcl = CombinedVcl { content: vec![] }; +// let combine_vcl = | name: String, vcl: &mut CombinedVcl, cmd_str: &String, env_str: &String | { +// if !cmd_str.is_empty() { +// vcl.content.push(name); +// vcl.content.push(cmd_str.to_string()); +// } +// else if !env_str.is_empty() { +// vcl.content.push(name); +// vcl.content.push(env_str.to_string()); +// } +// else { +// vcl.content.push(name); +// vcl.content.push("".to_string()); +// } +// }; +// combine_vcl("--data-directory".to_string(), &mut combined_vcl, &cmd_data_dir, &env_data_dir); +// combine_vcl("--config-file".to_string(), &mut combined_vcl, &cmd_config_file, &env_config_file); +// combine_vcl("--real-user".to_string(), &mut combined_vcl, &cmd_real_user, &env_real_user); +// +// // In case we define config file in ENV and we can find real-user in that file, therefore we need +// // to specify also data-directory in Environment or Command line, to be Node able figure out the +// // config file location, when config file is specified without absolute path or current directory eg.: "./" or "../" +// +// let mut user_defined = UserDefinedData { +// real_user: Default::default(), +// data_directory: Default::default(), +// config_file: Default::default(), +// real_user_type: RealUser::new(None, None, None).populate(dirs_wrapper), +// data_directory_path: data_directory_from_context(dirs_wrapper, &RealUser::new(None, None, None).populate(dirs_wrapper), DEFAULT_CHAIN), +// config_file_path: Default::default(), +// }; +// +// let preargs: Box; +// +// match combined_vcl.len() > 0 { +// true => { +// (user_defined.config_file, user_defined.data_directory, user_defined.real_user) = config_file_data_dir_real_user_from_enumerate(&combined_vcl.content); +// match user_defined.config_file.is_empty() { +// true => { +// user_defined.config_file = "config.toml".to_string(); +// check_status_of_data_directory(&mut user_defined); +// user_defined.config_file_path = user_defined.data_directory_path.join(user_defined.config_file_path); +// } +// false => { +// match check_status_of_config_file(&user_defined) { +// Ok(_) => {} +// Err(path) => { +// return Err(ConfigFileVclError::InvalidConfig( +// path, +// "Config file defined in Environment with relative path needs data-directory to be defined too".to_string() +// )) +// } +// } +// } +// } +// set_user_defined_config_file_and_path(&mut user_defined); +// let user_specified = !user_defined.config_file.is_empty(); +// let config_file_vcl = match ConfigFileVcl::new(&user_defined.config_file_path, user_specified) { +// Ok(cfv) => Box::new(cfv), +// Err(e) => return Err(e), +// }; +// preargs = merge( +// config_file_vcl, +// Box::new(EnvironmentVcl::new(app)), +// ); +// println!("preargs in first match config-file empty: {:#?}", preargs); +// } +// false => { +// user_defined.config_file_path = PathBuf::from(user_defined.data_directory).join(user_defined.config_file); +// let config_file_vcl = match ConfigFileVcl::new(&user_defined.config_file_path, false) { +// Ok(cfv) => Box::new(cfv), +// Err(e) => return Err(e), +// }; +// preargs = merge( +// config_file_vcl, +// Box::new(EnvironmentVcl::new(app)), +// ); +// } +// } +// +// let args = merge( +// preargs, +// Box::new(CommandLineVcl::new( +// vec!["".to_string(), +// "--config-file".to_string(), +// user_defined.config_file_path.to_string_lossy().to_string()] +// )) +// ); +// Ok(args) +// } + +fn set_user_defined_config_file_and_path(user_defined: &mut UserDefinedData) { + if user_defined.config_file.starts_with("./") { + let pwd = current_dir().expect("expected current directory from system call"); + user_defined.config_file = user_defined.config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); + } + user_defined.config_file_path = PathBuf::from(&user_defined.config_file.to_string()); + if user_defined.config_file_path.is_relative() && !user_defined.data_directory.is_empty() { + user_defined.config_file_path = PathBuf::from(user_defined.data_directory.clone().to_string()).join(&user_defined.config_file_path); + } +} - config_file_path = PathBuf::from(&config_file.to_string()); - let user_specified = !config_file.is_empty(); - if config_file_path.is_relative() && !data_directory.is_empty() { - config_file_path = PathBuf::from(data_directory.to_string()).join(config_file_path); - } - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(e), - }; - preargs = merge( - config_file_vcl, - Box::new(EnvironmentVcl::new(app)), - ); - } else if !data_directory.as_str().is_empty() { - println!("data dir not empty"); - let config_file = PathBuf::from("config.toml"); - config_file_path = PathBuf::from(data_directory).join(config_file); - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, false) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(e), - }; - preargs = merge( - config_file_vcl, - Box::new(EnvironmentVcl::new(app)), - ); - } else { - println!("data dir is empty"); - let config_file = PathBuf::from("config.toml"); - - let cmd_chain = argument_from_enumerate(&cmd_args, "--chain").expect("expected chain"); - let env_chain = argument_from_enumerate(&env_args, "--chain").expect("expected chain"); - let chain = match cmd_chain.is_empty() { - true => { - match env_chain.is_empty() { - true => DEFAULT_CHAIN.rec().literal_identifier, - false => env_chain.as_str() - } - } - false => cmd_chain.as_str() - }; - let data_dir = data_directory_from_context(dirs_wrapper, computed_real_user, Chain::from(chain)); - config_file_path = PathBuf::from(data_dir).join(config_file); - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, false) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(e), - }; - preargs = merge( - config_file_vcl, - Box::new(EnvironmentVcl::new(app)), - ); +fn check_status_of_data_directory(user_defined: &mut UserDefinedData) { + match user_defined.data_directory.is_empty() { + true => {}, + false => { + user_defined.data_directory_path = PathBuf::from(&user_defined.data_directory); } - - } else { - let config_file = PathBuf::from("config.toml"); - // let real_user = &RealUser::new(None, None, None).populate(dirs_wrapper); - let cmd_chain = argument_from_enumerate(&cmd_args, "--chain").expect("expected chain"); - let env_chain = argument_from_enumerate(&env_args, "--chain").expect("expected chain"); - let chain = match cmd_chain.is_empty() { - true => { - match env_chain.is_empty() { - true => DEFAULT_CHAIN.rec().literal_identifier, - false => env_chain.as_str() - } - } - false => cmd_chain.as_str() - }; - let data_dir = data_directory_from_context(dirs_wrapper, computed_real_user, Chain::from(chain)); - config_file_path = PathBuf::from(data_dir).join(config_file); - let config_file_vcl = match ConfigFileVcl::new(&config_file_path, false) { - Ok(cfv) => Box::new(cfv), - Err(e) => return Err(e), - }; - preargs = merge( - config_file_vcl, - Box::new(EnvironmentVcl::new(app)), - ); } - println!("completition"); - //Ok(Box::new(EnvironmentVcl::new(app))) - - let args = merge( - preargs, - Box::new(CommandLineVcl::new( - vec!["".to_string(), - "--config-file".to_string(), - config_file_path.to_string_lossy().to_string()] - )) - ); - Ok(args) +} + +fn check_status_of_config_file(user_defined: &UserDefinedData) -> Result<(), PathBuf> { + return if (!user_defined.config_file.starts_with("/") && !user_defined.config_file.starts_with("./") && !user_defined.config_file.starts_with("../")) + && user_defined.data_directory.is_empty() { + Err(PathBuf::from(&user_defined.config_file)) + } else { Ok(()) } } pub fn initialize_database( @@ -416,7 +475,7 @@ mod tests { .unwrap(); assert_eq!( &format!("{}", user_specific_data.config_file.parent().unwrap().display()), - &user_specific_data.data_directory.to_string_lossy().to_string(), + &user_specific_data.data_directory.unwrap().to_string_lossy().to_string(), ); assert_eq!("booga.toml", user_specific_data.config_file.file_name().unwrap()); assert_eq!(true, user_specific_data.real_user_specified); @@ -445,7 +504,7 @@ mod tests { .unwrap(); assert_eq!( format!("{}", user_specific_data.config_file.parent().unwrap().display()), - user_specific_data.data_directory.to_string_lossy().to_string(), + user_specific_data.data_directory.unwrap().to_string_lossy().to_string(), ); assert_eq!("booga.toml", user_specific_data.config_file.file_name().unwrap()); assert_eq!(true, user_specific_data.real_user_specified); diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index c98eb3801..fe2e6bd48 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -1,15 +1,16 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::bootstrapper::BootstrapperConfig; -use crate::node_configurator::DirsWrapperReal; +use crate::node_configurator::{argument_from_enumerate, DirsWrapperReal}; use crate::node_configurator::{initialize_database, DirsWrapper, NodeConfigurator}; use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; -use masq_lib::multi_config::{ComputedVcl, MultiConfig, VirtualCommandLine}; -use masq_lib::shared_schema::ConfiguratorError; +use masq_lib::multi_config::{ComputedVcl, MultiConfig, VclArg, VirtualCommandLine}; +use masq_lib::shared_schema::{ConfiguratorError, RealUser}; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; use std::net::{IpAddr, Ipv4Addr}; +use std::ops::Deref; use clap::value_t; use log::LevelFilter; @@ -32,6 +33,7 @@ use crate::tls_discriminator_factory::TlsDiscriminatorFactory; use masq_lib::constants::{DEFAULT_UI_PORT, HTTP_PORT, TLS_PORT}; use masq_lib::multi_config::{CommandLineVcl, ConfigFileVcl, EnvironmentVcl}; use std::str::FromStr; +use itertools::Itertools; pub struct NodeConfiguratorStandardPrivileged { dirs_wrapper: Box, @@ -140,22 +142,45 @@ pub fn server_initializer_collected_params<'a>( ) -> Result, ConfiguratorError> { let app = app_node(); let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, args)?; - println!("user_specific_data.pre_orientation_args: {:#?}", user_specific_data.pre_orientation_args); + let config_file_vcl = match ConfigFileVcl::new(&user_specific_data.config_file, user_specific_data.config_file_specified) { + Ok(cfv) => cfv, + Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())) + }; + let config_file_specified = &user_specific_data.config_file_specified; + let config_file_path = &user_specific_data.config_file; + let to_iter_config = &config_file_vcl.args(); + let config_real_user_args = to_iter_config + .iter().enumerate() + .filter(|(index, vcl_arg)| { + vcl_arg.deref() == &"--real-user".to_string() + }).collect_vec(); + let (real_user, real_user_specified) = match config_real_user_args.is_empty() { + false => { + let real_user_str = to_iter_config[config_real_user_args[0].0 + 1].clone(); + (real_user_str, true) + }, + true => (user_specific_data.real_user.unwrap().to_string(), false) + }; + let mut full_multi_config_vec: Vec> = vec![ + Box::new(config_file_vcl), Box::new(EnvironmentVcl::new(&app)), - user_specific_data.pre_orientation_args + Box::new(CommandLineVcl::new(args.to_vec())), ]; - + //TODO write test for MultiConfig "try_new" merge line 76 let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool | { match specified { true => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec!["".to_string(), key.to_string(), value.to_string(),]))), false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec!["".to_string(), key.to_string(), value.to_string(),]))) }; }; - fill_specified_or_unspecified_box("--config-file", user_specific_data.config_file.to_string_lossy().as_ref(), user_specific_data.config_file_specified); - fill_specified_or_unspecified_box("--data-directory", user_specific_data.data_directory.to_string_lossy().as_ref(), user_specific_data.data_directory_specified); - fill_specified_or_unspecified_box("--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_specified); - println!("full_multi_config_vec: {:#?}", full_multi_config_vec); + fill_specified_or_unspecified_box("--config-file", &user_specific_data.config_file.as_path().to_string_lossy().as_ref(), user_specific_data.config_file_specified); + fill_specified_or_unspecified_box("--data-directory", &user_specific_data.data_directory.unwrap().to_string_lossy().as_ref(), user_specific_data.data_directory_specified); + fill_specified_or_unspecified_box("--real-user", real_user.to_string().as_str(), real_user_specified); + //TODO check if following two lines can't overwrite the computed values wrongly + full_multi_config_vec.push( Box::new(EnvironmentVcl::new(&app))); + full_multi_config_vec.push( Box::new(CommandLineVcl::new(args.to_vec()))); + // println!("full_multi_config_vec: {:#?}", full_multi_config_vec); let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; Ok(full_multi_config) @@ -472,10 +497,7 @@ mod tests { &directory_wrapper, &slice_of_strs_to_vec_of_strings(&["", "--data-directory", home_dir.to_str().unwrap()]), ) - // generated/test/node_configurator_standard/server_initializer_collected_params_can_read_parameters_from_config_file/home - // /Users/vojtechparkan/Projekty/Node/node/generated/test/node_configurator_standard/server_initializer_collected_params_can_read_parameters_from_config_file/home .unwrap(); - println!("multiconfig: {:#?}", multi_config); assert_eq!( value_m!(multi_config, "dns-servers", String).unwrap(), "111.111.111.111,222.222.222.222".to_string() @@ -800,7 +822,7 @@ mod tests { false => { assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), - "/home/wooga/data_dir/MASQ/polygon-mainnet".to_string() + "booga/data_dir/MASQ/polygon-mainnet".to_string() ) } } @@ -880,15 +902,14 @@ mod tests { fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_directory() { running_test(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + println!("home_dir {:#?}", &home_dir); let data_dir = &home_dir.join("data_dir"); let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); fill_up_config_file(config_file_relative); let current_directory = current_dir().unwrap(); vec![ - ("MASQ_CONFIG_FILE", "./generated/config.toml"), - ("MASQ_DATA_DIRECTORY", ¤t_directory.display().to_string().as_str()), - #[cfg(not(target_os = "windows"))] - ("MASQ_REAL_USER", "9999:9999:booga"), + ("MASQ_CONFIG_FILE", "generated/config.toml"), + //("MASQ_DATA_DIRECTORY", ¤t_directory.display().to_string().as_str()), ].into_iter() .for_each (|(name, value)| std::env::set_var (name, value)); let args = ArgsBuilder::new(); @@ -898,182 +919,177 @@ mod tests { .data_dir_result(Some(data_dir.to_path_buf())); let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - let env_multiconfig = result.unwrap(); + let multiconfig = result.unwrap(); - match env_multiconfig.is_user_specified("--data-directory") { + match multiconfig.is_user_specified("--data-directory") { true => { assert_eq!( - &value_m!(env_multiconfig, "data-directory", String).unwrap(), + &value_m!(multiconfig, "data-directory", String).unwrap(), ¤t_directory.to_string_lossy().to_string() ) }, false => () } - - match env_multiconfig.is_user_specified("--real-user") { - true => { - assert_eq!( - &value_m!(env_multiconfig, "real-user", String).unwrap(), - "1002:1002:/home/wooga" - ) - }, - false => () - } - - match (env_multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { - (true, true) => { - let pwd = PathBuf::from( value_m!(env_multiconfig, "data-directory", String).unwrap()); - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() - ) - }, - (_, _) => () - } - } - - #[test] - fn server_initializer_collected_params_combine_vlcs_properly() { - running_test(); - let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); - let data_dir = &home_dir.join("data_dir"); - let config_file = File::create(&home_dir.join("config.toml")).unwrap(); - let current_directory = current_dir().unwrap(); - let data_dir_sys = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); - { - fill_up_config_file(config_file); - match data_dir_sys { - Ok(..) => { - let config_file_vcl = File::create(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); - fill_up_config_file(config_file_vcl); - } - Err(e) => panic!("unable to create config file: {}", e) - } - } - - let env_vec_array = vec![ - ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml"), - //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), - #[cfg(not(target_os = "windows"))] - ("MASQ_REAL_USER", "9999:9999:booga"), - ]; - env_vec_array.clone().into_iter() - .for_each (|(name, value)| std::env::set_var (name, value)); - let args = ArgsBuilder::new(); - let args_vec: Vec = args.into(); - let dir_wrapper = DirsWrapperMock::new() - .home_dir_result(Some(home_dir.clone())) - .data_dir_result(Some(data_dir.to_path_buf())); - let mut env_data_directory = false; - for (item, _vaue) in env_vec_array.to_vec().as_slice() { - if item == &"MASQ_DATA_DIRECTORY" { env_data_directory = true; } - } - - let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - let env_multiconfig = result.unwrap(); - - let args = ArgsBuilder::new() - .param("--data-directory", current_directory.join(Path::new("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home")).to_string_lossy().to_string().as_str()) - .param("--real-user", "1001:1001:cooga"); - let args_vec: Vec = args.into(); - let mut cmd_data_directory = false; - for item in args_vec.clone().as_slice() { - if item == &"--data-directory".to_string() { cmd_data_directory = true; } - } - let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - let result2 = params.as_ref().expect("REASON"); - let vcl_multiconfig = result2; - + println!("real-user {}", value_m!(multiconfig, "real-user", String).unwrap()); assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() - ); - match env_multiconfig.is_user_specified("--data-directory") { - true => { - assert_eq!( - value_m!(env_multiconfig, "data-directory", String).unwrap(), - "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() - ) - } - false => { - println!("data-directory is not user specified in Environment"); - () - } - } - - #[cfg(not(target_os = "windows"))] - match env_multiconfig.is_user_specified("--real-user") { - true => { - assert_eq!( - value_m!(env_multiconfig, "real-user", String).unwrap(), - "1002:1002:/home/wooga".to_string() - ) - } - false => { - println!("real-user is not user specified in Environment"); - () - } - } - - #[cfg(not(target_os = "windows"))] - match vcl_multiconfig.is_user_specified("--real-user") { - true => { - match env_multiconfig.is_user_specified("--real-user") { - true => { - println!("real-user is inherited from Environment {}", value_m!(vcl_multiconfig, "real-user", String).unwrap()); - assert_eq!( - value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "1001:1001:cooga".to_string() - ) - } - false => { - assert_eq!( - value_m!(vcl_multiconfig, "real-user", String).unwrap(), - "1002:1002:/home/wooga".to_string() - ) - } - } - } - false => { - println!("real-user is not user specified in Command-line"); - () - } - } - println!("env_data_directory {:#?}", env_data_directory); - match vcl_multiconfig.is_user_specified("--data-directory") { - true => { - match env_data_directory && !cmd_data_directory { - true => { - println!("data-directory is inherited from Environment"); - assert_eq!( - value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() - ) - } - false => { - match cmd_data_directory { - true => { - assert_eq!( - value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home").to_string_lossy().to_string() - ) - } - false => { - println!("data-directory is not user specified in ENV") - } - } - - } - }; + &value_m!(multiconfig, "real-user", String).unwrap(), + "1002:1002:/home/wooga" + ) - } - false => { - println!("data-directory is not user specified in Command-line"); - () - } - } + // match (multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { + // (true, true) => { + // let pwd = PathBuf::from( value_m!(multiconfig, "data-directory", String).unwrap()); + // assert_eq!( + // value_m!(env_multiconfig, "config-file", String).unwrap(), + // pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() + // ) + // }, + // (_, _) => () + // } } + // #[test] + // fn server_initializer_collected_params_combine_vlcs_properly() { + // running_test(); + // let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); + // let data_dir = &home_dir.join("data_dir"); + // let config_file = File::create(&home_dir.join("config.toml")).unwrap(); + // let current_directory = current_dir().unwrap(); + // let data_dir_sys = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); + // { + // fill_up_config_file(config_file); + // match data_dir_sys { + // Ok(..) => { + // let config_file_vcl = File::create(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); + // fill_up_config_file(config_file_vcl); + // } + // Err(e) => panic!("unable to create config file: {}", e) + // } + // } + // + // let env_vec_array = vec![ + // ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml"), + // //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), + // #[cfg(not(target_os = "windows"))] + // ("MASQ_REAL_USER", "9999:9999:booga"), + // ]; + // env_vec_array.clone().into_iter() + // .for_each (|(name, value)| std::env::set_var (name, value)); + // let args = ArgsBuilder::new(); + // let args_vec: Vec = args.into(); + // let dir_wrapper = DirsWrapperMock::new() + // .home_dir_result(Some(home_dir.clone())) + // .data_dir_result(Some(data_dir.to_path_buf())); + // let mut env_data_directory = false; + // for (item, _vaue) in env_vec_array.to_vec().as_slice() { + // if item == &"MASQ_DATA_DIRECTORY" { env_data_directory = true; } + // } + // + // let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + // let env_multiconfig = result.unwrap(); + // + // let args = ArgsBuilder::new() + // .param("--data-directory", current_directory.join(Path::new("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home")).to_string_lossy().to_string().as_str()) + // .param("--real-user", "1001:1001:cooga"); + // let args_vec: Vec = args.into(); + // let mut cmd_data_directory = false; + // for item in args_vec.clone().as_slice() { + // if item == &"--data-directory".to_string() { cmd_data_directory = true; } + // } + // let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + // let result2 = params.as_ref().expect("REASON"); + // let vcl_multiconfig = result2; + // + // assert_eq!( + // value_m!(env_multiconfig, "config-file", String).unwrap(), + // current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() + // ); + // match env_multiconfig.is_user_specified("--data-directory") { + // true => { + // assert_eq!( + // value_m!(env_multiconfig, "data-directory", String).unwrap(), + // "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() + // ) + // } + // false => { + // println!("data-directory is not user specified in Environment"); + // () + // } + // } + // + // #[cfg(not(target_os = "windows"))] + // match env_multiconfig.is_user_specified("--real-user") { + // true => { + // assert_eq!( + // value_m!(env_multiconfig, "real-user", String).unwrap(), + // "1002:1002:/home/wooga".to_string() + // ) + // } + // false => { + // println!("real-user is not user specified in Environment"); + // () + // } + // } + // + // #[cfg(not(target_os = "windows"))] + // match vcl_multiconfig.is_user_specified("--real-user") { + // true => { + // match env_multiconfig.is_user_specified("--real-user") { + // true => { + // println!("real-user is inherited from Environment {}", value_m!(vcl_multiconfig, "real-user", String).unwrap()); + // assert_eq!( + // value_m!(vcl_multiconfig, "real-user", String).unwrap(), + // "1001:1001:cooga".to_string() + // ) + // } + // false => { + // assert_eq!( + // value_m!(vcl_multiconfig, "real-user", String).unwrap(), + // "1002:1002:/home/wooga".to_string() + // ) + // } + // } + // } + // false => { + // println!("real-user is not user specified in Command-line"); + // () + // } + // } + // println!("env_data_directory {:#?}", env_data_directory); + // match vcl_multiconfig.is_user_specified("--data-directory") { + // true => { + // match env_data_directory && !cmd_data_directory { + // true => { + // println!("data-directory is inherited from Environment"); + // assert_eq!( + // value_m!(vcl_multiconfig, "data-directory", String).unwrap(), + // "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() + // ) + // } + // false => { + // match cmd_data_directory { + // true => { + // assert_eq!( + // value_m!(vcl_multiconfig, "data-directory", String).unwrap(), + // current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home").to_string_lossy().to_string() + // ) + // } + // false => { + // println!("data-directory is not user specified in ENV") + // } + // } + // + // } + // }; + // + // } + // false => { + // println!("data-directory is not user specified in Command-line"); + // () + // } + // } + // } + #[test] fn server_initializer_collected_params_senses_when_user_specifies_config_file() { running_test(); From 4dd0932edc3ee27e760a6d527703d73a86a190c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Mon, 23 Oct 2023 18:31:37 +0200 Subject: [PATCH 12/24] finalize preparing guts for multiconfig in server_initializer_collected_params, added handling for tilde in data_directory and config_file paths --- masq_lib/src/multi_config.rs | 94 +-- node/src/daemon/setup_reporter.rs | 7 +- node/src/node_configurator/mod.rs | 506 +++++++-------- .../node_configurator_standard.rs | 574 +++++++++--------- node/src/server_initializer.rs | 8 +- node/tests/utils.rs | 2 + 6 files changed, 563 insertions(+), 628 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index 8f1c51e49..c3e3e49c3 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -50,7 +50,7 @@ macro_rules! values_m { #[derive(Debug)] pub struct MultiConfig<'a> { arg_matches: ArgMatches<'a>, - computed_value_names: HashSet + computed_value_names: HashSet, } impl<'a> MultiConfig<'a> { @@ -69,31 +69,30 @@ impl<'a> MultiConfig<'a> { vcl.vcl_args().iter().for_each(|vcl_arg| { match vcl.is_computed() { true => computed_value_names.insert(vcl_arg.name().to_string()), - false => computed_value_names.remove(&vcl_arg.name().to_string()) + false => computed_value_names.remove(&vcl_arg.name().to_string()), }; }) }); - let merged = vcls.into_iter().fold(initial, |so_far, vcl | { - merge(so_far, vcl) - }); + let merged = vcls + .into_iter() + .fold(initial, |so_far, vcl| merge(so_far, vcl)); let arg_matches = match schema .clone() .get_matches_from_safe(merged.args().into_iter()) { - Ok(matches) => { - matches - }, - Err(e) => { - match e.kind { - clap::ErrorKind::HelpDisplayed | clap::ErrorKind::VersionDisplayed => { - unreachable!("The program's entry check failed to catch this.") - } - _ => return Err(Self::make_configurator_error(e)), + Ok(matches) => matches, + Err(e) => match e.kind { + clap::ErrorKind::HelpDisplayed | clap::ErrorKind::VersionDisplayed => { + unreachable!("The program's entry check failed to catch this.") } + _ => return Err(Self::make_configurator_error(e)), }, }; - Ok(MultiConfig { arg_matches, computed_value_names }) + Ok(MultiConfig { + arg_matches, + computed_value_names, + }) } fn check_for_invalid_value_err( @@ -155,9 +154,9 @@ impl<'a> MultiConfig<'a> { } pub fn is_user_specified(&self, value_name: &str) -> bool { - match self.computed_value_names.contains(value_name) { + match self.computed_value_names.contains(value_name) { true => false, - false => true + false => true, } } @@ -251,7 +250,9 @@ impl NameOnlyVclArg { pub trait VirtualCommandLine { fn vcl_args(&self) -> Vec<&dyn VclArg>; fn args(&self) -> Vec; - fn is_computed(&self) -> bool { false } + fn is_computed(&self) -> bool { + false + } } impl Debug for dyn VirtualCommandLine { @@ -291,7 +292,7 @@ pub fn merge( }) } -pub struct ComputedVcl { +pub struct ComputedVcl { vcl_args: Vec>, } @@ -407,7 +408,7 @@ impl EnvironmentVcl { .collect(); let mut vcl_args: Vec> = vec![]; for (upper_name, value) in std::env::vars() { - if (upper_name.len() < 5) || (&upper_name[0..5] != "MASQ_") { + if (upper_name.len() < 5) || (&upper_name[0..5] != "MASQ_") || (value == *"") { continue; } let lower_name = str::replace(&upper_name[5..].to_lowercase(), "_", "-"); @@ -567,11 +568,11 @@ fn append(ts: Vec, t: T) -> Vec { impl<'a> MultiConfig<'a> { pub fn new_test_only( arg_matches: ArgMatches<'a>, - computed_value_names: HashSet + computed_value_names: HashSet, ) -> Self { Self { arg_matches, - computed_value_names + computed_value_names, } } } @@ -1039,31 +1040,29 @@ pub mod tests { "--takes_no_value", "--other_takes_no_value", ] - .into_iter() - .map(|s| s.to_string()) - .collect(); + .into_iter() + .map(|s| s.to_string()) + .collect(); let subject = CommandLineVcl::new(command_line.clone()); - let existing_value = match subject.vcl_args + let existing_value = match subject + .vcl_args .iter() - .find(|vcl_arg_box| vcl_arg_box.deref().name() == "--first-value" ) { + .find(|vcl_arg_box| vcl_arg_box.deref().name() == "--first-value") + { Some(vcl_arg_box) => vcl_arg_box.deref().value_opt(), - None => None + None => None, }; - let non_existing_value = match subject.vcl_args + let non_existing_value = match subject + .vcl_args .iter() - .find(|vcl_arg_box| vcl_arg_box.deref().name() == "--takes_no_value" ) { + .find(|vcl_arg_box| vcl_arg_box.deref().name() == "--takes_no_value") + { Some(vcl_arg_box) => vcl_arg_box.deref().value_opt(), - None => None + None => None, }; - assert_eq!( - existing_value.unwrap(), - "/nonexistent/directory" - ); - assert_eq!( - non_existing_value, - None - ); + assert_eq!(existing_value.unwrap(), "/nonexistent/directory"); + assert_eq!(non_existing_value, None); } #[test] @@ -1080,12 +1079,19 @@ pub mod tests { #[test] fn environment_vcl_works() { let _guard = EnvironmentGuard::new(); - let schema = App::new("test").arg( - Arg::with_name("numeric-arg") - .long("numeric-arg") - .takes_value(true), - ); + let schema = App::new("test") + .arg( + Arg::with_name("numeric-arg") + .long("numeric-arg") + .takes_value(true), + ) + .arg( + Arg::with_name("empty-arg") + .long("empty-arg") + .takes_value(true), + ); std::env::set_var("MASQ_NUMERIC_ARG", "47"); + std::env::set_var("MASQ_EMPTY_ARG", ""); let subject = EnvironmentVcl::new(&schema); diff --git a/node/src/daemon/setup_reporter.rs b/node/src/daemon/setup_reporter.rs index fd060b145..20980f02c 100644 --- a/node/src/daemon/setup_reporter.rs +++ b/node/src/daemon/setup_reporter.rs @@ -18,7 +18,7 @@ use crate::node_configurator::unprivileged_parse_args_configuration::{ UnprivilegedParseArgsConfigurationDaoReal, }; use crate::node_configurator::{ - data_directory_from_context, determine_user_specific_data, DirsWrapperReal, DirsWrapper + data_directory_from_context, determine_user_specific_data, DirsWrapper, DirsWrapperReal, }; use crate::sub_lib::accountant::PaymentThresholds as PaymentThresholdsFromAccountant; use crate::sub_lib::accountant::DEFAULT_SCAN_INTERVALS; @@ -497,7 +497,10 @@ impl SetupReporterReal { }; let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, &command_line)?; - let config_file_vcl = match ConfigFileVcl::new(&user_specific_data.config_file, user_specific_data.config_file_specified) { + let config_file_vcl = match ConfigFileVcl::new( + &user_specific_data.config_file, + user_specific_data.config_file_spec, + ) { Ok(cfv) => cfv, Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 801431e7b..1e769aaed 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -5,9 +5,7 @@ pub mod node_configurator_initialization; pub mod node_configurator_standard; pub mod unprivileged_parse_args_configuration; -use std::env::{current_dir}; use crate::bootstrapper::RealUser; -use core::option::Option; use crate::database::db_initializer::DbInitializationConfig; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::persistent_configuration::{ @@ -15,318 +13,223 @@ use crate::db_config::persistent_configuration::{ }; use crate::sub_lib::utils::db_connection_launch_panic; use clap::{value_t, App}; +use core::option::Option; use dirs::{data_local_dir, home_dir}; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::DEFAULT_CHAIN; -use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg, VirtualCommandLine, ConfigFileVcl, ConfigFileVclError}; -use masq_lib::shared_schema::{config_file_arg, data_directory_arg, ConfiguratorError, DATA_DIRECTORY_HELP, chain_arg, real_user_arg}; +use masq_lib::multi_config::{merge, CommandLineVcl, EnvironmentVcl, MultiConfig, VclArg}; +use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::{add_masq_and_chain_directories, localhost}; +use std::env::current_dir; use std::net::{SocketAddr, TcpListener}; use std::ops::Deref; use std::path::{Path, PathBuf}; -use libc::option; - pub trait NodeConfigurator { fn configure(&self, multi_config: &MultiConfig) -> Result; } -fn config_file_data_dir_real_user_chain_from_enumerate(dirs_wrapper: &dyn DirsWrapper, configs: Vec>) - -> (Option, Option, Option, Option) { - let configs = configs.as_slice(); - let chain = match argument_from_enumerate(configs, "--chain") { - Some(chain) => Chain::from( chain), - None => DEFAULT_CHAIN - }; - let real_user = match argument_from_enumerate(configs, "--real-user") { +#[derive(Debug)] +pub struct UserSpecifiedData { + pub(crate) chain: Chain, + pub(crate) chain_spec: bool, + pub(crate) real_user: RealUser, + pub(crate) real_user_spec: bool, + pub(crate) data_directory: PathBuf, + pub(crate) data_directory_spec: bool, + pub(crate) config_file: PathBuf, + pub(crate) config_file_spec: bool, +} + +fn get_chain_from_vcl(configs: &[Box]) -> (Chain, bool) { + match argument_from_enumerate(configs, "--chain") { + Some(chain) => (Chain::from(chain), true), + None => (DEFAULT_CHAIN, false), + } +} + +fn get_real_user_from_vcl( + configs: &[Box], + dirs_wrapper: &dyn DirsWrapper, +) -> (RealUser, bool) { + match argument_from_enumerate(configs, "--real-user") { Some(user) => { - let real_user_split: Vec<&str> = user.split(":").collect(); - RealUser::new( - Some(real_user_split[0].parse::().expect("expected user id")), - Some(real_user_split[1].parse::().expect("expected user group")), - Some(PathBuf::from(real_user_split[2])) + let real_user_split: Vec<&str> = user.split(':').collect(); + ( + RealUser::new( + Some(real_user_split[0].parse::().expect("expected user id")), + Some( + real_user_split[1] + .parse::() + .expect("expected user group"), + ), + Some(PathBuf::from(real_user_split[2])), + ), + true, ) + } + None => ( + RealUser::new(None, None, None).populate(dirs_wrapper), + false, + ), + } +} +fn get_data_directory_from_vcl( + configs: &[Box], + dirs_wrapper: &dyn DirsWrapper, + real_user: &RealUser, + chain: &Chain, +) -> (PathBuf, bool) { + match argument_from_enumerate(configs, "--data-directory") { + Some(data_dir) => match PathBuf::from(data_dir).starts_with("~/") { + true => { + let home_dir_from_wrapper = dirs_wrapper + .home_dir() + .expect("expexted users home dir") + .to_str() + .expect("expect home dir") + .to_string(); + let replaced_tilde_dir = + data_dir + .to_string() + .replacen('~', home_dir_from_wrapper.as_str(), 1); + (PathBuf::from(replaced_tilde_dir), true) + } + false => (PathBuf::from(&data_dir), true), }, - None => RealUser::new(None, None, None).populate(dirs_wrapper) - }; - let data_directory = match argument_from_enumerate(configs, "--data-directory") { - Some(data_dir) => PathBuf::from(&data_dir), - None => data_directory_from_context(dirs_wrapper, &real_user, chain) - }; - let config_match = match argument_from_enumerate(configs, "--config-file") { + None => ( + data_directory_from_context(dirs_wrapper, real_user, *chain), + false, + ), + } +} + +fn get_config_file_from_vcl( + configs: &[Box], + data_directory: &PathBuf, + data_directory_def: bool, + dirs_wrapper: &dyn DirsWrapper, +) -> (PathBuf, bool) { + match argument_from_enumerate(configs, "--config-file") { Some(config_str) => { - match PathBuf::from(config_str).is_relative() { - true => current_dir().expect("expected curerrnt dir").join(PathBuf::from(config_str)), - false => PathBuf::from(config_str) + let path = match PathBuf::from(config_str).is_relative() { + true => { + match PathBuf::from(config_str).file_name().expect("expected file name") == config_str { + true => PathBuf::from(data_directory).join(PathBuf::from(config_str)), + false => match PathBuf::from(config_str).starts_with("./") || PathBuf::from(config_str).starts_with("../") { + true => current_dir().expect("expected curerrnt dir").join(PathBuf::from(config_str)), + false => match PathBuf::from(config_str).starts_with("~") { + true => { + let home_dir_from_wrapper = dirs_wrapper + .home_dir() + .expect("expexted users home dir") + .to_str() + .expect("expect home dir") + .to_string(); + let replaced_tilde_dir = + config_str + .to_string() + .replacen('~', home_dir_from_wrapper.as_str(), 1); + PathBuf::from(replaced_tilde_dir) + } + false => match data_directory_def { + true => PathBuf::from(data_directory).join(PathBuf::from(config_str)), + false => panic!("You need to define data-directory to be able define config file with naked directory 'dirname/config.toml'.") + } + } + } + } + } + false => PathBuf::from(config_str), + }; + (path, true) + } + None => { + let path = PathBuf::from(data_directory).join(PathBuf::from("config.toml")); + match path.is_file() { + true => (path, true), + false => (path, false), } } - None => PathBuf::from(&data_directory).join(PathBuf::from("config.toml")) + } +} + +fn config_file_data_dir_real_user_chain_from_enumerate( + dirs_wrapper: &dyn DirsWrapper, + configs: Vec>, +) -> UserSpecifiedData { + //TODO break down this function to collection of small one purpose functions + let mut user_specified_data = UserSpecifiedData { + chain: Default::default(), + chain_spec: false, + real_user: Default::default(), + real_user_spec: false, + data_directory: Default::default(), + data_directory_spec: false, + config_file: Default::default(), + config_file_spec: false, }; - (Some(config_match), Some(data_directory), Some(real_user), Some(chain)) + let configs = configs.as_slice(); + (user_specified_data.chain, user_specified_data.chain_spec) = get_chain_from_vcl(configs); + ( + user_specified_data.real_user, + user_specified_data.real_user_spec, + ) = get_real_user_from_vcl(configs, dirs_wrapper); + ( + user_specified_data.data_directory, + user_specified_data.data_directory_spec, + ) = get_data_directory_from_vcl( + configs, + dirs_wrapper, + &user_specified_data.real_user, + &user_specified_data.chain, + ); + ( + user_specified_data.config_file, + user_specified_data.config_file_spec, + ) = get_config_file_from_vcl( + configs, + &user_specified_data.data_directory, + user_specified_data.data_directory_spec, + dirs_wrapper, + ); + user_specified_data } fn argument_from_enumerate<'a>(configs: &'a [Box], needle: &'a str) -> Option<&'a str> { match configs .iter() - .find(|vcl_arg_box| vcl_arg_box.deref().name() == needle ) { + .find(|vcl_arg_box| vcl_arg_box.deref().name() == needle) + { Some(vcl_arg_box) => vcl_arg_box.deref().value_opt(), - None => None + None => None, } } -#[derive(Debug)] -pub struct UserSpecificData { - pub(crate) config_file: PathBuf, - pub(crate) config_file_specified: bool, - pub(crate) data_directory: Option, - pub(crate) data_directory_specified: bool, - pub(crate) real_user: Option, - pub(crate) real_user_specified: bool, - // pub config_file_vcl: Box, -} - -pub fn determine_user_specific_data ( +pub fn determine_user_specific_data( dirs_wrapper: &dyn DirsWrapper, app: &App, args: &[String], -) -> Result { - - // let pre_orientation_args = match create_preorientation_args(args, &app, dirs_wrapper); - let mut data_directory_specified: bool = false; - let mut real_user_specified: bool = false; - let mut config_file_specified: bool = false; - let config_file_path: PathBuf; - let orientation_schema = App::new("MASQNode") - .arg(chain_arg()) - .arg(real_user_arg()) - .arg(data_directory_arg(DATA_DIRECTORY_HELP)) - .arg(config_file_arg()); +) -> Result { let orientation_args: Vec> = merge( - Box::new(EnvironmentVcl::new(&orientation_schema)), + Box::new(EnvironmentVcl::new(app)), Box::new(CommandLineVcl::new(args.to_vec())), ) - .vcl_args() - .into_iter() - .filter(|vcl_arg| { - (vcl_arg.name() == "--chain") - || (vcl_arg.name() == "--real-user") - || (vcl_arg.name() == "--data-directory") - || (vcl_arg.name() == "--config-file") - }) - .map(|vcl_arg| vcl_arg.dup()) - .collect(); - let (config_file,data_directory,real_user, chain) = - config_file_data_dir_real_user_chain_from_enumerate( dirs_wrapper, orientation_args); - match config_file { - Some(config_file_pth) => { - config_file_specified = true; - config_file_path = config_file_pth; - // match ConfigFileVcl::new(&config_file_path, config_file_specified) { - // Ok(cfv) => Box::new(cfv), - // Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), - // } - } - None => { - config_file_specified = false; - config_file_path = data_directory.clone().expect("expect data directory").join("config.toml"); - // match ConfigFileVcl::new(&config_file_path, config_file_specified) { - // Ok(cfv) => Box::new(cfv), - // Err(e) => e, - // } - } - }; - //println!("determine_user_specific_data orientation_args {:#?}", &orientation_args); - {// let config_file_vcl = match ConfigFileVcl::new(&config_file_path, config_file_specified) { - // Ok(cfv) => Box::new(cfv), - // Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), - // }; - - // let config_user_specified = !config_file.is_empty(); - // let data_directory_specified = !data_dir.is_empty(); - // let real_user_specified = !real_user.is_empty(); - // if real_user.is_empty() { - // real_user = RealUser::new(None, None, None).populate(dirs_wrapper).to_string(); - // } - // let chain = match argument_from_enumerate(&orientation_vcl.args(), "--chain") { - // Some(chain) => { - // Chain::from(chain.as_str()) - // }, - // None => DEFAULT_CHAIN - // }; - // let real_user_split: Vec<&str> = real_user.split(":").collect(); - // let real_user_obj = RealUser::new( - // Some(real_user_split[0].parse::().expect("expected user id")), - // Some(real_user_split[1].parse::().expect("expected user group")), - // Some(PathBuf::from(real_user_split[2]))); - // let data_directory = match data_dir.is_empty() { - // false => PathBuf::from(data_dir), - // true => data_directory_from_context(dirs_wrapper, &real_user_obj, chain), - // }; - // let final_orientation_args; - // if !config_user_specified { - // config_file = data_directory.join("config.toml").to_string_lossy().to_string(); - // final_orientation_args = merge( - // Box::new(orientation_vcl), - // Box::new(CommandLineVcl::new(vec!["".to_string(), "--config-file".to_string(), config_file.clone()])) - // ); - // } else { - // final_orientation_args = Box::new(orientation_vcl); - // } - // let final_orientation_args = Box::new(orientation_vcl); - } - Ok( UserSpecificData { - config_file: config_file_path, - config_file_specified, - data_directory, - data_directory_specified, - real_user, - real_user_specified, - // config_file_vcl - } - ) -} - -struct CombinedVcl { - content: Vec -} - -impl CombinedVcl { - fn len(&self) -> u32 { - *&self.content.as_slice().iter().count() as u32 - } -} - -struct UserDefinedData { - real_user: String, - data_directory: String, - config_file: String, - real_user_type: RealUser, - data_directory_path: PathBuf, - config_file_path: PathBuf -} - -// fn create_preorientation_args(cmd_args: &[String], app: &App, dirs_wrapper: &dyn DirsWrapper,) -> Result, ConfigFileVclError> { -// let env_args = Box::new(EnvironmentVcl::new(&app)).args(); -// let cmd_args = cmd_args.to_vec(); -// let (env_config_file, env_data_dir, env_real_user) = config_file_data_dir_real_user_chain_from_enumerate(Box::new(dirs_wrapper), &env_args); -// let (cmd_config_file, cmd_data_dir, cmd_real_user) = config_file_data_dir_real_user_chain_from_enumerate(Box::new(dirs_wrapper), &cmd_args); -// let mut combined_vcl: CombinedVcl = CombinedVcl { content: vec![] }; -// let combine_vcl = | name: String, vcl: &mut CombinedVcl, cmd_str: &String, env_str: &String | { -// if !cmd_str.is_empty() { -// vcl.content.push(name); -// vcl.content.push(cmd_str.to_string()); -// } -// else if !env_str.is_empty() { -// vcl.content.push(name); -// vcl.content.push(env_str.to_string()); -// } -// else { -// vcl.content.push(name); -// vcl.content.push("".to_string()); -// } -// }; -// combine_vcl("--data-directory".to_string(), &mut combined_vcl, &cmd_data_dir, &env_data_dir); -// combine_vcl("--config-file".to_string(), &mut combined_vcl, &cmd_config_file, &env_config_file); -// combine_vcl("--real-user".to_string(), &mut combined_vcl, &cmd_real_user, &env_real_user); -// -// // In case we define config file in ENV and we can find real-user in that file, therefore we need -// // to specify also data-directory in Environment or Command line, to be Node able figure out the -// // config file location, when config file is specified without absolute path or current directory eg.: "./" or "../" -// -// let mut user_defined = UserDefinedData { -// real_user: Default::default(), -// data_directory: Default::default(), -// config_file: Default::default(), -// real_user_type: RealUser::new(None, None, None).populate(dirs_wrapper), -// data_directory_path: data_directory_from_context(dirs_wrapper, &RealUser::new(None, None, None).populate(dirs_wrapper), DEFAULT_CHAIN), -// config_file_path: Default::default(), -// }; -// -// let preargs: Box; -// -// match combined_vcl.len() > 0 { -// true => { -// (user_defined.config_file, user_defined.data_directory, user_defined.real_user) = config_file_data_dir_real_user_from_enumerate(&combined_vcl.content); -// match user_defined.config_file.is_empty() { -// true => { -// user_defined.config_file = "config.toml".to_string(); -// check_status_of_data_directory(&mut user_defined); -// user_defined.config_file_path = user_defined.data_directory_path.join(user_defined.config_file_path); -// } -// false => { -// match check_status_of_config_file(&user_defined) { -// Ok(_) => {} -// Err(path) => { -// return Err(ConfigFileVclError::InvalidConfig( -// path, -// "Config file defined in Environment with relative path needs data-directory to be defined too".to_string() -// )) -// } -// } -// } -// } -// set_user_defined_config_file_and_path(&mut user_defined); -// let user_specified = !user_defined.config_file.is_empty(); -// let config_file_vcl = match ConfigFileVcl::new(&user_defined.config_file_path, user_specified) { -// Ok(cfv) => Box::new(cfv), -// Err(e) => return Err(e), -// }; -// preargs = merge( -// config_file_vcl, -// Box::new(EnvironmentVcl::new(app)), -// ); -// println!("preargs in first match config-file empty: {:#?}", preargs); -// } -// false => { -// user_defined.config_file_path = PathBuf::from(user_defined.data_directory).join(user_defined.config_file); -// let config_file_vcl = match ConfigFileVcl::new(&user_defined.config_file_path, false) { -// Ok(cfv) => Box::new(cfv), -// Err(e) => return Err(e), -// }; -// preargs = merge( -// config_file_vcl, -// Box::new(EnvironmentVcl::new(app)), -// ); -// } -// } -// -// let args = merge( -// preargs, -// Box::new(CommandLineVcl::new( -// vec!["".to_string(), -// "--config-file".to_string(), -// user_defined.config_file_path.to_string_lossy().to_string()] -// )) -// ); -// Ok(args) -// } - -fn set_user_defined_config_file_and_path(user_defined: &mut UserDefinedData) { - if user_defined.config_file.starts_with("./") { - let pwd = current_dir().expect("expected current directory from system call"); - user_defined.config_file = user_defined.config_file.replacen(".", pwd.to_string_lossy().to_string().as_str(), 1); - } - user_defined.config_file_path = PathBuf::from(&user_defined.config_file.to_string()); - if user_defined.config_file_path.is_relative() && !user_defined.data_directory.is_empty() { - user_defined.config_file_path = PathBuf::from(user_defined.data_directory.clone().to_string()).join(&user_defined.config_file_path); - } -} - -fn check_status_of_data_directory(user_defined: &mut UserDefinedData) { - match user_defined.data_directory.is_empty() { - true => {}, - false => { - user_defined.data_directory_path = PathBuf::from(&user_defined.data_directory); - } - } -} - -fn check_status_of_config_file(user_defined: &UserDefinedData) -> Result<(), PathBuf> { - return if (!user_defined.config_file.starts_with("/") && !user_defined.config_file.starts_with("./") && !user_defined.config_file.starts_with("../")) - && user_defined.data_directory.is_empty() { - Err(PathBuf::from(&user_defined.config_file)) - } else { Ok(()) } + .vcl_args() + .into_iter() + .filter(|vcl_arg| { + (vcl_arg.name() == "--chain") + || (vcl_arg.name() == "--real-user") + || (vcl_arg.name() == "--data-directory") + || (vcl_arg.name() == "--config-file") + }) + .map(|vcl_arg| vcl_arg.dup()) + .collect(); + let user_specified_data = + config_file_data_dir_real_user_chain_from_enumerate(dirs_wrapper, orientation_args); + + Ok(user_specified_data) } pub fn initialize_database( @@ -415,6 +318,7 @@ mod tests { use super::*; use crate::node_test_utils::DirsWrapperMock; use crate::test_utils::ArgsBuilder; + use masq_lib::shared_schema::{config_file_arg, data_directory_arg, DATA_DIRECTORY_HELP}; use masq_lib::test_utils::environment_guard::EnvironmentGuard; use masq_lib::test_utils::utils::ensure_node_home_directory_exists; use masq_lib::utils::find_free_port; @@ -474,11 +378,20 @@ mod tests { ) .unwrap(); assert_eq!( - &format!("{}", user_specific_data.config_file.parent().unwrap().display()), - &user_specific_data.data_directory.unwrap().to_string_lossy().to_string(), + &format!( + "{}", + user_specific_data.config_file.parent().unwrap().display() + ), + &user_specific_data + .data_directory + .to_string_lossy() + .to_string(), ); - assert_eq!("booga.toml", user_specific_data.config_file.file_name().unwrap()); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!( + "booga.toml", + user_specific_data.config_file.file_name().unwrap() + ); + assert_eq!(user_specific_data.real_user_spec, false); } #[test] @@ -503,11 +416,20 @@ mod tests { ) .unwrap(); assert_eq!( - format!("{}", user_specific_data.config_file.parent().unwrap().display()), - user_specific_data.data_directory.unwrap().to_string_lossy().to_string(), + format!( + "{}", + user_specific_data.config_file.parent().unwrap().display() + ), + user_specific_data + .data_directory + .to_string_lossy() + .to_string(), + ); + assert_eq!( + "booga.toml", + user_specific_data.config_file.file_name().unwrap() ); - assert_eq!("booga.toml", user_specific_data.config_file.file_name().unwrap()); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!(user_specific_data.real_user_spec, false); //all these assertions of 'real_user_specified' was incorrect, no idea how this tests could pass before } #[cfg(not(target_os = "windows"))] @@ -530,7 +452,7 @@ mod tests { "/tmp/booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!(user_specific_data.real_user_spec, false); } #[cfg(target_os = "windows")] @@ -553,7 +475,7 @@ mod tests { r"\tmp\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!(user_specific_data.real_user_specified, false); } #[cfg(target_os = "windows")] @@ -576,7 +498,7 @@ mod tests { r"c:\tmp\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!(user_specific_data.real_user_specified, false); } #[cfg(target_os = "windows")] @@ -599,7 +521,7 @@ mod tests { r"\\TMP\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!(user_specific_data.real_user_specified, false); } #[cfg(target_os = "windows")] @@ -623,7 +545,7 @@ mod tests { r"c:tmp\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(true, user_specific_data.real_user_specified); + assert_eq!(user_specific_data.real_user_specified, false); } #[test] diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index fe2e6bd48..e921df71b 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -1,12 +1,12 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::bootstrapper::BootstrapperConfig; -use crate::node_configurator::{argument_from_enumerate, DirsWrapperReal}; +use crate::node_configurator::DirsWrapperReal; use crate::node_configurator::{initialize_database, DirsWrapper, NodeConfigurator}; use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; -use masq_lib::multi_config::{ComputedVcl, MultiConfig, VclArg, VirtualCommandLine}; -use masq_lib::shared_schema::{ConfiguratorError, RealUser}; +use masq_lib::multi_config::{ComputedVcl, MultiConfig, VirtualCommandLine}; +use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; use std::net::{IpAddr, Ipv4Addr}; @@ -24,16 +24,17 @@ use crate::node_configurator::unprivileged_parse_args_configuration::{ UnprivilegedParseArgsConfiguration, UnprivilegedParseArgsConfigurationDaoReal, }; use crate::node_configurator::{ - data_directory_from_context, determine_user_specific_data, real_user_data_directory_path_and_chain, + data_directory_from_context, determine_user_specific_data, + real_user_data_directory_path_and_chain, }; use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::utils::make_new_multi_config; use crate::tls_discriminator_factory::TlsDiscriminatorFactory; +use itertools::Itertools; use masq_lib::constants::{DEFAULT_UI_PORT, HTTP_PORT, TLS_PORT}; use masq_lib::multi_config::{CommandLineVcl, ConfigFileVcl, EnvironmentVcl}; use std::str::FromStr; -use itertools::Itertools; pub struct NodeConfiguratorStandardPrivileged { dirs_wrapper: Box, @@ -142,47 +143,103 @@ pub fn server_initializer_collected_params<'a>( ) -> Result, ConfiguratorError> { let app = app_node(); let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, args)?; - let config_file_vcl = match ConfigFileVcl::new(&user_specific_data.config_file, user_specific_data.config_file_specified) { + let config_file_vcl = match ConfigFileVcl::new( + &user_specific_data.config_file, + user_specific_data.config_file_spec, + ) { Ok(cfv) => cfv, - Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())) + Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; - let config_file_specified = &user_specific_data.config_file_specified; - let config_file_path = &user_specific_data.config_file; - let to_iter_config = &config_file_vcl.args(); - let config_real_user_args = to_iter_config - .iter().enumerate() - .filter(|(index, vcl_arg)| { - vcl_arg.deref() == &"--real-user".to_string() - }).collect_vec(); - let (real_user, real_user_specified) = match config_real_user_args.is_empty() { - false => { - let real_user_str = to_iter_config[config_real_user_args[0].0 + 1].clone(); - (real_user_str, true) - }, - true => (user_specific_data.real_user.unwrap().to_string(), false) - }; - + // println!("user_specific_data: {:#?}", user_specific_data); + let environment_vcl = EnvironmentVcl::new(&app); + let commandline_vcl = CommandLineVcl::new(args.to_vec()); + let config_file_specified = user_specific_data.config_file_spec; + let config_file_path = user_specific_data.config_file; + let extract_value_from_vcl = + |vcl: &dyn VirtualCommandLine, name: &str, var: &str, spec: bool| { + let args = vcl.args(); + let extracted_args = args + .iter() + .enumerate() + .filter(|(_index, vcl_arg)| vcl_arg.deref() == &name.to_string()) + .collect_vec(); + match extracted_args.is_empty() { + false => { + let val_str = args[extracted_args[0].0 + 1].clone(); + (val_str, true) + } + true => (var.to_string(), spec), + } + }; + let (cf_real_user, cf_real_user_specified) = extract_value_from_vcl( + &config_file_vcl, + "--real-user", + user_specific_data.real_user.to_string().as_str(), + user_specific_data.real_user_spec, + ); + let (env_real_user, env_real_user_specified) = extract_value_from_vcl( + &environment_vcl, + "--real-user", + user_specific_data.real_user.to_string().as_str(), + user_specific_data.real_user_spec, + ); + let (cmd_real_user, cmd_real_user_specified) = extract_value_from_vcl( + &commandline_vcl, + "--real-user", + user_specific_data.real_user.to_string().as_str(), + user_specific_data.real_user_spec, + ); let mut full_multi_config_vec: Vec> = vec![ - Box::new(config_file_vcl), - Box::new(EnvironmentVcl::new(&app)), - Box::new(CommandLineVcl::new(args.to_vec())), - ]; + Box::new(config_file_vcl), + Box::new(environment_vcl), + Box::new(commandline_vcl), + ]; //TODO write test for MultiConfig "try_new" merge line 76 - let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool | { + let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool| { match specified { - true => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec!["".to_string(), key.to_string(), value.to_string(),]))), - false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec!["".to_string(), key.to_string(), value.to_string(),]))) + true => match value.is_empty() { + true => (), + false => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec![ + "".to_string(), + key.to_string(), + value.to_string(), + ]))), + }, + false => match value.is_empty() { + true => (), + false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec![ + "".to_string(), + key.to_string(), + value.to_string(), + ]))), + }, }; }; - fill_specified_or_unspecified_box("--config-file", &user_specific_data.config_file.as_path().to_string_lossy().as_ref(), user_specific_data.config_file_specified); - fill_specified_or_unspecified_box("--data-directory", &user_specific_data.data_directory.unwrap().to_string_lossy().as_ref(), user_specific_data.data_directory_specified); - fill_specified_or_unspecified_box("--real-user", real_user.to_string().as_str(), real_user_specified); - //TODO check if following two lines can't overwrite the computed values wrongly - full_multi_config_vec.push( Box::new(EnvironmentVcl::new(&app))); - full_multi_config_vec.push( Box::new(CommandLineVcl::new(args.to_vec()))); - // println!("full_multi_config_vec: {:#?}", full_multi_config_vec); - let full_multi_config = make_new_multi_config(&app,full_multi_config_vec)?; + fill_specified_or_unspecified_box( + "--config-file", + config_file_path.as_path().to_string_lossy().as_ref(), + config_file_specified, + ); + fill_specified_or_unspecified_box( + "--data-directory", + user_specific_data.data_directory.to_string_lossy().as_ref(), + user_specific_data.data_directory_spec, + ); + fill_specified_or_unspecified_box("--real-user", cf_real_user.as_str(), cf_real_user_specified); + fill_specified_or_unspecified_box( + "--real-user", + env_real_user.as_str(), + env_real_user_specified, + ); + fill_specified_or_unspecified_box( + "--real-user", + cmd_real_user.as_str(), + cmd_real_user_specified, + ); + // println!("full_multi_config_vec: {:#?}", full_multi_config_vec); + let full_multi_config = make_new_multi_config(&app, full_multi_config_vec)?; + // println!("full_multi_config: {:#?}", full_multi_config); Ok(full_multi_config) } @@ -329,7 +386,7 @@ mod tests { use masq_lib::multi_config::VirtualCommandLine; use masq_lib::test_utils::environment_guard::{ClapGuard, EnvironmentGuard}; use masq_lib::test_utils::utils::{ensure_node_home_directory_exists, TEST_DEFAULT_CHAIN}; - use masq_lib::utils::{running_test, slice_of_strs_to_vec_of_strings}; + use masq_lib::utils::running_test; use rustc_hex::FromHex; use std::convert::TryFrom; use std::env::current_dir; @@ -481,6 +538,7 @@ mod tests { fn server_initializer_collected_params_can_read_parameters_from_config_file() { running_test(); let _guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard", "server_initializer_collected_params_can_read_parameters_from_config_file", @@ -488,16 +546,20 @@ mod tests { { let mut config_file = File::create(home_dir.join("config.toml")).unwrap(); config_file - .write_all(b"dns-servers = \"111.111.111.111,222.222.222.222\"\n") + .write_all(b"dns-servers = \"111.111.111.111,222.222.222.222\"\nreal-user = \"1004:1004:/home/gooba\"\n") .unwrap(); } + std::env::set_var("MASQ_DNS_SERVERS", ""); + std::env::set_var("MASQ_CONFIG_FILE", ""); let directory_wrapper = make_pre_populated_mocked_directory_wrapper(); - - let multi_config = server_initializer_collected_params( - &directory_wrapper, - &slice_of_strs_to_vec_of_strings(&["", "--data-directory", home_dir.to_str().unwrap()]), - ) - .unwrap(); + let args = ArgsBuilder::new().param("--data-directory", home_dir.to_str().unwrap()); + let args_vec: Vec = args.into(); + let multi_config = + server_initializer_collected_params(&directory_wrapper, args_vec.as_slice()).unwrap(); + assert_eq!( + value_m!(multi_config, "data-directory", String).unwrap(), + home_dir.to_str().unwrap() + ); assert_eq!( value_m!(multi_config, "dns-servers", String).unwrap(), "111.111.111.111,222.222.222.222".to_string() @@ -797,17 +859,24 @@ mod tests { #[test] fn multi_config_vcl_is_computed_do_right_job() { running_test(); - let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + let _env_guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); + let home_dir = ensure_node_home_directory_exists( + "node_configurator_standard", + "multi_config_vcl_is_computed_do_right_job", + ); let data_dir = &home_dir.join("data_dir"); - let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); + let config_file_relative = File::create(PathBuf::from("./generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job").join("config.toml")).unwrap(); fill_up_config_file(config_file_relative); let env_vec_array = vec![ - ("MASQ_CONFIG_FILE", "./generated/config.toml"), + ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/config.toml"), #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), ]; - env_vec_array.clone().into_iter() - .for_each (|(name, value)| std::env::set_var (name, value)); + env_vec_array + .clone() + .into_iter() + .for_each(|(name, value)| std::env::set_var(name, value)); let args = ArgsBuilder::new(); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() @@ -817,49 +886,37 @@ mod tests { let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let env_multiconfig = result.unwrap(); - match env_multiconfig.is_user_specified("--data-directory") { - true => (), - false => { - assert_eq!( - value_m!(env_multiconfig, "data-directory", String).unwrap(), - "booga/data_dir/MASQ/polygon-mainnet".to_string() - ) - } - } - - match (env_multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { - (true, true) => { - let pwd = PathBuf::from( value_m!(env_multiconfig, "data-directory", String).unwrap()); - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() - ) - }, - (true, false) => { - let pwd = current_dir().unwrap(); - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() - ) - }, - (_, _) => () - } + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "booga/data_dir/MASQ/polygon-mainnet".to_string() + ); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + current_dir().expect("expected curerrnt dir") + .join(PathBuf::from( "./generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/config.toml")) + .to_string_lossy().to_string() + ); } #[test] - fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot() { + fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot( + ) { running_test(); + let _guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); let data_dir = &home_dir.join("data_dir"); - let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); + let config_file_relative = File::create(PathBuf::from("./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot").join("config.toml")).unwrap(); fill_up_config_file(config_file_relative); let env_vec_array = vec![ - ("MASQ_CONFIG_FILE", "./generated/config.toml"), + ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml"), #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), ]; - env_vec_array.clone().into_iter() - .for_each (|(name, value)| std::env::set_var (name, value)); + env_vec_array + .clone() + .into_iter() + .for_each(|(name, value)| std::env::set_var(name, value)); let args = ArgsBuilder::new(); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() @@ -869,50 +926,83 @@ mod tests { let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let env_multiconfig = result.unwrap(); - match env_multiconfig.is_user_specified("--data-directory") { - true => (), - false => { - assert_eq!( - value_m!(env_multiconfig, "data-directory", String).unwrap(), - "/home/wooga/data_dir/MASQ/polygon-mainnet".to_string() - ) - } - } + assert_eq!(env_multiconfig.is_user_specified("--data-directory"), false); + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "booga/data_dir/MASQ/polygon-mainnet".to_string() + ); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + current_dir().unwrap().join(PathBuf::from( "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml")).to_string_lossy().to_string() + ); + } - match (env_multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { - (true, true) => { - let pwd = PathBuf::from( value_m!(env_multiconfig, "data-directory", String).unwrap()); - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() - ) - }, - (true, false) => { - let pwd = current_dir().unwrap(); - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() - ) - }, - (_, _) => () - } + #[test] + fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde( + ) { + running_test(); + let _guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde"); + let data_dir = &home_dir.join("data_dir"); + let _create_data_dir = create_dir_all(data_dir); + let config_file_relative = File::create(home_dir.join("config.toml")).unwrap(); + fill_up_config_file(config_file_relative); + let env_vec_array = vec![ + ("MASQ_DATA_DIRECTORY", "~/data_dir"), + ("MASQ_CONFIGFILE", "~/config.toml"), + #[cfg(not(target_os = "windows"))] + ("MASQ_REAL_USER", "9999:9999:booga"), + ]; + env_vec_array + .clone() + .into_iter() + .for_each(|(name, value)| std::env::set_var(name, value)); + let args = ArgsBuilder::new(); + let args_vec: Vec = args.into(); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_tilde"))) + .data_dir_result(Some(data_dir.to_path_buf())); + let result_data_dir = current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_tilde/data_dir"); + + let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + let env_multiconfig = result.unwrap(); + + assert_eq!(env_multiconfig.is_user_specified("--data-directory"), true); + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + result_data_dir.to_string_lossy().to_string() + ); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + result_data_dir + .join(PathBuf::from("config.toml")) + .to_string_lossy() + .to_string() + ); } #[test] - fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_directory() { + fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_directory( + ) { running_test(); - let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); - println!("home_dir {:#?}", &home_dir); + let _guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_directory"); let data_dir = &home_dir.join("data_dir"); - let config_file_relative = File::create(PathBuf::from("./generated").join("config.toml")).unwrap(); + create_dir_all(home_dir.join("config")).expect("expected directory for config"); + let config_file_relative = File::create(&home_dir.join("config/config.toml")).unwrap(); fill_up_config_file(config_file_relative); - let current_directory = current_dir().unwrap(); vec![ - ("MASQ_CONFIG_FILE", "generated/config.toml"), - //("MASQ_DATA_DIRECTORY", ¤t_directory.display().to_string().as_str()), - ].into_iter() - .for_each (|(name, value)| std::env::set_var (name, value)); - let args = ArgsBuilder::new(); + ("MASQ_CONFIG_FILE", "config/config.toml"), + ("MASQ_DATA_DIRECTORY", "/unexistent/directory"), + ("MASQ_REAL_USER", "999:999:/home/malooga"), + ] + .into_iter() + .for_each(|(name, value)| std::env::set_var(name, value)); + let args = ArgsBuilder::new() + .param("--real-user", "1001:1001:cooga") + .param("--data-directory", &home_dir.to_string_lossy().to_string()); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() .home_dir_result(Some(home_dir.clone())) @@ -921,174 +1011,88 @@ mod tests { let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let multiconfig = result.unwrap(); - match multiconfig.is_user_specified("--data-directory") { - true => { - assert_eq!( - &value_m!(multiconfig, "data-directory", String).unwrap(), - ¤t_directory.to_string_lossy().to_string() - ) - }, - false => () - } - println!("real-user {}", value_m!(multiconfig, "real-user", String).unwrap()); + assert_eq!(multiconfig.is_user_specified("--data-directory"), true); + assert_eq!( + &value_m!(multiconfig, "data-directory", String).unwrap(), + &home_dir.to_string_lossy().to_string() + ); assert_eq!( &value_m!(multiconfig, "real-user", String).unwrap(), - "1002:1002:/home/wooga" - ) + "1001:1001:cooga" + ); + } + + #[test] + #[should_panic( + expected = "You need to define data-directory to be able define config file with naked directory 'dirname/config.toml'." + )] + fn server_initializer_collected_params_fails_on_naked_dir_config_file_without_data_directory() { + running_test(); + let _guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + + let data_dir = &home_dir.join("data_dir"); + vec![("MASQ_CONFIG_FILE", "config/config.toml")] + .into_iter() + .for_each(|(name, value)| std::env::set_var(name, value)); + let args = ArgsBuilder::new(); + let args_vec: Vec = args.into(); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(home_dir.clone())) + .data_dir_result(Some(data_dir.to_path_buf())); - // match (multiconfig.is_user_specified("--config-file"), env_multiconfig.is_user_specified("--data-directory")) { - // (true, true) => { - // let pwd = PathBuf::from( value_m!(multiconfig, "data-directory", String).unwrap()); - // assert_eq!( - // value_m!(env_multiconfig, "config-file", String).unwrap(), - // pwd.join(PathBuf::from( "generated/config.toml")).to_string_lossy().to_string() - // ) - // }, - // (_, _) => () - // } + let _result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); } - // #[test] - // fn server_initializer_collected_params_combine_vlcs_properly() { - // running_test(); - // let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_combine_vlcs_properly"); - // let data_dir = &home_dir.join("data_dir"); - // let config_file = File::create(&home_dir.join("config.toml")).unwrap(); - // let current_directory = current_dir().unwrap(); - // let data_dir_sys = create_dir_all(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet")); - // { - // fill_up_config_file(config_file); - // match data_dir_sys { - // Ok(..) => { - // let config_file_vcl = File::create(PathBuf::from(home_dir.to_string_lossy().as_ref().to_owned() + "/data_dir/MASQ/polygon-mainnet").join("config.toml")).unwrap(); - // fill_up_config_file(config_file_vcl); - // } - // Err(e) => panic!("unable to create config file: {}", e) - // } - // } - // - // let env_vec_array = vec![ - // ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml"), - // //("MASQ_DATA_DIRECTORY", home_dir.to_str().unwrap()), - // #[cfg(not(target_os = "windows"))] - // ("MASQ_REAL_USER", "9999:9999:booga"), - // ]; - // env_vec_array.clone().into_iter() - // .for_each (|(name, value)| std::env::set_var (name, value)); - // let args = ArgsBuilder::new(); - // let args_vec: Vec = args.into(); - // let dir_wrapper = DirsWrapperMock::new() - // .home_dir_result(Some(home_dir.clone())) - // .data_dir_result(Some(data_dir.to_path_buf())); - // let mut env_data_directory = false; - // for (item, _vaue) in env_vec_array.to_vec().as_slice() { - // if item == &"MASQ_DATA_DIRECTORY" { env_data_directory = true; } - // } - // - // let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - // let env_multiconfig = result.unwrap(); - // - // let args = ArgsBuilder::new() - // .param("--data-directory", current_directory.join(Path::new("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home")).to_string_lossy().to_string().as_str()) - // .param("--real-user", "1001:1001:cooga"); - // let args_vec: Vec = args.into(); - // let mut cmd_data_directory = false; - // for item in args_vec.clone().as_slice() { - // if item == &"--data-directory".to_string() { cmd_data_directory = true; } - // } - // let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - // let result2 = params.as_ref().expect("REASON"); - // let vcl_multiconfig = result2; - // - // assert_eq!( - // value_m!(env_multiconfig, "config-file", String).unwrap(), - // current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() - // ); - // match env_multiconfig.is_user_specified("--data-directory") { - // true => { - // assert_eq!( - // value_m!(env_multiconfig, "data-directory", String).unwrap(), - // "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() - // ) - // } - // false => { - // println!("data-directory is not user specified in Environment"); - // () - // } - // } - // - // #[cfg(not(target_os = "windows"))] - // match env_multiconfig.is_user_specified("--real-user") { - // true => { - // assert_eq!( - // value_m!(env_multiconfig, "real-user", String).unwrap(), - // "1002:1002:/home/wooga".to_string() - // ) - // } - // false => { - // println!("real-user is not user specified in Environment"); - // () - // } - // } - // - // #[cfg(not(target_os = "windows"))] - // match vcl_multiconfig.is_user_specified("--real-user") { - // true => { - // match env_multiconfig.is_user_specified("--real-user") { - // true => { - // println!("real-user is inherited from Environment {}", value_m!(vcl_multiconfig, "real-user", String).unwrap()); - // assert_eq!( - // value_m!(vcl_multiconfig, "real-user", String).unwrap(), - // "1001:1001:cooga".to_string() - // ) - // } - // false => { - // assert_eq!( - // value_m!(vcl_multiconfig, "real-user", String).unwrap(), - // "1002:1002:/home/wooga".to_string() - // ) - // } - // } - // } - // false => { - // println!("real-user is not user specified in Command-line"); - // () - // } - // } - // println!("env_data_directory {:#?}", env_data_directory); - // match vcl_multiconfig.is_user_specified("--data-directory") { - // true => { - // match env_data_directory && !cmd_data_directory { - // true => { - // println!("data-directory is inherited from Environment"); - // assert_eq!( - // value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - // "generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home".to_string() - // ) - // } - // false => { - // match cmd_data_directory { - // true => { - // assert_eq!( - // value_m!(vcl_multiconfig, "data-directory", String).unwrap(), - // current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home").to_string_lossy().to_string() - // ) - // } - // false => { - // println!("data-directory is not user specified in ENV") - // } - // } - // - // } - // }; - // - // } - // false => { - // println!("data-directory is not user specified in Command-line"); - // () - // } - // } - // } + #[test] + fn server_initializer_collected_params_combine_vlcs_properly() { + running_test(); + let _guard = EnvironmentGuard::new(); + let _clap_guard = ClapGuard::new(); + let home_dir = ensure_node_home_directory_exists( + "node_configurator_standard", + "server_initializer_collected_params_combine_vlcs_properly", + ); + let data_dir = &home_dir.join("data_dir"); + let config_file = File::create(&home_dir.join("config.toml")).unwrap(); + let current_directory = current_dir().unwrap(); + fill_up_config_file(config_file); + + let env_vec_array = vec![ + ("MASQ_CONFIG_FILE", "config.toml"), + ("MASQ_DATA_DIRECTORY", "/nonexistent/directory/home"), + #[cfg(not(target_os = "windows"))] + ("MASQ_REAL_USER", "9999:9999:booga"), + ]; + env_vec_array + .clone() + .into_iter() + .for_each(|(name, value)| std::env::set_var(name, value)); + let dir_wrapper = DirsWrapperMock::new() + .home_dir_result(Some(home_dir.clone())) + .data_dir_result(Some(data_dir.to_path_buf())); + let args = ArgsBuilder::new() + .param("--data-directory", current_directory.join(Path::new("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home")).to_string_lossy().to_string().as_str()) + .param("--real-user", "1001:1001:cooga"); + let args_vec: Vec = args.into(); + let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); + let result = params.as_ref().expect("REASON"); + let multiconfig = result; + + assert_eq!( + value_m!(multiconfig, "config-file", String).unwrap(), + current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() + ); + assert_eq!(multiconfig.is_user_specified("--data-directory"), true); + + #[cfg(not(target_os = "windows"))] + assert_eq!(multiconfig.is_user_specified("--real-user"), true); + assert_eq!( + value_m!(multiconfig, "real-user", String).unwrap(), + "1001:1001:cooga".to_string() + ); + } #[test] fn server_initializer_collected_params_senses_when_user_specifies_config_file() { @@ -1232,6 +1236,7 @@ mod tests { #[test] fn server_initializer_collected_params_rejects_invalid_gas_price() { running_test(); + let _guard = EnvironmentGuard::new(); let _clap_guard = ClapGuard::new(); let args = ArgsBuilder::new().param("--gas-price", "unleaded"); let args_vec: Vec = args.into(); @@ -1408,8 +1413,8 @@ mod tests { .data_dir_result(Some(PathBuf::from(standard_data_dir))), }; - let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()) - .unwrap(); + let result = + server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()).unwrap(); assert_eq!( value_m!(result, "data-directory", String).unwrap(), @@ -1420,6 +1425,7 @@ mod tests { #[test] fn server_initializer_collected_params_senses_when_user_specifies_data_directory_without_chain_specific_directory( ) { + let _guard = EnvironmentGuard::new(); running_test(); let home_dir = Path::new("/home/cooga"); let home_dir_poly_main = home_dir.join(".local").join("MASQ").join("polygon-mainnet"); diff --git a/node/src/server_initializer.rs b/node/src/server_initializer.rs index eac4a5ac0..f7d4961ad 100644 --- a/node/src/server_initializer.rs +++ b/node/src/server_initializer.rs @@ -47,18 +47,14 @@ impl ServerInitializer for ServerInitializerReal { .as_mut() .initialize_as_privileged(¶ms), ) - .combine_results( - self.bootstrapper - .as_mut() - .initialize_as_privileged(¶ms), - ); + .combine_results(self.bootstrapper.as_mut().initialize_as_privileged(¶ms)); self.privilege_dropper .chown(Path::new(data_directory.as_str()), &real_user); self.privilege_dropper.drop_privileges(&real_user); - result + result .combine_results( self.dns_socket_server .as_mut() diff --git a/node/tests/utils.rs b/node/tests/utils.rs index b60017063..bc80d7d39 100644 --- a/node/tests/utils.rs +++ b/node/tests/utils.rs @@ -273,6 +273,8 @@ impl MASQNode { #[allow(dead_code)] pub fn wait_for_exit(&mut self) -> Option { + //TODO Put the body of this function in a background thread and wait on the thread for a few + // seconds. If the thread doesn't terminate, leak the thread and return None. let child_opt = self.child.take(); let output_opt = self.output.take(); match (child_opt, output_opt) { From 413ffc599013ae25de9aa54dcf12d5032705306b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Mon, 23 Oct 2023 20:52:56 +0200 Subject: [PATCH 13/24] fix windows test of real_user soecified --- node/src/node_configurator/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 1e769aaed..a7c36e7d9 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -475,7 +475,7 @@ mod tests { r"\tmp\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(user_specific_data.real_user_specified, false); + assert_eq!(user_specific_data.real_user_spec, false); } #[cfg(target_os = "windows")] @@ -498,7 +498,7 @@ mod tests { r"c:\tmp\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(user_specific_data.real_user_specified, false); + assert_eq!(user_specific_data.real_user_spec, false); } #[cfg(target_os = "windows")] @@ -521,7 +521,7 @@ mod tests { r"\\TMP\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(user_specific_data.real_user_specified, false); + assert_eq!(user_specific_data.real_user_spec, false); } #[cfg(target_os = "windows")] @@ -545,7 +545,7 @@ mod tests { r"c:tmp\booga.toml", &format!("{}", user_specific_data.config_file.display()) ); - assert_eq!(user_specific_data.real_user_specified, false); + assert_eq!(user_specific_data.real_user_spec, false); } #[test] From 18d0cc1dd5aa8585adcb68094dead6b11fa0f631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 25 Oct 2023 18:15:47 +0200 Subject: [PATCH 14/24] renaming, adding TODOs, removing resolved TODOS --- masq_lib/src/multi_config.rs | 1 + node/src/node_configurator/mod.rs | 22 +++++++++---------- .../node_configurator_standard.rs | 3 +-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index c3e3e49c3..b2b5ec21e 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -73,6 +73,7 @@ impl<'a> MultiConfig<'a> { }; }) }); + // TODO pull this out to function to use in determine_user_specific_data let merged = vcls .into_iter() .fold(initial, |so_far, vcl| merge(so_far, vcl)); diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index a7c36e7d9..380c038a8 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -42,7 +42,7 @@ pub struct UserSpecifiedData { } fn get_chain_from_vcl(configs: &[Box]) -> (Chain, bool) { - match argument_from_enumerate(configs, "--chain") { + match argument_from_vcl(configs, "--chain") { Some(chain) => (Chain::from(chain), true), None => (DEFAULT_CHAIN, false), } @@ -52,7 +52,7 @@ fn get_real_user_from_vcl( configs: &[Box], dirs_wrapper: &dyn DirsWrapper, ) -> (RealUser, bool) { - match argument_from_enumerate(configs, "--real-user") { + match argument_from_vcl(configs, "--real-user") { Some(user) => { let real_user_split: Vec<&str> = user.split(':').collect(); ( @@ -81,7 +81,7 @@ fn get_data_directory_from_vcl( real_user: &RealUser, chain: &Chain, ) -> (PathBuf, bool) { - match argument_from_enumerate(configs, "--data-directory") { + match argument_from_vcl(configs, "--data-directory") { Some(data_dir) => match PathBuf::from(data_dir).starts_with("~/") { true => { let home_dir_from_wrapper = dirs_wrapper @@ -111,7 +111,7 @@ fn get_config_file_from_vcl( data_directory_def: bool, dirs_wrapper: &dyn DirsWrapper, ) -> (PathBuf, bool) { - match argument_from_enumerate(configs, "--config-file") { + match argument_from_vcl(configs, "--config-file") { Some(config_str) => { let path = match PathBuf::from(config_str).is_relative() { true => { @@ -123,9 +123,9 @@ fn get_config_file_from_vcl( true => { let home_dir_from_wrapper = dirs_wrapper .home_dir() - .expect("expexted users home dir") + .expect("expexted users home_dir") .to_str() - .expect("expect home dir") + .expect("expect str home_dir") .to_string(); let replaced_tilde_dir = config_str @@ -135,7 +135,7 @@ fn get_config_file_from_vcl( } false => match data_directory_def { true => PathBuf::from(data_directory).join(PathBuf::from(config_str)), - false => panic!("You need to define data-directory to be able define config file with naked directory 'dirname/config.toml'.") + false => panic!("You need to define data-directory to define config file with naked directory 'dirname/config.toml'.") } } } @@ -155,11 +155,10 @@ fn get_config_file_from_vcl( } } -fn config_file_data_dir_real_user_chain_from_enumerate( +fn config_file_data_dir_real_user_chain_from_vcl( dirs_wrapper: &dyn DirsWrapper, configs: Vec>, ) -> UserSpecifiedData { - //TODO break down this function to collection of small one purpose functions let mut user_specified_data = UserSpecifiedData { chain: Default::default(), chain_spec: false, @@ -197,7 +196,7 @@ fn config_file_data_dir_real_user_chain_from_enumerate( user_specified_data } -fn argument_from_enumerate<'a>(configs: &'a [Box], needle: &'a str) -> Option<&'a str> { +fn argument_from_vcl<'a>(configs: &'a [Box], needle: &'a str) -> Option<&'a str> { match configs .iter() .find(|vcl_arg_box| vcl_arg_box.deref().name() == needle) @@ -226,8 +225,9 @@ pub fn determine_user_specific_data( }) .map(|vcl_arg| vcl_arg.dup()) .collect(); + //TODO probably need to implement new merge from config_vcl with orientation_args let user_specified_data = - config_file_data_dir_real_user_chain_from_enumerate(dirs_wrapper, orientation_args); + config_file_data_dir_real_user_chain_from_vcl(dirs_wrapper, orientation_args); Ok(user_specified_data) } diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index e921df71b..42609aa62 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -150,7 +150,6 @@ pub fn server_initializer_collected_params<'a>( Ok(cfv) => cfv, Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; - // println!("user_specific_data: {:#?}", user_specific_data); let environment_vcl = EnvironmentVcl::new(&app); let commandline_vcl = CommandLineVcl::new(args.to_vec()); let config_file_specified = user_specific_data.config_file_spec; @@ -1024,7 +1023,7 @@ mod tests { #[test] #[should_panic( - expected = "You need to define data-directory to be able define config file with naked directory 'dirname/config.toml'." + expected = "You need to define data-directory to define config file with naked directory 'dirname/config.toml'." )] fn server_initializer_collected_params_fails_on_naked_dir_config_file_without_data_directory() { running_test(); From efd3fbb57d07f360354338dbb9790513ecee233f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Mon, 30 Oct 2023 15:07:08 +0100 Subject: [PATCH 15/24] fixing tests for windows os --- .../node_configurator_standard.rs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 42609aa62..917297c96 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -224,12 +224,15 @@ pub fn server_initializer_collected_params<'a>( user_specific_data.data_directory.to_string_lossy().as_ref(), user_specific_data.data_directory_spec, ); + #[cfg(not(target_os = "windows"))] fill_specified_or_unspecified_box("--real-user", cf_real_user.as_str(), cf_real_user_specified); + #[cfg(not(target_os = "windows"))] fill_specified_or_unspecified_box( "--real-user", env_real_user.as_str(), env_real_user_specified, ); + #[cfg(not(target_os = "windows"))] fill_specified_or_unspecified_box( "--real-user", cmd_real_user.as_str(), @@ -885,10 +888,17 @@ mod tests { let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let env_multiconfig = result.unwrap(); + #[cfg(not(target_os = "windows"))] assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), "booga/data_dir/MASQ/polygon-mainnet".to_string() ); + #[cfg(target_os = "windows")] + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/home\\data_dir\\MASQ\\polygon-mainnet".to_string() + ); + #[cfg(not(target_os = "windows"))] assert_eq!( value_m!(env_multiconfig, "config-file", String).unwrap(), current_dir().expect("expected curerrnt dir") @@ -926,10 +936,17 @@ mod tests { let env_multiconfig = result.unwrap(); assert_eq!(env_multiconfig.is_user_specified("--data-directory"), false); + #[cfg(not(target_os = "windows"))] assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), "booga/data_dir/MASQ/polygon-mainnet".to_string() ); + #[cfg(target_os = "windows")] + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/home\\data_dir\\MASQ\\polygon-mainnet".to_string() + ); + #[cfg(not(target_os = "windows"))] assert_eq!( value_m!(env_multiconfig, "config-file", String).unwrap(), current_dir().unwrap().join(PathBuf::from( "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml")).to_string_lossy().to_string() @@ -995,6 +1012,7 @@ mod tests { vec![ ("MASQ_CONFIG_FILE", "config/config.toml"), ("MASQ_DATA_DIRECTORY", "/unexistent/directory"), + #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "999:999:/home/malooga"), ] .into_iter() @@ -1015,6 +1033,7 @@ mod tests { &value_m!(multiconfig, "data-directory", String).unwrap(), &home_dir.to_string_lossy().to_string() ); + #[cfg(not(target_os = "windows"))] assert_eq!( &value_m!(multiconfig, "real-user", String).unwrap(), "1001:1001:cooga" @@ -1078,15 +1097,20 @@ mod tests { let params = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let result = params.as_ref().expect("REASON"); let multiconfig = result; - + #[cfg(not(target_os = "windows"))] assert_eq!( value_m!(multiconfig, "config-file", String).unwrap(), current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() ); + #[cfg(target_os = "windows")] + assert_eq!( + value_m!(multiconfig, "config-file", String).unwrap(), + current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home\\config.toml").to_string_lossy().to_string() + ); assert_eq!(multiconfig.is_user_specified("--data-directory"), true); - #[cfg(not(target_os = "windows"))] assert_eq!(multiconfig.is_user_specified("--real-user"), true); + #[cfg(not(target_os = "windows"))] assert_eq!( value_m!(multiconfig, "real-user", String).unwrap(), "1001:1001:cooga".to_string() From cf6da59bc0efc45634ecb113451673efcc45b543 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Oct 2023 06:38:53 -0700 Subject: [PATCH 16/24] fixed on windows --- node/src/node_configurator/node_configurator_standard.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 917297c96..9845707c4 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -10,6 +10,7 @@ use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; use std::net::{IpAddr, Ipv4Addr}; +#[cfg(not(target_os = "windows"))] use std::ops::Deref; use clap::value_t; @@ -31,6 +32,7 @@ use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::utils::make_new_multi_config; use crate::tls_discriminator_factory::TlsDiscriminatorFactory; +#[cfg(not(target_os = "windows"))] use itertools::Itertools; use masq_lib::constants::{DEFAULT_UI_PORT, HTTP_PORT, TLS_PORT}; use masq_lib::multi_config::{CommandLineVcl, ConfigFileVcl, EnvironmentVcl}; @@ -154,6 +156,7 @@ pub fn server_initializer_collected_params<'a>( let commandline_vcl = CommandLineVcl::new(args.to_vec()); let config_file_specified = user_specific_data.config_file_spec; let config_file_path = user_specific_data.config_file; + #[cfg(not(target_os = "windows"))] let extract_value_from_vcl = |vcl: &dyn VirtualCommandLine, name: &str, var: &str, spec: bool| { let args = vcl.args(); @@ -170,18 +173,21 @@ pub fn server_initializer_collected_params<'a>( true => (var.to_string(), spec), } }; + #[cfg(not(target_os = "windows"))] let (cf_real_user, cf_real_user_specified) = extract_value_from_vcl( &config_file_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); + #[cfg(not(target_os = "windows"))] let (env_real_user, env_real_user_specified) = extract_value_from_vcl( &environment_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); + #[cfg(not(target_os = "windows"))] let (cmd_real_user, cmd_real_user_specified) = extract_value_from_vcl( &commandline_vcl, "--real-user", @@ -944,7 +950,7 @@ mod tests { #[cfg(target_os = "windows")] assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), - "generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/home\\data_dir\\MASQ\\polygon-mainnet".to_string() + "generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/home\\data_dir\\MASQ\\polygon-mainnet".to_string() ); #[cfg(not(target_os = "windows"))] assert_eq!( From 589587932e511b29025baae45f692ee0e743c400 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Nov 2023 17:12:51 -0700 Subject: [PATCH 17/24] fixed real user for windows --- node/src/node_configurator/mod.rs | 9 +++++++- .../node_configurator_standard.rs | 21 +++++++++---------- node/src/server_initializer.rs | 6 ++++-- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 380c038a8..2cadad6cc 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -69,7 +69,14 @@ fn get_real_user_from_vcl( ) } None => ( - RealUser::new(None, None, None).populate(dirs_wrapper), + #[cfg(target_os = "windows")] + { + RealUser::new(Some(999999), Some(999999), None).populate(dirs_wrapper) + }, + #[cfg(not(target_os = "windows"))] + { + RealUser::new(None, None, None).populate(dirs_wrapper) + }, false, ), } diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 9845707c4..afad98c50 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -10,7 +10,6 @@ use masq_lib::shared_schema::ConfiguratorError; use masq_lib::utils::NeighborhoodModeLight; use std::net::SocketAddr; use std::net::{IpAddr, Ipv4Addr}; -#[cfg(not(target_os = "windows"))] use std::ops::Deref; use clap::value_t; @@ -32,7 +31,6 @@ use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::utils::make_new_multi_config; use crate::tls_discriminator_factory::TlsDiscriminatorFactory; -#[cfg(not(target_os = "windows"))] use itertools::Itertools; use masq_lib::constants::{DEFAULT_UI_PORT, HTTP_PORT, TLS_PORT}; use masq_lib::multi_config::{CommandLineVcl, ConfigFileVcl, EnvironmentVcl}; @@ -156,7 +154,7 @@ pub fn server_initializer_collected_params<'a>( let commandline_vcl = CommandLineVcl::new(args.to_vec()); let config_file_specified = user_specific_data.config_file_spec; let config_file_path = user_specific_data.config_file; - #[cfg(not(target_os = "windows"))] + let extract_value_from_vcl = |vcl: &dyn VirtualCommandLine, name: &str, var: &str, spec: bool| { let args = vcl.args(); @@ -173,21 +171,21 @@ pub fn server_initializer_collected_params<'a>( true => (var.to_string(), spec), } }; - #[cfg(not(target_os = "windows"))] + let (cf_real_user, cf_real_user_specified) = extract_value_from_vcl( &config_file_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); - #[cfg(not(target_os = "windows"))] + let (env_real_user, env_real_user_specified) = extract_value_from_vcl( &environment_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); - #[cfg(not(target_os = "windows"))] + let (cmd_real_user, cmd_real_user_specified) = extract_value_from_vcl( &commandline_vcl, "--real-user", @@ -200,6 +198,7 @@ pub fn server_initializer_collected_params<'a>( Box::new(commandline_vcl), ]; //TODO write test for MultiConfig "try_new" merge line 76 + // TODO use vector from line 206 and push into it and then construct the CommandLineVcl same with ComputedVcl let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool| { match specified { true => match value.is_empty() { @@ -230,24 +229,24 @@ pub fn server_initializer_collected_params<'a>( user_specific_data.data_directory.to_string_lossy().as_ref(), user_specific_data.data_directory_spec, ); - #[cfg(not(target_os = "windows"))] + fill_specified_or_unspecified_box("--real-user", cf_real_user.as_str(), cf_real_user_specified); - #[cfg(not(target_os = "windows"))] + fill_specified_or_unspecified_box( "--real-user", env_real_user.as_str(), env_real_user_specified, ); - #[cfg(not(target_os = "windows"))] + fill_specified_or_unspecified_box( "--real-user", cmd_real_user.as_str(), cmd_real_user_specified, ); - // println!("full_multi_config_vec: {:#?}", full_multi_config_vec); + //println!("full_multi_config_vec: {:#?}", full_multi_config_vec); let full_multi_config = make_new_multi_config(&app, full_multi_config_vec)?; - // println!("full_multi_config: {:#?}", full_multi_config); + //println!("full_multi_config: {:#?}", full_multi_config); Ok(full_multi_config) } diff --git a/node/src/server_initializer.rs b/node/src/server_initializer.rs index f7d4961ad..eba5f945f 100644 --- a/node/src/server_initializer.rs +++ b/node/src/server_initializer.rs @@ -38,8 +38,10 @@ pub struct ServerInitializerReal { impl ServerInitializer for ServerInitializerReal { fn go(&mut self, streams: &mut StdStreams<'_>, args: &[String]) -> RunModeResult { let params = server_initializer_collected_params(self.dirs_wrapper.as_ref(), args)?; - let real_user = value_m!(params, "real-user", RealUser).unwrap(); - let data_directory = value_m!(params, "data-directory", String).unwrap(); + let real_user = value_m!(params, "real-user", RealUser) + .expect("ServerInitializer: Real user not present in Multi Config"); + let data_directory = value_m!(params, "data-directory", String) + .expect("ServerInitializer: Data directory not present in Multi Config"); let result: RunModeResult = Ok(()) .combine_results( From 62e99e33e171232e579033c0d8c4e8f6f58157b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 1 Nov 2023 19:12:23 +0100 Subject: [PATCH 18/24] removed filling specified and unspecified boxes from server_initializer_collected_params, fixed formatting for get_real_user_from_vcl --- node/src/node_configurator/mod.rs | 13 +-- .../node_configurator_standard.rs | 104 +++++++++++------- 2 files changed, 72 insertions(+), 45 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index 2cadad6cc..d746e60e5 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -68,17 +68,16 @@ fn get_real_user_from_vcl( true, ) } - None => ( + None => { #[cfg(target_os = "windows")] { - RealUser::new(Some(999999), Some(999999), None).populate(dirs_wrapper) - }, + (RealUser::new(Some(999999), Some(999999), None).populate(dirs_wrapper), false) + } #[cfg(not(target_os = "windows"))] { - RealUser::new(None, None, None).populate(dirs_wrapper) - }, - false, - ), + (RealUser::new(None, None, None).populate(dirs_wrapper), false) + } + }, } } diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index afad98c50..c7f93f88a 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -1,7 +1,7 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::bootstrapper::BootstrapperConfig; -use crate::node_configurator::DirsWrapperReal; +use crate::node_configurator::{DirsWrapperReal, UserSpecifiedData}; use crate::node_configurator::{initialize_database, DirsWrapper, NodeConfigurator}; use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; @@ -137,24 +137,16 @@ fn collect_externals_from_multi_config( ) } -pub fn server_initializer_collected_params<'a>( - dirs_wrapper: &dyn DirsWrapper, - args: &[String], -) -> Result, ConfiguratorError> { - let app = app_node(); - let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, args)?; - let config_file_vcl = match ConfigFileVcl::new( - &user_specific_data.config_file, - user_specific_data.config_file_spec, - ) { - Ok(cfv) => cfv, - Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), - }; - let environment_vcl = EnvironmentVcl::new(&app); - let commandline_vcl = CommandLineVcl::new(args.to_vec()); +fn extract_values_and_fill_boxes( + config_file_vcl: Box, + environment_vcl: Box, + commandline_vcl: Box, + user_specific_data: UserSpecifiedData +) -> (Vec, Vec) { + let mut unspecified_vec: Vec = vec!["".to_string()]; + let mut specified_vec: Vec = vec!["".to_string()]; let config_file_specified = user_specific_data.config_file_spec; let config_file_path = user_specific_data.config_file; - let extract_value_from_vcl = |vcl: &dyn VirtualCommandLine, name: &str, var: &str, spec: bool| { let args = vcl.args(); @@ -171,51 +163,42 @@ pub fn server_initializer_collected_params<'a>( true => (var.to_string(), spec), } }; - let (cf_real_user, cf_real_user_specified) = extract_value_from_vcl( - &config_file_vcl, + &*config_file_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); let (env_real_user, env_real_user_specified) = extract_value_from_vcl( - &environment_vcl, + &*environment_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); let (cmd_real_user, cmd_real_user_specified) = extract_value_from_vcl( - &commandline_vcl, + &*commandline_vcl, "--real-user", user_specific_data.real_user.to_string().as_str(), user_specific_data.real_user_spec, ); - let mut full_multi_config_vec: Vec> = vec![ - Box::new(config_file_vcl), - Box::new(environment_vcl), - Box::new(commandline_vcl), - ]; - //TODO write test for MultiConfig "try_new" merge line 76 - // TODO use vector from line 206 and push into it and then construct the CommandLineVcl same with ComputedVcl + let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool| { match specified { true => match value.is_empty() { true => (), - false => full_multi_config_vec.push(Box::new(CommandLineVcl::new(vec![ - "".to_string(), - key.to_string(), - value.to_string(), - ]))), + false => { + unspecified_vec.push(key.to_string()); + unspecified_vec.push(value.to_string()); + } }, false => match value.is_empty() { true => (), - false => full_multi_config_vec.push(Box::new(ComputedVcl::new(vec![ - "".to_string(), - key.to_string(), - value.to_string(), - ]))), + false => { + specified_vec.push(key.to_string()); + specified_vec.push(value.to_string()); + } }, }; }; @@ -243,6 +226,51 @@ pub fn server_initializer_collected_params<'a>( cmd_real_user.as_str(), cmd_real_user_specified, ); + (unspecified_vec, specified_vec) +} + +pub fn server_initializer_collected_params<'a>( + dirs_wrapper: &dyn DirsWrapper, + args: &[String], +) -> Result, ConfiguratorError> { + let app = app_node(); + let user_specific_data = determine_user_specific_data(dirs_wrapper, &app, args)?; + let config_file_vcl = match ConfigFileVcl::new( + &user_specific_data.config_file, + user_specific_data.config_file_spec, + ) { + Ok(cfv) => cfv, + Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), + }; + //TODO get rid of this second construction of ConfigFileVcl + let config_file_vcl_next = match ConfigFileVcl::new( + &user_specific_data.config_file, + user_specific_data.config_file_spec, + ) { + Ok(cfv) => cfv, + Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), + }; + let environment_vcl = EnvironmentVcl::new(&app); + let commandline_vcl = CommandLineVcl::new(args.to_vec()); + let (unspecified_vec, specified_vec) = extract_values_and_fill_boxes( + Box::new(config_file_vcl), + Box::new(EnvironmentVcl::new(&app)), + Box::new(CommandLineVcl::new(commandline_vcl.args())), + user_specific_data + ); + let mut full_multi_config_vec: Vec> = vec![ + Box::new(config_file_vcl_next), + Box::new(environment_vcl), + Box::new(commandline_vcl), + ]; + + //TODO write test for MultiConfig "try_new" merge line 76 + if unspecified_vec.len() > 1 { + full_multi_config_vec.push(Box::new(ComputedVcl::new(unspecified_vec))); + } + if specified_vec.len() > 1 { + full_multi_config_vec.push(Box::new(CommandLineVcl::new(specified_vec))); + } //println!("full_multi_config_vec: {:#?}", full_multi_config_vec); let full_multi_config = make_new_multi_config(&app, full_multi_config_vec)?; From 34b8fea084cf68f97f0b4a981c299bd64336bec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 1 Nov 2023 19:19:00 +0100 Subject: [PATCH 19/24] formatting --- node/src/node_configurator/mod.rs | 12 +++++++++--- .../node_configurator/node_configurator_standard.rs | 6 +++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index d746e60e5..bda38980b 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -71,13 +71,19 @@ fn get_real_user_from_vcl( None => { #[cfg(target_os = "windows")] { - (RealUser::new(Some(999999), Some(999999), None).populate(dirs_wrapper), false) + ( + RealUser::new(Some(999999), Some(999999), None).populate(dirs_wrapper), + false, + ) } #[cfg(not(target_os = "windows"))] { - (RealUser::new(None, None, None).populate(dirs_wrapper), false) + ( + RealUser::new(None, None, None).populate(dirs_wrapper), + false, + ) } - }, + } } } diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index c7f93f88a..d306d7317 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -1,8 +1,8 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::bootstrapper::BootstrapperConfig; -use crate::node_configurator::{DirsWrapperReal, UserSpecifiedData}; use crate::node_configurator::{initialize_database, DirsWrapper, NodeConfigurator}; +use crate::node_configurator::{DirsWrapperReal, UserSpecifiedData}; use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; use masq_lib::multi_config::{ComputedVcl, MultiConfig, VirtualCommandLine}; @@ -141,7 +141,7 @@ fn extract_values_and_fill_boxes( config_file_vcl: Box, environment_vcl: Box, commandline_vcl: Box, - user_specific_data: UserSpecifiedData + user_specific_data: UserSpecifiedData, ) -> (Vec, Vec) { let mut unspecified_vec: Vec = vec!["".to_string()]; let mut specified_vec: Vec = vec!["".to_string()]; @@ -256,7 +256,7 @@ pub fn server_initializer_collected_params<'a>( Box::new(config_file_vcl), Box::new(EnvironmentVcl::new(&app)), Box::new(CommandLineVcl::new(commandline_vcl.args())), - user_specific_data + user_specific_data, ); let mut full_multi_config_vec: Vec> = vec![ Box::new(config_file_vcl_next), From 8369ff98efffca5e530666b04ab44f69ed94400c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Mon, 6 Nov 2023 17:54:24 +0100 Subject: [PATCH 20/24] last fixes of extract_values_and_fill_boxes, and test server_initializer_collected_params_handle_config_file_from_commandline_and_real_user_from_config_file_with_data_dir_started_by_tilde --- masq_lib/src/multi_config.rs | 8 ++ .../node_configurator_standard.rs | 100 +++++++++++------- 2 files changed, 69 insertions(+), 39 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index b2b5ec21e..1663290db 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -427,6 +427,14 @@ pub struct ConfigFileVcl { vcl_args: Vec>, } +impl Clone for ConfigFileVcl { + fn clone(&self) -> Self { + ConfigFileVcl { + vcl_args: self.vcl_args.iter().map(|arg| arg.dup()).collect(), + } + } +} + impl VirtualCommandLine for ConfigFileVcl { fn vcl_args(&self) -> Vec<&dyn VclArg> { vcl_args_to_vcl_args(&self.vcl_args) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index d306d7317..6ca0d730a 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -184,24 +184,40 @@ fn extract_values_and_fill_boxes( user_specific_data.real_user_spec, ); - let mut fill_specified_or_unspecified_box = |key: &str, value: &str, specified: bool| { - match specified { - true => match value.is_empty() { - true => (), - false => { - unspecified_vec.push(key.to_string()); - unspecified_vec.push(value.to_string()); - } - }, - false => match value.is_empty() { - true => (), - false => { - specified_vec.push(key.to_string()); - specified_vec.push(value.to_string()); - } + let mut fill_specified_or_unspecified_box = + |key: &str, value: &str, specified: bool| match value.is_empty() { + true => (), + false => match specified { + true => match specified_vec.contains(&key.to_string()) { + true => { + let index = specified_vec + .iter() + .position(|r| r == key) + .expect("expected index of vcl name") + + 1; + specified_vec[index] = value.to_string(); + } + false => { + specified_vec.push(key.to_string()); + specified_vec.push(value.to_string()); + } + }, + false => match unspecified_vec.contains(&key.to_string()) { + true => { + let index = unspecified_vec + .iter() + .position(|r| r == key) + .expect("expected index of vcl name") + + 1; + unspecified_vec[index] = value.to_string(); + } + false => { + unspecified_vec.push(key.to_string()); + unspecified_vec.push(value.to_string()); + } + }, }, }; - }; fill_specified_or_unspecified_box( "--config-file", config_file_path.as_path().to_string_lossy().as_ref(), @@ -242,28 +258,20 @@ pub fn server_initializer_collected_params<'a>( Ok(cfv) => cfv, Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), }; - //TODO get rid of this second construction of ConfigFileVcl - let config_file_vcl_next = match ConfigFileVcl::new( - &user_specific_data.config_file, - user_specific_data.config_file_spec, - ) { - Ok(cfv) => cfv, - Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())), - }; + let environment_vcl = EnvironmentVcl::new(&app); let commandline_vcl = CommandLineVcl::new(args.to_vec()); let (unspecified_vec, specified_vec) = extract_values_and_fill_boxes( - Box::new(config_file_vcl), + Box::new(config_file_vcl.clone()), Box::new(EnvironmentVcl::new(&app)), Box::new(CommandLineVcl::new(commandline_vcl.args())), user_specific_data, ); let mut full_multi_config_vec: Vec> = vec![ - Box::new(config_file_vcl_next), + Box::new(config_file_vcl), Box::new(environment_vcl), Box::new(commandline_vcl), ]; - //TODO write test for MultiConfig "try_new" merge line 76 if unspecified_vec.len() > 1 { full_multi_config_vec.push(Box::new(ComputedVcl::new(unspecified_vec))); @@ -987,19 +995,19 @@ mod tests { } #[test] - fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde( + fn server_initializer_collected_params_handle_config_file_from_commandline_and_real_user_from_config_file_with_data_dir_started_by_tilde( ) { running_test(); let _guard = EnvironmentGuard::new(); let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde"); - let data_dir = &home_dir.join("data_dir"); + let data_dir = &home_dir.join("masqhome"); let _create_data_dir = create_dir_all(data_dir); - let config_file_relative = File::create(home_dir.join("config.toml")).unwrap(); + let config_file_relative = File::create(data_dir.join("config.toml")).unwrap(); fill_up_config_file(config_file_relative); let env_vec_array = vec![ - ("MASQ_DATA_DIRECTORY", "~/data_dir"), - ("MASQ_CONFIGFILE", "~/config.toml"), + ("MASQ_IP", "9.8.7.6"), + ("MASQ_BLOCKCHAIN-SERVICE-URL", "https://www.mainnet2.com"), #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), ]; @@ -1007,28 +1015,42 @@ mod tests { .clone() .into_iter() .for_each(|(name, value)| std::env::set_var(name, value)); - let args = ArgsBuilder::new(); + let args = ArgsBuilder::new() + .param("--blockchain-service-url", "https://www.mainnet1.com") + .param("--config-file", "~/masqhome/config.toml") + .param("--data-directory", "~/masqhome"); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() - .home_dir_result(Some(current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_tilde"))) + .home_dir_result(Some(current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde/home"))) .data_dir_result(Some(data_dir.to_path_buf())); - let result_data_dir = current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_tilde/data_dir"); + let result_data_dir = current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde/home/masqhome"); let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); - let env_multiconfig = result.unwrap(); + let multiconfig = result.unwrap(); - assert_eq!(env_multiconfig.is_user_specified("--data-directory"), true); + assert_eq!(multiconfig.is_user_specified("--data-directory"), true); assert_eq!( - value_m!(env_multiconfig, "data-directory", String).unwrap(), + value_m!(multiconfig, "data-directory", String).unwrap(), result_data_dir.to_string_lossy().to_string() ); + assert_eq!(multiconfig.is_user_specified("--real-user"), true); assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), + value_m!(multiconfig, "real-user", String).unwrap(), + "9999:9999:booga" + ); + assert_eq!(multiconfig.is_user_specified("--config-file"), true); + assert_eq!( + value_m!(multiconfig, "config-file", String).unwrap(), result_data_dir .join(PathBuf::from("config.toml")) .to_string_lossy() .to_string() ); + assert_eq!(value_m!(multiconfig, "ip", String).unwrap(), "9.8.7.6"); + assert_eq!( + value_m!(multiconfig, "blockchain-service-url", String).unwrap(), + "https://www.mainnet1.com" + ); } #[test] From 5b02822f62a90f3f168de7d241794771e99ed3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 8 Nov 2023 09:51:11 +0100 Subject: [PATCH 21/24] fixed windows test for tilde --- .../node_configurator_standard.rs | 77 ++++++++++--------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 6ca0d730a..311a4e240 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -930,22 +930,23 @@ mod tests { let env_multiconfig = result.unwrap(); #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(env_multiconfig, "data-directory", String).unwrap(), - "booga/data_dir/MASQ/polygon-mainnet".to_string() - ); + { + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "booga/data_dir/MASQ/polygon-mainnet".to_string() + ); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + current_dir().expect("expected curerrnt dir") + .join(PathBuf::from( "./generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/config.toml")) + .to_string_lossy().to_string() + ); + } #[cfg(target_os = "windows")] assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), "generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/home\\data_dir\\MASQ\\polygon-mainnet".to_string() ); - #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - current_dir().expect("expected curerrnt dir") - .join(PathBuf::from( "./generated/test/node_configurator_standard/multi_config_vcl_is_computed_do_right_job/config.toml")) - .to_string_lossy().to_string() - ); } #[test] @@ -978,20 +979,21 @@ mod tests { assert_eq!(env_multiconfig.is_user_specified("--data-directory"), false); #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(env_multiconfig, "data-directory", String).unwrap(), - "booga/data_dir/MASQ/polygon-mainnet".to_string() - ); + { + assert_eq!( + value_m!(env_multiconfig, "data-directory", String).unwrap(), + "booga/data_dir/MASQ/polygon-mainnet".to_string() + ); + assert_eq!( + value_m!(env_multiconfig, "config-file", String).unwrap(), + current_dir().unwrap().join(PathBuf::from( "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml")).to_string_lossy().to_string() + ); + } #[cfg(target_os = "windows")] assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), "generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/home\\data_dir\\MASQ\\polygon-mainnet".to_string() ); - #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(env_multiconfig, "config-file", String).unwrap(), - current_dir().unwrap().join(PathBuf::from( "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml")).to_string_lossy().to_string() - ); } #[test] @@ -1033,11 +1035,14 @@ mod tests { value_m!(multiconfig, "data-directory", String).unwrap(), result_data_dir.to_string_lossy().to_string() ); - assert_eq!(multiconfig.is_user_specified("--real-user"), true); - assert_eq!( - value_m!(multiconfig, "real-user", String).unwrap(), - "9999:9999:booga" - ); + #[cfg(not(target_os = "windows"))] + { + assert_eq!(multiconfig.is_user_specified("--real-user"), true); + assert_eq!( + value_m!(multiconfig, "real-user", String).unwrap(), + "9999:9999:booga" + ); + } assert_eq!(multiconfig.is_user_specified("--config-file"), true); assert_eq!( value_m!(multiconfig, "config-file", String).unwrap(), @@ -1153,23 +1158,23 @@ mod tests { let result = params.as_ref().expect("REASON"); let multiconfig = result; #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(multiconfig, "config-file", String).unwrap(), - current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() - ); + { + assert_eq!( + value_m!(multiconfig, "config-file", String).unwrap(), + current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home/config.toml").to_string_lossy().to_string() + ); + assert_eq!(multiconfig.is_user_specified("--real-user"), true); + assert_eq!( + value_m!(multiconfig, "real-user", String).unwrap(), + "1001:1001:cooga".to_string() + ); + } #[cfg(target_os = "windows")] assert_eq!( value_m!(multiconfig, "config-file", String).unwrap(), current_directory.join("generated/test/node_configurator_standard/server_initializer_collected_params_combine_vlcs_properly/home\\config.toml").to_string_lossy().to_string() ); assert_eq!(multiconfig.is_user_specified("--data-directory"), true); - #[cfg(not(target_os = "windows"))] - assert_eq!(multiconfig.is_user_specified("--real-user"), true); - #[cfg(not(target_os = "windows"))] - assert_eq!( - value_m!(multiconfig, "real-user", String).unwrap(), - "1001:1001:cooga".to_string() - ); } #[test] From 0603f700fd9423441a141e9a24ac36f2b74cdf79 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Nov 2023 11:57:25 -0800 Subject: [PATCH 22/24] fix tilde test for windows --- node/src/node_configurator/node_configurator_standard.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 311a4e240..b0cd688a0 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -1017,10 +1017,16 @@ mod tests { .clone() .into_iter() .for_each(|(name, value)| std::env::set_var(name, value)); + #[cfg(not(target_os = "windows"))] let args = ArgsBuilder::new() .param("--blockchain-service-url", "https://www.mainnet1.com") .param("--config-file", "~/masqhome/config.toml") .param("--data-directory", "~/masqhome"); + #[cfg(target_os = "windows")] + let args = ArgsBuilder::new() + .param("--blockchain-service-url", "https://www.mainnet1.com") + .param("--config-file", "~/masqhome\\config.toml") + .param("--data-directory", "~/masqhome"); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() .home_dir_result(Some(current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde/home"))) From 2ec7e12b29ba1ddbadb5cb9402d9ce5f15eb1346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Wed, 8 Nov 2023 18:15:46 +0100 Subject: [PATCH 23/24] renaming of tests and functions --- .../node_configurator_standard.rs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index b0cd688a0..c257b1f23 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -137,7 +137,7 @@ fn collect_externals_from_multi_config( ) } -fn extract_values_and_fill_boxes( +fn extract_values_vcl_fill_multiconfig_vec( config_file_vcl: Box, environment_vcl: Box, commandline_vcl: Box, @@ -261,28 +261,27 @@ pub fn server_initializer_collected_params<'a>( let environment_vcl = EnvironmentVcl::new(&app); let commandline_vcl = CommandLineVcl::new(args.to_vec()); - let (unspecified_vec, specified_vec) = extract_values_and_fill_boxes( + let (unspecified_vec, specified_vec) = extract_values_vcl_fill_multiconfig_vec( Box::new(config_file_vcl.clone()), Box::new(EnvironmentVcl::new(&app)), Box::new(CommandLineVcl::new(commandline_vcl.args())), user_specific_data, ); - let mut full_multi_config_vec: Vec> = vec![ + let mut multi_config_args_vec: Vec> = vec![ Box::new(config_file_vcl), Box::new(environment_vcl), Box::new(commandline_vcl), ]; //TODO write test for MultiConfig "try_new" merge line 76 if unspecified_vec.len() > 1 { - full_multi_config_vec.push(Box::new(ComputedVcl::new(unspecified_vec))); + multi_config_args_vec.push(Box::new(ComputedVcl::new(unspecified_vec))); } if specified_vec.len() > 1 { - full_multi_config_vec.push(Box::new(CommandLineVcl::new(specified_vec))); + multi_config_args_vec.push(Box::new(CommandLineVcl::new(specified_vec))); } - //println!("full_multi_config_vec: {:#?}", full_multi_config_vec); - let full_multi_config = make_new_multi_config(&app, full_multi_config_vec)?; - //println!("full_multi_config: {:#?}", full_multi_config); + let full_multi_config = make_new_multi_config(&app, multi_config_args_vec)?; + Ok(full_multi_config) } @@ -950,17 +949,19 @@ mod tests { } #[test] - fn server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot( - ) { + fn server_initializer_collected_params_handle_dot_in_path_and_real_user_in_config_file() { running_test(); let _guard = EnvironmentGuard::new(); let _clap_guard = ClapGuard::new(); - let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot"); + let home_dir = ensure_node_home_directory_exists( + "node_configurator_standard", + "server_initializer_collected_params_handle_dot_in_path_and_real_user_in_config_file", + ); let data_dir = &home_dir.join("data_dir"); - let config_file_relative = File::create(PathBuf::from("./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot").join("config.toml")).unwrap(); + let config_file_relative = File::create(PathBuf::from("./generated/test/node_configurator_standard/server_initializer_collected_params_handle_dot_in_path_and_real_user_in_config_file").join("config.toml")).unwrap(); fill_up_config_file(config_file_relative); let env_vec_array = vec![ - ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml"), + ("MASQ_CONFIG_FILE", "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_dot_in_path_and_real_user_in_config_file/config.toml"), #[cfg(not(target_os = "windows"))] ("MASQ_REAL_USER", "9999:9999:booga"), ]; @@ -986,23 +987,23 @@ mod tests { ); assert_eq!( value_m!(env_multiconfig, "config-file", String).unwrap(), - current_dir().unwrap().join(PathBuf::from( "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/config.toml")).to_string_lossy().to_string() + current_dir().unwrap().join(PathBuf::from( "./generated/test/node_configurator_standard/server_initializer_collected_params_handle_dot_in_path_and_real_user_in_config_file/config.toml")).to_string_lossy().to_string() ); } #[cfg(target_os = "windows")] assert_eq!( value_m!(env_multiconfig, "data-directory", String).unwrap(), - "generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_path_started_by_dot/home\\data_dir\\MASQ\\polygon-mainnet".to_string() + "generated/test/node_configurator_standard/server_initializer_collected_params_handle_dot_in_path_and_real_user_in_config_file/home\\data_dir\\MASQ\\polygon-mainnet".to_string() ); } #[test] - fn server_initializer_collected_params_handle_config_file_from_commandline_and_real_user_from_config_file_with_data_dir_started_by_tilde( + fn server_initializer_collected_params_handle_tilde_in_path_config_file_from_commandline_and_real_user_from_config_file( ) { running_test(); let _guard = EnvironmentGuard::new(); let _clap_guard = ClapGuard::new(); - let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde"); + let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_handle_tilde_in_path_config_file_from_commandline_and_real_user_from_config_file"); let data_dir = &home_dir.join("masqhome"); let _create_data_dir = create_dir_all(data_dir); let config_file_relative = File::create(data_dir.join("config.toml")).unwrap(); @@ -1029,9 +1030,9 @@ mod tests { .param("--data-directory", "~/masqhome"); let args_vec: Vec = args.into(); let dir_wrapper = DirsWrapperMock::new() - .home_dir_result(Some(current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde/home"))) + .home_dir_result(Some(current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_tilde_in_path_config_file_from_commandline_and_real_user_from_config_file/home"))) .data_dir_result(Some(data_dir.to_path_buf())); - let result_data_dir = current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_config_file_from_environment_and_real_user_from_config_file_with_data_dir_started_by_tilde/home/masqhome"); + let result_data_dir = current_dir().expect("expect current directory").join("generated/test/node_configurator_standard/server_initializer_collected_params_handle_tilde_in_path_config_file_from_commandline_and_real_user_from_config_file/home/masqhome"); let result = server_initializer_collected_params(&dir_wrapper, args_vec.as_slice()); let multiconfig = result.unwrap(); From fe491ab7607b0bc2544ec4542904b54ce15115f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Parka=CC=81n?= Date: Fri, 10 Nov 2023 12:04:52 +0100 Subject: [PATCH 24/24] remove GatheredParams (the goal), optimizing is_user_specified in MultiConfig, dealing with comments --- masq_lib/src/multi_config.rs | 5 +---- node/src/server_initializer.rs | 25 ------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/masq_lib/src/multi_config.rs b/masq_lib/src/multi_config.rs index 1663290db..5c87da2c8 100644 --- a/masq_lib/src/multi_config.rs +++ b/masq_lib/src/multi_config.rs @@ -155,10 +155,7 @@ impl<'a> MultiConfig<'a> { } pub fn is_user_specified(&self, value_name: &str) -> bool { - match self.computed_value_names.contains(value_name) { - true => false, - false => true, - } + !self.computed_value_names.contains(value_name) } pub fn occurrences_of(&self, parameter: &str) -> u64 { diff --git a/node/src/server_initializer.rs b/node/src/server_initializer.rs index eba5f945f..ece182c5d 100644 --- a/node/src/server_initializer.rs +++ b/node/src/server_initializer.rs @@ -18,7 +18,6 @@ use log::{log, Level}; use masq_lib::command::StdStreams; use masq_lib::logger; use masq_lib::logger::{real_format_function, POINTER_TO_FORMAT_FUNCTION}; -use masq_lib::multi_config::MultiConfig; use masq_lib::shared_schema::ConfiguratorError; use std::any::Any; use std::io; @@ -116,30 +115,6 @@ impl ResultsCombiner for RunModeResult { } } -#[derive(Debug)] -pub struct GatheredParams<'a> { - pub multi_config: MultiConfig<'a>, - pub config_file_path: PathBuf, - pub real_user: RealUser, - pub data_directory: PathBuf, -} - -impl<'a> GatheredParams<'a> { - pub fn new( - multi_config: MultiConfig<'a>, - config_file_path: PathBuf, - real_user: RealUser, - data_directory: PathBuf, - ) -> Self { - Self { - multi_config, - config_file_path, - real_user, - data_directory, - } - } -} - lazy_static! { pub static ref LOGFILE_NAME: Mutex = Mutex::new(PathBuf::from("uninitialized")); }