use datapipe::datapipe_types::{DatapipeError, EncryptionKey, generate_random_string};
use datapipe::utilities::{get_unused_port, identical_contents, start_after_random_delay};
use std::path::PathBuf;
use tokio::fs::remove_file;
use tokio::process::Command;
const CARGO_MANIFEST_DIR: &str = "CARGO_MANIFEST_DIR";
const RANDOM_DELAY_MAX: u8 = 8;
#[cfg(test)]
fn get_datapipe_binary() -> Result<PathBuf, DatapipeError> {
let cargo_manifest_dir = std::env::var(CARGO_MANIFEST_DIR)?;
let datapipe_binary_pathbuf: PathBuf = [&cargo_manifest_dir, "target", "debug", "datapipe"]
.iter()
.collect();
Ok(datapipe_binary_pathbuf)
}
#[cfg(test)]
fn get_test_document() -> Result<PathBuf, DatapipeError> {
let cargo_manifest_dir = std::env::var(CARGO_MANIFEST_DIR)?;
let test_document_pathbuf: PathBuf = [&cargo_manifest_dir, "tests", "data", "document.pdf"]
.iter()
.collect();
Ok(test_document_pathbuf)
}
#[cfg(test)]
fn get_temp_dir() -> PathBuf {
std::env::temp_dir()
}
#[cfg(test)]
async fn run_datapipe(args: Vec<String>) {
let datapipe_pathbuf = get_datapipe_binary().unwrap();
let exit_status = Command::new(datapipe_pathbuf)
.args(&args)
.spawn()
.unwrap()
.wait()
.await
.unwrap();
assert!(exit_status.success());
}
#[tokio::test]
async fn integration_test_copy_file() {
start_after_random_delay(RANDOM_DELAY_MAX).await;
let test_document_pathbuf = get_test_document().unwrap();
let temp_dir_pathbuf = get_temp_dir();
let mut output_file_path = temp_dir_pathbuf.clone();
let mut random_filename = generate_random_string(16);
random_filename.push_str(".pdf");
output_file_path.push(&random_filename);
let args: Vec<String> = vec![
"--file-input".to_string(),
test_document_pathbuf.to_str().unwrap().to_string(),
"--file-output".to_string(),
output_file_path.to_str().unwrap().to_string(),
];
run_datapipe(args).await;
assert!(output_file_path.exists());
assert!(
identical_contents(&test_document_pathbuf, &output_file_path)
.await
.unwrap()
);
remove_file(&output_file_path).await.unwrap();
}
#[tokio::test]
async fn integration_test_uucp_file() {
start_after_random_delay(RANDOM_DELAY_MAX).await;
let test_document_pathbuf = get_test_document().unwrap();
let temp_dir_pathbuf = get_temp_dir();
let mut output_file_path = temp_dir_pathbuf.clone();
let mut random_filename = generate_random_string(16);
random_filename.push_str(".pdf");
output_file_path.push(&random_filename);
let port = get_unused_port().await.unwrap();
println!("uucp using port {port}");
let tcp_address = format!("localhost:{}", port);
let mut children = Vec::new();
let args1: Vec<String> = vec![
"--file-input".to_string(),
test_document_pathbuf.to_str().unwrap().to_string(),
"--tcp-output".to_string(),
tcp_address.clone(),
];
let args2 = vec![
"--tcp-listen-input".to_string(),
tcp_address.clone(),
"--file-output".to_string(),
output_file_path.to_str().unwrap().to_string(),
];
children.push(tokio::spawn(run_datapipe(args2)));
children.push(tokio::spawn(run_datapipe(args1)));
for child in children {
match child.await {
Ok(()) => {}
Err(error) => {
eprintln!("{error}");
}
}
}
assert!(output_file_path.exists());
assert!(
identical_contents(&test_document_pathbuf, &output_file_path)
.await
.unwrap()
);
remove_file(&output_file_path).await.unwrap();
}
#[tokio::test]
async fn integration_test_weak_scp_file() {
start_after_random_delay(RANDOM_DELAY_MAX).await;
let test_document_pathbuf = get_test_document().unwrap();
let temp_dir_pathbuf = get_temp_dir();
let mut output_file_path = temp_dir_pathbuf.clone();
let mut random_filename = generate_random_string(16);
random_filename.push_str(".pdf");
output_file_path.push(&random_filename);
let encryption_key = EncryptionKey::generate();
let encryption_key_string = encryption_key.to_string();
let port = get_unused_port().await.unwrap();
println!("scp using port {port}");
let tcp_address = format!("localhost:{}", port);
let mut children = Vec::new();
let args1: Vec<String> = vec![
"--file-input".to_string(),
test_document_pathbuf.to_str().unwrap().to_string(),
"--encrypt".to_string(),
encryption_key_string.clone(),
"--tcp-output".to_string(),
tcp_address.clone(),
];
let args2 = vec![
"--tcp-listen-input".to_string(),
tcp_address.clone(),
"--decrypt".to_string(),
encryption_key_string,
"--file-output".to_string(),
output_file_path.to_str().unwrap().to_string(),
];
children.push(tokio::spawn(run_datapipe(args2)));
children.push(tokio::spawn(run_datapipe(args1)));
for child in children {
match child.await {
Ok(()) => {}
Err(error) => {
eprintln!("{error}");
}
}
}
assert!(output_file_path.exists());
assert!(
identical_contents(&test_document_pathbuf, &output_file_path)
.await
.unwrap()
);
remove_file(&output_file_path).await.unwrap();
}
#[tokio::test]
async fn integration_test_strong_scp_file() {
start_after_random_delay(RANDOM_DELAY_MAX).await;
let test_document_pathbuf = get_test_document().unwrap();
let temp_dir_pathbuf = get_temp_dir();
let mut output_file_path = temp_dir_pathbuf.clone();
let mut random_filename = generate_random_string(16);
random_filename.push_str(".pdf");
output_file_path.push(&random_filename);
let encryption_key = EncryptionKey::generate();
let encryption_key_string = encryption_key.to_string();
let port = get_unused_port().await.unwrap();
println!("scp using port {port}");
let tcp_address = format!("localhost:{}", port);
let mut children = Vec::new();
let args1: Vec<String> = vec![
"--file-input".to_string(),
test_document_pathbuf.to_str().unwrap().to_string(),
"--encrypt".to_string(),
encryption_key_string.clone(),
"--tls-output".to_string(),
tcp_address.clone(),
"--tls-output-skip-server-verify".to_string(),
"--keep-logs".to_string(),
];
let args2 = vec![
"--tls-listen-input".to_string(),
tcp_address.clone(),
"--tls-listen-input-generate-self-signed".to_string(),
"--tls-listen-input-skip-client-verify".to_string(),
"--decrypt".to_string(),
encryption_key_string,
"--file-output".to_string(),
output_file_path.to_str().unwrap().to_string(),
"--keep-logs".to_string(),
];
children.push(tokio::spawn(run_datapipe(args2)));
tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
children.push(tokio::spawn(run_datapipe(args1)));
for child in children {
match child.await {
Ok(()) => {}
Err(error) => {
eprintln!("{error}");
}
}
}
assert!(output_file_path.exists());
assert!(
identical_contents(&test_document_pathbuf, &output_file_path)
.await
.unwrap()
);
remove_file(&output_file_path).await.unwrap();
}