Skip to content

Commit 8fc27ff

Browse files
Validate "seconds" command line options
- Validate the `--polling-interval` command line option - Validate the `--timeout` command line option - Validate the `--ttl` command line option Issue #56
1 parent 6473fd0 commit 8fc27ff

File tree

1 file changed

+85
-9
lines changed

1 file changed

+85
-9
lines changed

src/options.rs

+85-9
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,54 @@ pub struct DaemonOpts {
2121
pub common: CommonOpts, // cov(skip)
2222

2323
/// Change detection polling interval in seconds
24-
#[structopt(short = "p", long = "poll", default_value = "30")]
24+
#[structopt(
25+
short = "p", long = "poll", default_value = "30",
26+
validator = validate_polling_interval)]
2527
pub polling_interval: u64,
2628

2729
/// Log to syslog (vice console)
2830
#[structopt(long = "syslog")]
2931
pub syslog: bool, // cov(skip)
3032

3133
/// Avahi D-Bus connection timeout
32-
#[structopt(long = "timeout", default_value = "60")]
34+
#[structopt(long = "timeout", default_value = "60", validator = validate_timeout)]
3335
pub timeout: u64,
3436

3537
/// Alias mDNS time-to-live (TTL) in seconds
36-
#[structopt(long = "ttl", default_value = "60")]
38+
#[structopt(long = "ttl", default_value = "60", validator = validate_ttl)]
3739
pub ttl: u64,
3840
}
3941

42+
fn validate_polling_interval(value: String) -> Result<(), String> {
43+
match value.parse::<u64>() {
44+
Err(error) => Err(error.to_string()),
45+
Ok(timeout) if !(10..=60).contains(&timeout) => {
46+
Err("polling interval must be 10-60 seconds".to_string())
47+
},
48+
_ => Ok(()),
49+
}
50+
}
51+
52+
fn validate_timeout(value: String) -> Result<(), String> {
53+
match value.parse::<u64>() {
54+
Err(error) => Err(error.to_string()),
55+
Ok(timeout) if !(10..=300).contains(&timeout) => {
56+
Err("timeout must be 10-300 seconds".to_string())
57+
},
58+
_ => Ok(()),
59+
}
60+
}
61+
62+
fn validate_ttl(value: String) -> Result<(), String> {
63+
match value.parse::<u64>() {
64+
Err(error) => Err(error.to_string()),
65+
Ok(timeout) if timeout > (i32::MAX as u64) => {
66+
Err("time-to-live (TTL) must be less than 2,147,483,648 (2^31) seconds".to_string())
67+
},
68+
_ => Ok(()),
69+
}
70+
}
71+
4072
#[derive(Debug, StructOpt)]
4173
pub struct CommonOpts {
4274
/// Prints detailed messages
@@ -377,22 +409,66 @@ mod tests {
377409
}
378410

379411
#[test]
380-
fn daemon_timeout_option_works() {
381-
let opts = DaemonOpts::from_iter(["", "--timeout", "100"]);
382-
assert_eq!(opts.timeout, 100);
412+
fn polling_interval_validation_returns_ok_for_in_range_values() {
413+
assert!(validate_polling_interval(String::from("10")).is_ok());
414+
assert!(validate_polling_interval(String::from("30")).is_ok());
415+
assert!(validate_polling_interval(String::from("60")).is_ok());
383416
}
384417

385418
#[test]
386-
fn daemon_ttl_option_works() {
387-
let opts = DaemonOpts::from_iter(["", "--ttl", "100"]);
388-
assert_eq!(opts.ttl, 100);
419+
fn polling_interval_validation_returns_error_for_out_of_range_values() {
420+
assert!(validate_polling_interval(String::from("0")).is_err());
421+
assert!(validate_polling_interval(String::from("9")).is_err());
422+
assert!(validate_polling_interval(String::from("61")).is_err());
423+
assert!(validate_polling_interval(String::from("120")).is_err());
424+
}
425+
426+
#[test]
427+
fn timeout_validation_returns_ok_for_in_range_values() {
428+
assert!(validate_timeout(String::from("10")).is_ok());
429+
assert!(validate_timeout(String::from("60")).is_ok());
430+
assert!(validate_timeout(String::from("300")).is_ok());
431+
}
432+
433+
#[test]
434+
fn timeout_validation_returns_error_for_out_of_range_values() {
435+
assert!(validate_timeout(String::from("0")).is_err());
436+
assert!(validate_timeout(String::from("9")).is_err());
437+
assert!(validate_timeout(String::from("301")).is_err());
438+
assert!(validate_timeout(String::from("600")).is_err());
439+
}
440+
441+
#[test]
442+
fn ttl_validation_returns_ok_for_in_range_values() {
443+
assert!(validate_ttl(String::from("0")).is_ok());
444+
assert!(validate_ttl(String::from("30")).is_ok());
445+
assert!(validate_ttl(String::from("86400")).is_ok());
446+
assert!(validate_ttl(i32::MAX.to_string()).is_ok());
447+
}
448+
449+
#[test]
450+
fn ttl_validation_returns_error_for_out_of_range_values() {
451+
assert!(validate_ttl(((i32::MAX as u64) + 1).to_string()).is_err());
452+
assert!(validate_ttl(u64::MAX.to_string()).is_err());
389453
}
390454

391455
#[test]
392456
fn daemon_syslog_option_works() {
393457
let opts = DaemonOpts::from_iter(["", "--syslog"]);
394458
assert!(opts.syslog);
395459
}
460+
461+
#[test]
462+
fn daemon_timeout_option_works() {
463+
let opts = DaemonOpts::from_iter(["", "--timeout", "100"]);
464+
assert_eq!(opts.timeout, 100);
465+
}
466+
467+
#[test]
468+
fn daemon_ttl_option_works() {
469+
let opts = DaemonOpts::from_iter(["", "--ttl", "100"]);
470+
assert_eq!(opts.ttl, 100);
471+
}
396472
}
397473

398474
// end

0 commit comments

Comments
 (0)