diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..c79ecdd --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,25 @@ +name: Integration Tests + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Install atftp + run: | + sudo apt-get update + sudo apt-get install atftp + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --test integration_test --features integration --verbose -- --test-threads 1 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 31000a2..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Rust - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml new file mode 100644 index 0000000..3c28b72 --- /dev/null +++ b/.github/workflows/unit.yml @@ -0,0 +1,21 @@ +name: Unit Tests + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose diff --git a/Cargo.toml b/Cargo.toml index 857e786..52f66df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,6 @@ repository = "https://github.com/altugbakan/rs-tftpd" license = "MIT" keywords = ["tftp", "server"] categories = ["command-line-utilities"] + +[features] +integration = [] \ No newline at end of file diff --git a/tests/integration_test.rs b/tests/integration_test.rs new file mode 100644 index 0000000..9159d02 --- /dev/null +++ b/tests/integration_test.rs @@ -0,0 +1,98 @@ +#![cfg(feature = "integration")] + +use std::fs::create_dir_all; +use std::process::{Child, Command, ExitStatus}; + +const SERVER_DIR: &str = "target/integration/server"; +const CLIENT_DIR: &str = "target/integration/client"; + +struct CommandRunner { + process: Child, +} + +impl CommandRunner { + fn new(program: &str, args: &[&str]) -> Self { + let command = Command::new(program) + .args(args) + .spawn() + .expect("error starting process"); + Self { process: command } + } + + fn wait(&mut self) -> ExitStatus { + self.process.wait().expect("error waiting for process") + } + + fn kill(&mut self) { + self.process.kill().expect("error killing process"); + } +} + +impl Drop for CommandRunner { + fn drop(&mut self) { + self.kill() + } +} + +#[test] +fn test_send() { + let file_name = "send"; + let port = "6969"; + initialize(format!("{SERVER_DIR}/{file_name}").as_str()); + + let _server = CommandRunner::new("target/debug/tftpd", &["-p", port, "-d", SERVER_DIR]); + let mut client = + CommandRunner::new("time", &["atftp", "-g", "-r", file_name, "127.0.0.1", port]); + + let status = client.wait(); + assert!(status.success()); +} + +#[test] +fn test_receive() { + let file_name = "receive"; + let port = "6970"; + initialize(format!("{CLIENT_DIR}/{file_name}").as_str()); + + let _server = CommandRunner::new("target/debug/tftpd", &["-p", port, "-d", SERVER_DIR]); + let mut client = CommandRunner::new( + "time", + &[ + "atftp", + "-p", + "-r", + file_name, + "-l", + format!("{CLIENT_DIR}/{file_name}").as_str(), + "127.0.0.1", + port, + ], + ); + + let status = client.wait(); + assert!(status.success()); +} + +fn initialize(file_name: &str) { + create_folders(); + create_file(file_name); +} + +fn create_folders() { + create_dir_all(SERVER_DIR).expect("error creating server directory"); + create_dir_all(CLIENT_DIR).expect("error creating client directory"); +} + +fn create_file(file_name: &str) { + Command::new("dd") + .args([ + "if=/dev/urandom", + format!("of={file_name}").as_str(), + "bs=1M", + "count=10", + ]) + .spawn() + .expect("error creating test file") + .wait() + .expect("error waiting for test file creation"); +}