Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH 731 - review #362

Merged
merged 55 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
cedb1b3
begining with test server_initializer_collected_params_combine_vlcs_p…
czarte Aug 23, 2023
32dd2cb
removed GatheredParams from server_initializer_collected_params, adde…
czarte Aug 28, 2023
690b099
add ComputedVcl struct and its implementation, add VclType enum, to b…
czarte Aug 29, 2023
0d7427b
back to VirtualCommandLine type without enum, passing different types…
czarte Aug 30, 2023
22e607b
fixed data flow with Evironment and Command line arguments, need to f…
czarte Aug 31, 2023
b9a6e85
changes in test to access config.file for various scenarios, add mach…
czarte Sep 4, 2023
08349e2
try to get rid of redundant MultiConfig construction in determine_use…
czarte Sep 13, 2023
8aead2a
handle computed arguments in multiconfig, closure for server_initiali…
czarte Sep 15, 2023
6167856
computing env_args and cmd_args in create_preorientation_args fn!
czarte Sep 21, 2023
7286ee8
fix passing test server_initializer_collected_params_can_read_paramet…
czarte Oct 4, 2023
fce6fe1
fixed VclArg problem with withdrawing data from VirtualCommandline, s…
czarte Oct 11, 2023
4dd0932
finalize preparing guts for multiconfig in server_initializer_collect…
czarte Oct 23, 2023
413ffc5
fix windows test of real_user soecified
czarte Oct 23, 2023
18d0cc1
renaming, adding TODOs, removing resolved TODOS
czarte Oct 25, 2023
efd3fbb
fixing tests for windows os
czarte Oct 30, 2023
cf6da59
fixed on windows
czarte Oct 31, 2023
34b8fea
formatting
czarte Nov 1, 2023
5895879
fixed real user for windows
czarte Nov 2, 2023
62e99e3
removed filling specified and unspecified boxes from server_initializ…
czarte Nov 1, 2023
8369ff9
last fixes of extract_values_and_fill_boxes, and test server_initiali…
czarte Nov 6, 2023
5b02822
fixed windows test for tilde
czarte Nov 8, 2023
0603f70
fix tilde test for windows
czarte Nov 8, 2023
2ec7e12
renaming of tests and functions
czarte Nov 8, 2023
fe491ab
remove GatheredParams (the goal), optimizing is_user_specified in Mul…
czarte Nov 10, 2023
53feaac
remove value_opt form VclArg, remove test for that, change MultiConfi…
czarte Nov 20, 2023
71ad41e
resolving comments from review
czarte Nov 21, 2023
fcd1c0d
optimization of get_config_file_from_mc fn
czarte Dec 4, 2023
0c8a866
fixed the config_path reference bin replace_dots fn
czarte Dec 4, 2023
3a46f00
solving dereferencing path in replace_dots fn
czarte Dec 4, 2023
8205800
solving config_path in replace_dots fn
czarte Dec 4, 2023
151ab18
fixed get_config_file_from_mc fn - optimized for readability
czarte Dec 4, 2023
dd290ea
formatting
czarte Dec 4, 2023
08930b9
removed println, and formated
czarte Dec 6, 2023
15e66e6
fixed windows tests
czarte Dec 8, 2023
1391842
formatting
czarte Dec 10, 2023
6973082
workaround for actual_server_drop test
czarte Dec 18, 2023
9ad7413
forgotten u64 for another test in connection_termination_test.rs
czarte Dec 18, 2023
ccdb0ad
add one more request to actual_serve_drop
czarte Dec 18, 2023
d50c740
remove forgotten piece of code
czarte Dec 19, 2023
2606ebd
fixing comments from review2
czarte Jan 4, 2024
553ac0b
remove redundant lifetime, and remove convertion to PathBuf
czarte Jan 4, 2024
a3bce20
fixing absolute path for tests of handle config-file and data directo…
czarte Jan 5, 2024
e7fdf8e
run the actions
czarte Jan 5, 2024
e5b8a6e
merge master into GH-731
czarte Jan 5, 2024
09f84ce
Merge branch 'master' into GH-731
czarte Jan 5, 2024
1877513
fix ENV and CLAP Guards in tests
czarte Jan 8, 2024
29a1c3d
fix Windows panic message for server_initializer_collected_params_han…
czarte Jan 8, 2024
4bae1dd
formatting
czarte Jan 8, 2024
4a75406
removing debugging println from accountant
czarte Jan 8, 2024
ee900f9
fix CLI UI issue with config file
czarte Jan 18, 2024
3b829b7
remove canonicalize() from test uses home_dir() from dirs crate. Prod…
czarte Jan 22, 2024
cb58d97
Reformatted some code, added a comment
dnwiebe Jan 24, 2024
7110f4f
formatting, fix order of Vcls in setup_reporter, add assertion to nod…
czarte Jan 25, 2024
9fb3296
Merge branch 'master' into GH-731
czarte Feb 7, 2024
177cc88
Merge branch 'master' into GH-731
dnwiebe Feb 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 141 additions & 12 deletions masq_lib/src/multi_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ macro_rules! values_m {
#[derive(Debug)]
pub struct MultiConfig<'a> {
arg_matches: ArgMatches<'a>,
computed_value_names: HashSet<String>,
}

