rnp 0.1.146

A simple layer 4 ping tool for cloud.
Documentation
use rnp::{parse_ping_target, RnpStubServerConfig, RnpSupportedProtocol};
use std::net::SocketAddr;
use std::time::Duration;
use structopt::StructOpt;

#[derive(Debug, StructOpt, PartialEq)]
#[structopt(name = rnp::RNP_SERVER_NAME, author = rnp::RNP_AUTHOR, about = rnp::RNP_ABOUT)]
pub struct RnpServerCliOptions {
    #[structopt(flatten)]
    pub common_options: RnpServerCliCommonOptions,
}

#[derive(Debug, StructOpt, PartialEq)]
pub struct RnpServerCliCommonOptions {
    #[structopt(short = "m", long = "mode", default_value = "TCP", help = "Specify protocol to use.")]
    pub protocol: RnpSupportedProtocol,

    #[structopt(parse(try_from_str = parse_ping_target), default_value = "0.0.0.0:20821", help = "Server address.")]
    pub server_address: SocketAddr,

    #[structopt(short = "r", long = "report-interval", default_value = "1000", help = "The interval between each status report in milliseconds.")]
    pub report_interval_in_ms: u64,

    #[structopt(long, alias = "coa", help = "Close connection as soon as accepting it. [alias: --coa]")]
    pub close_on_accept: bool,

    #[structopt(short = "w", long, default_value = "0", help = "If not 0, after connection is established, write to connection.")]
    pub write_chunk_size: usize,

    #[structopt(long, alias = "wc", default_value = "1", help = "How many writes to perform, after connection is established. [alias: --wc]")]
    pub write_count_limit: u32,

    #[structopt(
        long = "write-delay",
        alias = "wd",
        default_value = "0",
        help = "When write back is enabled, sleep in milliseconds before write back. [alias: --wd]"
    )]
    pub sleep_before_write_in_ms: u64,

    #[structopt(
        long = "disconnect-delay",
        alias = "dd",
        default_value = "0",
        help = "When half shutdown is detected, wait specified milliseconds before fully shutdown the connection. [alias: --dd]"
    )]
    pub wait_before_disconnect_in_ms: u64,
}

impl RnpServerCliOptions {
    pub fn prepare_to_use(&mut self) {}

    pub fn to_stub_server_config(self) -> RnpStubServerConfig {
        return RnpStubServerConfig {
            protocol: self.common_options.protocol,
            server_address: self.common_options.server_address,
            close_on_accept: self.common_options.close_on_accept,
            sleep_before_write: Duration::from_millis(self.common_options.sleep_before_write_in_ms),
            write_chunk_size: self.common_options.write_chunk_size,
            write_count_limit: self.common_options.write_count_limit,
            report_interval: Duration::from_millis(self.common_options.report_interval_in_ms),
            wait_before_disconnect: Duration::from_millis(self.common_options.wait_before_disconnect_in_ms),
        };
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use pretty_assertions::assert_eq;
    use rnp::{RnpStubServerConfig, RnpSupportedProtocol};
    use structopt::StructOpt;

    #[test]
    fn parsing_default_options_should_work() {
        assert_eq!(
            RnpServerCliOptions {
                common_options: RnpServerCliCommonOptions {
                    protocol: RnpSupportedProtocol::TCP,
                    server_address: "10.0.0.1:443".parse().unwrap(),
                    report_interval_in_ms: 1000,
                    close_on_accept: false,
                    write_chunk_size: 0,
                    write_count_limit: 1,
                    sleep_before_write_in_ms: 0,
                    wait_before_disconnect_in_ms: 0,
                },
            },
            RnpServerCliOptions::from_iter(&["rnp_server.exe", "10.0.0.1:443"])
        );
    }

    #[test]
    fn parsing_short_options_should_work() {
        assert_eq!(
            RnpServerCliOptions {
                common_options: RnpServerCliCommonOptions {
                    protocol: RnpSupportedProtocol::TCP,
                    server_address: "10.0.0.1:443".parse().unwrap(),
                    report_interval_in_ms: 2000,
                    close_on_accept: true,
                    write_chunk_size: 1024,
                    write_count_limit: 10,
                    sleep_before_write_in_ms: 1000,
                    wait_before_disconnect_in_ms: 3000,
                },
            },
            RnpServerCliOptions::from_iter(&[
                "rnp_server.exe",
                "10.0.0.1:443",
                "-m",
                "tcp",
                "-r",
                "2000",
                "--coa",
                "-w",
                "1024",
                "--wc",
                "10",
                "--wd",
                "1000",
                "--dd",
                "3000",
            ])
        );
    }

    #[test]
    fn parsing_long_options_should_work() {
        assert_eq!(
            RnpServerCliOptions {
                common_options: RnpServerCliCommonOptions {
                    protocol: RnpSupportedProtocol::QUIC,
                    server_address: "10.0.0.1:443".parse().unwrap(),
                    report_interval_in_ms: 3000,
                    close_on_accept: true,
                    write_chunk_size: 2048,
                    write_count_limit: 20,
                    sleep_before_write_in_ms: 2000,
                    wait_before_disconnect_in_ms: 3000
                },
            },
            RnpServerCliOptions::from_iter(&[
                "rnp_server.exe",
                "10.0.0.1:443",
                "--mode",
                "quic",
                "--report-interval",
                "3000",
                "--close-on-accept",
                "--write-chunk-size",
                "2048",
                "--write-count-limit",
                "20",
                "--write-delay",
                "2000",
                "--disconnect-delay",
                "3000",
            ])
        );
    }

    #[test]
    fn new_from_cli_options_should_work() {
        assert_eq!(
            RnpStubServerConfig {
                protocol: RnpSupportedProtocol::TCP,
                server_address: "10.0.0.1:443".parse().unwrap(),
                report_interval: Duration::from_millis(1000),
                close_on_accept: true,
                write_chunk_size: 2000,
                write_count_limit: 3000,
                sleep_before_write: Duration::from_millis(4000),
                wait_before_disconnect: Duration::from_millis(5000),
            },
            RnpServerCliOptions {
                common_options: RnpServerCliCommonOptions {
                    protocol: RnpSupportedProtocol::TCP,
                    server_address: "10.0.0.1:443".parse().unwrap(),
                    report_interval_in_ms: 1000,
                    close_on_accept: true,
                    write_chunk_size: 2000,
                    write_count_limit: 3000,
                    sleep_before_write_in_ms: 4000,
                    wait_before_disconnect_in_ms: 5000,
                },
            }
            .to_stub_server_config()
        );
    }
}