Add unit tests and use Rust 2021

This commit is contained in:
KernelErr 2021-10-25 22:12:44 +08:00
parent 4352050b04
commit 7a5ce8e1b6
6 changed files with 120 additions and 6 deletions

2
Cargo.lock generated
View File

@ -76,7 +76,7 @@ dependencies = [
[[package]]
name = "fourth"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"futures",
"log",

View File

@ -1,7 +1,7 @@
[package]
name = "fourth"
version = "0.1.0"
edition = "2018"
version = "0.1.1"
edition = "2021"
authors = ["LI Rui <lr_cn@outlook.com>"]
license = "Apache-2.0"
description = "Simple and fast layer 4 proxy in Rust"

View File

@ -54,9 +54,11 @@ fn load_config(path: &str) -> Result<BaseConfig, ConfigError> {
}
let log_level = parsed.log.clone().unwrap_or_else(|| "info".to_string());
std::env::set_var("FOURTH_LOG", log_level.clone());
pretty_env_logger::init_custom_env("FOURTH_LOG");
debug!("Set log level to {}", log_level);
if !log_level.eq("disable") {
std::env::set_var("FOURTH_LOG", log_level.clone());
pretty_env_logger::init_custom_env("FOURTH_LOG");
debug!("Set log level to {}", log_level);
}
debug!("Config version {}", parsed.version);
@ -74,3 +76,17 @@ impl From<serde_yaml::Error> for ConfigError {
ConfigError::Yaml(err)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_load_config() {
let config = Config::new("tests/config.yaml").unwrap();
assert_eq!(config.base.version, 1);
assert_eq!(config.base.log.unwrap(), "disable");
assert_eq!(config.base.servers.len(), 2);
assert_eq!(config.base.upstream.len(), 2);
}
}

View File

@ -206,3 +206,30 @@ where
Err(_) => Ok(0),
}
}
#[cfg(test)]
mod test {
use std::thread::{self, sleep};
use std::time::Duration;
use super::*;
#[tokio::test]
async fn test_echo_server() {
use crate::config::Config;
let config = Config::new("tests/config.yaml").unwrap();
let mut server = Server::new(config.base);
thread::spawn(move || {
let _ = server.run();
});
sleep(Duration::from_secs(1)); // wait for server to start
let mut conn = TcpStream::connect("127.0.0.1:54956").await.unwrap();
let mut buf = [0u8; 1];
for i in 0..=255u8 {
conn.write(&[i]).await.unwrap();
conn.read(&mut buf).await.unwrap();
assert_eq!(&buf, &[i]);
}
conn.shutdown().await.unwrap();
}
}

View File

@ -51,3 +51,53 @@ pub fn get_sni(buf: &[u8]) -> Vec<String> {
snis
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sni_extract() {
const BUF: [u8; 517] = [
0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0xfc, 0x03, 0x03, 0x35, 0x7a, 0xba,
0x3d, 0x89, 0xd2, 0x5e, 0x7a, 0xa2, 0xd4, 0xe5, 0x6d, 0xd5, 0xa3, 0x98, 0x41, 0xb0,
0xae, 0x41, 0xfc, 0xe6, 0x64, 0xfd, 0xae, 0x0b, 0x27, 0x6d, 0x90, 0xa8, 0x0a, 0xfa,
0x90, 0x20, 0x59, 0x6f, 0x13, 0x18, 0x4a, 0xd1, 0x1c, 0xc4, 0x83, 0x8c, 0xfc, 0x93,
0xac, 0x6b, 0x3b, 0xac, 0x67, 0xd0, 0x36, 0xb0, 0xa2, 0x1b, 0x04, 0xf7, 0xde, 0x02,
0xfb, 0x96, 0x1e, 0xdc, 0x76, 0xa8, 0x00, 0x20, 0x2a, 0x2a, 0x13, 0x01, 0x13, 0x02,
0x13, 0x03, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xcc, 0xa9, 0xcc, 0xa8,
0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00,
0x01, 0x93, 0xea, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x11, 0x00, 0x00,
0x0e, 0x77, 0x77, 0x77, 0x2e, 0x6c, 0x69, 0x72, 0x75, 0x69, 0x2e, 0x74, 0x65, 0x63,
0x68, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a,
0x00, 0x08, 0xba, 0xba, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02,
0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68,
0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x05, 0x00, 0x05,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08,
0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00,
0x12, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2b, 0x00, 0x29, 0xba, 0xba, 0x00, 0x01, 0x00,
0x00, 0x1d, 0x00, 0x20, 0x3b, 0x45, 0xf9, 0xbc, 0x6e, 0x23, 0x86, 0x41, 0xa5, 0xb2,
0xf5, 0x03, 0xec, 0x67, 0x4a, 0xd7, 0x9a, 0x17, 0x9f, 0x0c, 0x38, 0x6d, 0x36, 0xf3,
0x4e, 0x5d, 0xa4, 0x7d, 0x15, 0x79, 0xa4, 0x3f, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01,
0x00, 0x2b, 0x00, 0x0b, 0x0a, 0xba, 0xba, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x03,
0x01, 0x00, 0x1b, 0x00, 0x03, 0x02, 0x00, 0x02, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03,
0x02, 0x68, 0x32, 0xda, 0xda, 0x00, 0x01, 0x00, 0x00, 0x15, 0x00, 0xc5, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let sni = get_sni(&BUF);
assert!(sni[0] == "www.lirui.tech".to_string());
}
}

21
tests/config.yaml Normal file
View File

@ -0,0 +1,21 @@
version: 1
log: disable
servers:
test_server:
listen:
- "0.0.0.0:21341"
- "[::]:21341"
tls: true
sni:
proxy.test.com: proxy
www.test.com: web
default: ban
echo_server:
listen:
- "0.0.0.0:54956"
default: echo
upstream:
web: "127.0.0.1:8080"
proxy: "www.example.com:1024"