impl<'a> MultiConfig<'a> {
Expand All @@ -63,9 +64,20 @@ impl<'a> MultiConfig<'a> {
) -> Result<MultiConfig<'a>, ConfiguratorError> {
let initial: Box<dyn VirtualCommandLine> =
czarte marked this conversation as resolved.
Show resolved Hide resolved
Box::new(CommandLineVcl::new(vec![String::new()]));
let merged: Box<dyn VirtualCommandLine> = vcls
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()),
};
})
});
// TODO pull this out to function to use in determine_user_specific_data
czarte marked this conversation as resolved.
Show resolved Hide resolved
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())
Expand All @@ -78,7 +90,10 @@ impl<'a> MultiConfig<'a> {
_ => return Err(Self::make_configurator_error(e)),
},
};
Ok(MultiConfig { arg_matches })
Ok(MultiConfig {
arg_matches,
computed_value_names,
})
}

fn check_for_invalid_value_err(
Expand Down Expand Up @@ -139,6 +154,10 @@ impl<'a> MultiConfig<'a> {
ConfiguratorError::required("<unknown>", &format!("Unfamiliar message: {}", e.message))
}

pub fn is_user_specified(&self, value_name: &str) -> bool {
!self.computed_value_names.contains(value_name)
}

pub fn occurrences_of(&self, parameter: &str) -> u64 {
self.arg_matches.occurrences_of(parameter)
}
Expand All @@ -150,6 +169,7 @@ impl<'a> MultiConfig<'a> {

pub trait VclArg: Debug {
fn name(&self) -> &str;
fn value_opt(&self) -> Option<&str>;
fn to_args(&self) -> Vec<String>;
fn dup(&self) -> Box<dyn VclArg>;
}
Expand All @@ -175,7 +195,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<String> {
vec![self.name.clone(), self.value.clone()]
}
Expand Down Expand Up @@ -203,7 +225,9 @@ impl VclArg for NameOnlyVclArg {
fn name(&self) -> &str {
&self.name
}

fn value_opt(&self) -> Option<&str> {
None
}
fn to_args(&self) -> Vec<String> {
vec![self.name.clone()]
}
Expand All @@ -224,6 +248,9 @@ impl NameOnlyVclArg {
pub trait VirtualCommandLine {
fn vcl_args(&self) -> Vec<&dyn VclArg>;
fn args(&self) -> Vec<String>;
fn is_computed(&self) -> bool {
false
}
}

impl Debug for dyn VirtualCommandLine {
Expand Down Expand Up @@ -263,6 +290,24 @@ pub fn merge(
})
}

pub struct ComputedVcl {
vcl_args: Vec<Box<dyn VclArg>>,
}

impl VirtualCommandLine for ComputedVcl {
fn vcl_args(&self) -> Vec<&dyn VclArg> {
vcl_args_to_vcl_args(&self.vcl_args)
}

fn args(&self) -> Vec<String> {
vcl_args_to_args(&self.vcl_args)
}

fn is_computed(&self) -> bool {
true
}
}

pub struct CommandLineVcl {
vcl_args: Vec<Box<dyn VclArg>>,
}
Expand All @@ -283,6 +328,33 @@ impl From<Vec<Box<dyn VclArg>>> for CommandLineVcl {
}
}

impl ComputedVcl {
pub fn new(mut args: Vec<String>) -> 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<String>) -> Option<Box<dyn VclArg>> {
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<String>) -> CommandLineVcl {
args.remove(0); // remove command
Expand Down Expand Up @@ -334,7 +406,7 @@ impl EnvironmentVcl {
.collect();
let mut vcl_args: Vec<Box<dyn VclArg>> = 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 == *"") {
czarte marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
let lower_name = str::replace(&upper_name[5..].to_lowercase(), "_", "-");
Expand All @@ -347,10 +419,19 @@ impl EnvironmentVcl {
}
}

#[derive(Debug)]
pub struct ConfigFileVcl {
vcl_args: Vec<Box<dyn VclArg>>,
}

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)
Expand Down Expand Up @@ -491,8 +572,14 @@ fn append<T>(ts: Vec<T>, t: T) -> Vec<T> {

#[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<String>,
) -> Self {
Self {
arg_matches,
computed_value_names,
}
}
}

Expand All @@ -504,6 +591,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() {
Expand Down Expand Up @@ -949,6 +1037,40 @@ 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<String> = vec![
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a utility function with a long name that you could use in place of this? Something like vec_of_slices_to_vec_of_strings() or something?

"",
"--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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this match at the beginning could be replaced with a .map() at the end. Also, this sequence of code that you write once for existing_value and once for non_existing_value could probably be made into a local function or closure and called twice. If locating a VclArg inside a VirtualCommandLine by name turns out to be useful enough, it could turn into a local utility function that other tests could use.

.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() {
Expand All @@ -963,12 +1085,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);

Expand Down
11 changes: 7 additions & 4 deletions node/src/daemon/setup_reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, DirsWrapper, DirsWrapperReal,
};
use crate::sub_lib::accountant::PaymentThresholds as PaymentThresholdsFromAccountant;
use crate::sub_lib::accountant::DEFAULT_SCAN_INTERVALS;
Expand Down Expand Up @@ -495,9 +495,12 @@ 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_vcl = match ConfigFileVcl::new(&config_file_path, user_specified) {
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_spec,
) {
Ok(cfv) => cfv,
Err(e) => return Err(ConfiguratorError::required("config-file", &e.to_string())),
};
Expand Down
Loading
Loading