Skip to content

Commit

Permalink
tests: add more tests and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
beac0n committed Aug 11, 2024
1 parent de60dac commit 7824c11
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ruroco*.pem
!tests/conf_dir/*

# Created by https://www.toptal.com/developers/gitignore/api/rust,intellij+all
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,intellij+all
Expand Down
4 changes: 2 additions & 2 deletions src/blocklist.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module is responsible for persisting, holding and checking the blocklist for blocked items
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;

use log::error;
use serde::ser::{SerializeSeq, Serializer};
Expand Down Expand Up @@ -43,7 +43,7 @@ where
impl Blocklist {
/// create an empty blocklist. Every entry will be saved to config_dir/blocklist.toml.
/// If the blocklist.toml file already exists, its content will be loaded if possible.
pub fn create(config_dir: &Path) -> Blocklist {
pub fn create(config_dir: &PathBuf) -> Blocklist {
let blocklist_path = get_blocklist_path(config_dir);
let blocklist_str =
fs::read_to_string(&blocklist_path).unwrap_or_else(|_| String::from(""));
Expand Down
37 changes: 30 additions & 7 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::path::{Path, PathBuf};
use std::time::SystemTime;

use log::error;
use openssl::rsa::Padding;
use std::path::PathBuf;
use std::time::SystemTime;
use std::{env, fs};

pub const RSA_PADDING: Padding = Padding::PKCS1;
pub const PADDING_SIZE: usize = 11; // see https://www.rfc-editor.org/rfc/rfc3447#section-7.2.1
Expand All @@ -17,10 +18,32 @@ pub fn time() -> Result<u128, String> {
Ok(duration.as_nanos())
}

pub fn get_socket_path(config_dir: &Path) -> PathBuf {
config_dir.join("ruroco.socket")
pub fn get_socket_path(config_dir: &PathBuf) -> PathBuf {
resolve_path(config_dir).join("ruroco.socket")
}

pub fn get_blocklist_path(config_dir: &PathBuf) -> PathBuf {
resolve_path(config_dir).join("blocklist.toml")
}

pub fn get_blocklist_path(config_dir: &Path) -> PathBuf {
config_dir.join("blocklist.toml")
pub fn resolve_path(path: &PathBuf) -> PathBuf {
if path.is_absolute() {
path.to_path_buf()
} else {
let mut full_path = match env::current_dir() {
Ok(p) => p,
Err(e) => {
error!("Could not get current directory: {e}");
return path.to_path_buf();
}
};
full_path.push(path);
match fs::canonicalize(&full_path) {
Ok(p) => p,
Err(e) => {
error!("Could not canonicalize {:?}: {e}", &full_path);
full_path
}
}
}
}
29 changes: 15 additions & 14 deletions src/server.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
use log::{error, info};
use openssl::error::ErrorStack;
use openssl::pkey::Public;
use openssl::rsa::Rsa;
use openssl::version::version;
use std::fs::ReadDir;
use std::io::Write;
use std::net::{SocketAddr, UdpSocket};
Expand All @@ -6,15 +11,9 @@ use std::os::unix::net::UnixStream;
use std::path::PathBuf;
use std::{env, fs};

use log::{error, info};
use openssl::error::ErrorStack;
use openssl::pkey::Public;
use openssl::rsa::Rsa;
use openssl::version::version;

use crate::blocklist::Blocklist;
use crate::commander_data::CommanderData;
use crate::common::{get_socket_path, time, RSA_PADDING};
use crate::common::{get_socket_path, resolve_path, time, RSA_PADDING};
use crate::config_server::ConfigServer;

#[derive(Debug)]
Expand All @@ -30,7 +29,9 @@ pub struct Server {

impl PartialEq for Server {
fn eq(&self, other: &Self) -> bool {
self.address == other.address
let self_address_split = self.address.split(':').next().unwrap_or("");
let other_address_split = other.address.split(':').next().unwrap_or("");
self_address_split == other_address_split
&& self.encrypted_data == other.encrypted_data
&& self.decrypted_data == other.decrypted_data
&& self.socket_path == other.socket_path
Expand All @@ -49,15 +50,15 @@ impl Server {
match fs::read_to_string(&path) {
Err(e) => Err(format!("Could not read {path:?}: {e}")),
Ok(config) => match toml::from_str::<ConfigServer>(&config) {
Err(e) => Err(format!("Could not parse TOML from {path:?}: {e}")),
Err(e) => Err(format!("Could not create TOML from {path:?}: {e}")),
Ok(config) => Server::create(config),
},
}
}

pub fn create(config: ConfigServer) -> Result<Server, String> {
let address = config.address;
let config_dir = config.config_dir;
let config_dir = resolve_path(&config.config_dir);

let pem_path = Self::get_pem_path(&config_dir)?;
info!("Creating server, loading public PEM from {pem_path:?}, using {} ...", version());
Expand Down Expand Up @@ -104,11 +105,11 @@ impl Server {
fn get_pem_path(config_dir: &PathBuf) -> Result<PathBuf, String> {
let pem_files = Self::get_pem_files(config_dir);

return match pem_files.len() {
match pem_files.len() {
0 => Err(format!("Could not find any .pem files in {config_dir:?}")),
1 => Ok(pem_files.first().unwrap().clone()),
other => Err(format!("Only one public PEM is supported, found {other}")),
};
}
}

fn get_pem_files(config_dir: &PathBuf) -> Vec<PathBuf> {
Expand All @@ -120,13 +121,13 @@ impl Server {
}
};

return entries
entries
.flatten()
.map(|entry| entry.path())
.filter(|path| {
path.is_file() && path.extension().is_some() && path.extension().unwrap() == "pem"
})
.collect();
.collect()
}

pub fn run(&mut self) -> Result<(), String> {
Expand Down
34 changes: 33 additions & 1 deletion tests/commander_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,38 @@ mod tests {
format!("{rand_str}{suffix}")
}

#[test]
fn test_create_from_invalid_path() {
let path = env::current_dir()
.unwrap_or(PathBuf::from("/tmp"))
.join("tests")
.join("config_invalid.toml");

let result = Commander::create_from_path(path);

assert!(result.is_err());
assert_eq!(
result.err().unwrap(),
r#"Could not create TOML from "/home/beac0n/dev/beac0n/ruroco/tests/config_invalid.toml": TOML parse error at line 1, column 1
|
1 | foo = "bar"
| ^^^^^^^^^^^
missing field `commands`
"#
);
}

#[test]
fn test_create_from_invalid_toml_path() {
let result = Commander::create_from_path(PathBuf::from("/tmp/path/does/not/exist"));

assert!(result.is_err());
assert_eq!(
result.err().unwrap(),
r#"Could not read "/tmp/path/does/not/exist": No such file or directory (os error 2)"#
);
}

#[test]
fn test_create_from_path() {
let mut commands = HashMap::new();
Expand All @@ -31,7 +63,7 @@ mod tests {
Commander::create_from_path(path),
Ok(Commander::create(ConfigServer {
address: String::from("127.0.0.1:8080"),
config_dir: PathBuf::from("/etc/ruroco/"),
config_dir: PathBuf::from("tests/conf_dir"),
socket_user: String::from("ruroco"),
socket_group: String::from("ruroco"),
commands,
Expand Down
25 changes: 25 additions & 0 deletions tests/conf_dir/ruroco_public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-----BEGIN PUBLIC KEY-----
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAsYILpb/aVzhKuwAMqSX8
Ao57fgaPpqIOoRiAxUzu19Mi5+SHA7JhzVKTRV23oUQt8KyvOMPsfYkfIuWqu5ZV
mJDN0NbN5PwmQWjYY0kDCKzjdkxWCgxLXT9E7SCqJk4i6DaLnzEKuj0cnOHzqtpu
39tKkefWSFBzp52YCEyAIFMO62G0l76PRuowz/tlWaLAxA+eleGg4DJWWgiy8Kss
xhkLJkTy78jufaHgxKlpzvCF3QAhrWEDLPBPx83SlIaYuhtXZMhfd3w0on6ii5wN
N5AcsalnBLPV/mduXNkSSYxsXq4wkXOakXOxo4ZPbwVsy7QFe/IrroLZ+Z4CTTkO
zbbS/HkDQhxzmY0bsBwihQBOOaSVZ9r5baB4DWzrkepjTkJqf6seJdbiG98ADwTN
wNCn11kf4zHR7tfsX8QG3sdVPS2NbxhxbKm4na9gNN1PpWBSog6fCw3h2awyFWFO
f1xKFmeCpC6TiJscQiAk31nJV6gW0qcAmwDH36F/fcn+buxu/0WYxDtQHLkw4Yp4
p57RFwRXv17awz9hZeAdeU5kcBu89o8frldTtUKshCXecNqDJf2ogNgFeqHugOSy
g1V/py3UZso4a/ohfl98h4XxWmeigZyosowE0zf7wgtVgNZaEbX77WWYaun2P4ka
RsMHRQGMEBQerI9tPHLJYeb4hc0d69Ei7Ukv0X0H3mLWSBixZiSV0cuC150TCYIE
aEFqdkMhgSELUtKZBDVjfQv4XfbqU1bNHcC+CeoYvjz7VheqfWcZm7AEqFW1oVQ1
iaixe6VyIb2yhtoZsi3C0eCg26l/q3DnL8lxUOeuyDhjtnxiB8DZwTmiD2qxlPEt
vy4VtsJeZwDhyxCzBXkClq1TwcxSsHjultcTWnxB/uiaCIL8CLspowEYwUd4SLF6
QdAUZ+JYV2QLIeHB36WQg1mBZyg6ELysXkQRoJ6xfAgdjJHesI78rt22aQs0I6+q
vYWDPLzkfutcwzaWlHZvwDVoQzvap1U52zNR/VIxaOH/GLvmAgJkGGgoAl47FOub
lOV760WBHOslbFP4O1hxAI+MUiUpdyT34bbrWZZq3HWCYiWgLoFUi7NsuteRYz6N
xXdDYXlOXWEBQlmq90ozFAv0SYKM41AxxTNkX5foy53sRajPwCtXHmmC2X60FbDj
0/mptvlqt0LyflPbjxXAkfTH1jISZx30yVvmmSSIpqDsJqRVLmHfWBDEA7gVljU4
/g0SqONHBfa4dSuKikNhtdpVfdlRErjXNtQ1OzxfnKlOxTepiOxyy7zbU9kyUmbU
AguhECfVELBTO16MXgXZ5hY184iifFuOEBy/wGE8wjzWQp749dlDldqy8trVR8Qh
WQIDAQAB
-----END PUBLIC KEY-----
2 changes: 1 addition & 1 deletion tests/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
address = "127.0.0.1:8080"
config_dir = "/etc/ruroco/"
config_dir = "tests/conf_dir"

[commands]
default = "touch /tmp/ruroco_test/start.test /tmp/ruroco_test/stop.test"
2 changes: 2 additions & 0 deletions tests/config_invalid.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo = "bar"
baz = "foo"
69 changes: 59 additions & 10 deletions tests/server_test.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,72 @@
#[cfg(test)]
mod tests {
use ruroco::config_server::ConfigServer;
use ruroco::server::Server;
use std::env;
use std::path::PathBuf;

use ruroco::config_server::ConfigServer;
use ruroco::server::Server;
#[test]
fn test_create_invalid_pid() {
env::set_var("LISTEN_PID", "12345");

let conf_dir_path =
env::current_dir().unwrap_or(PathBuf::from("/tmp")).join("tests").join("conf_dir");

let result = Server::create(ConfigServer {
address: String::from("127.0.0.1:8082"),
config_dir: conf_dir_path,
..Default::default()
});

assert!(result.is_ok());
}

#[test]
fn test_create_from_path() {
let path =
env::current_dir().unwrap_or(PathBuf::from("/tmp")).join("tests").join("config.toml");
let tests_dir_path = env::current_dir().unwrap_or(PathBuf::from("/tmp")).join("tests");
let conf_path = tests_dir_path.join("config.toml");
let conf_dir_path = tests_dir_path.join("conf_dir");

let res_path = Server::create_from_path(conf_path).unwrap();
let res_create = Server::create(ConfigServer {
address: String::from("127.0.0.1:8081"),
config_dir: conf_dir_path,
..Default::default()
})
.unwrap();

assert_eq!(res_path, res_create);
}

#[test]
fn test_create_from_invalid_path() {
let path = env::current_dir()
.unwrap_or(PathBuf::from("/tmp"))
.join("tests")
.join("config_invalid.toml");

let result = Server::create_from_path(path);

assert!(result.is_err());
assert_eq!(
result.err().unwrap(),
r#"Could not create TOML from "/home/beac0n/dev/beac0n/ruroco/tests/config_invalid.toml": TOML parse error at line 1, column 1
|
1 | foo = "bar"
| ^^^^^^^^^^^
missing field `commands`
"#
);
}

#[test]
fn test_create_from_invalid_toml_path() {
let result = Server::create_from_path(PathBuf::from("/tmp/path/does/not/exist"));

assert!(result.is_err());
assert_eq!(
Server::create_from_path(path),
Server::create(ConfigServer {
address: String::from("127.0.0.1:8080"),
config_dir: PathBuf::from("/etc/ruroco/"),
..Default::default()
})
result.err().unwrap(),
r#"Could not read "/tmp/path/does/not/exist": No such file or directory (os error 2)"#
);
}
}

0 comments on commit 7824c11

Please sign in to comment.