Skip to content

Commit 4c0a523

Browse files
committed
feat: split nginx test util into a module
1 parent ecfd561 commit 4c0a523

File tree

3 files changed

+195
-80
lines changed

3 files changed

+195
-80
lines changed

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ pub mod http;
5656
/// This module provides an interface into the NGINX logger framework.
5757
pub mod log;
5858

59+
/// The test utility module.
60+
///
61+
/// This module provides utilities for integration tests with bundled NGINX.
62+
pub mod test_util;
63+
5964
/// Define modules exported by this library.
6065
///
6166
/// These are normally generated by the Nginx module system, but need to be

src/test_util.rs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
use std::ffi::OsStr;
2+
use std::fs;
3+
use std::fs::read_dir;
4+
use std::io::Result;
5+
use std::path::Path;
6+
use std::path::PathBuf;
7+
use std::process::Command;
8+
use std::process::Output;
9+
10+
const NGINX_PREFIX: &str = nginx_sys::metadata::NGINX_INSTALL_DIR;
11+
12+
const NGINX_SBIN_SUFFIX: &str = "sbin/nginx";
13+
const NGINX_MODULES_SUFFIX: &str = "modules";
14+
const NGINX_CONF_SUFFIX: &str = "conf/nginx.conf";
15+
const NGINX_CONF_PREFIX_SUFFIX: &str = "conf";
16+
const NGINX_ERROR_LOG_SUFFIX: &str = "logs/error.log";
17+
const NGINX_PID_SUFFIX: &str = "logs/nginx.pid";
18+
const NGINX_LOCK_SUFFIX: &str = "logs/nginx.lock";
19+
20+
const NGINX_HTTP_LOG_SUFFIX: &str = "logs/access.log";
21+
const NGINX_HTTP_CLIENT_BODY_SUFFIX: &str = "client_body_temp";
22+
const NGINX_HTTP_PROXY_TEMP_SUFFIX: &str = "proxy_temp";
23+
const NGINX_HTTP_FASTCGI_TEMP_SUFFIX: &str = "fastcgi_temp";
24+
const NGINX_HTTP_UWSGI_TEMP_SUFFIX: &str = "uwsgi_temp";
25+
const NGINX_HTTP_SCGI_TEMP_SUFFIX: &str = "scgi_temp";
26+
27+
/// harness to test nginx
28+
#[allow(dead_code)]
29+
pub struct Nginx {
30+
// these paths have options to change them from default paths (in prefix dir)
31+
// most of them are not used, but keep them for future uses
32+
prefix: PathBuf,
33+
sbin_path: PathBuf,
34+
modules_path: PathBuf,
35+
conf_path: PathBuf,
36+
conf_prefix: PathBuf,
37+
error_log_path: PathBuf,
38+
pid_path: PathBuf,
39+
lock_path: PathBuf,
40+
http_log_path: PathBuf,
41+
http_client_body_temp_path: PathBuf,
42+
http_proxy_temp_path: PathBuf,
43+
http_fastcgi_temp_path: PathBuf,
44+
http_uwsgi_temp_path: PathBuf,
45+
http_scgi_temp_path: PathBuf,
46+
}
47+
48+
impl Default for Nginx {
49+
fn default() -> Nginx {
50+
Self::new_with_prefix(NGINX_PREFIX.into())
51+
}
52+
}
53+
54+
impl Nginx {
55+
/// create nginx with prefix only
56+
pub fn new_with_prefix(prefix: PathBuf) -> Nginx {
57+
Nginx {
58+
sbin_path: prefix.join(NGINX_SBIN_SUFFIX),
59+
modules_path: prefix.join(NGINX_MODULES_SUFFIX),
60+
conf_path: prefix.join(NGINX_CONF_SUFFIX),
61+
conf_prefix: prefix.join(NGINX_CONF_PREFIX_SUFFIX),
62+
error_log_path: prefix.join(NGINX_ERROR_LOG_SUFFIX),
63+
pid_path: prefix.join(NGINX_PID_SUFFIX),
64+
lock_path: prefix.join(NGINX_LOCK_SUFFIX),
65+
http_log_path: prefix.join(NGINX_HTTP_LOG_SUFFIX),
66+
http_client_body_temp_path: prefix.join(NGINX_HTTP_CLIENT_BODY_SUFFIX),
67+
http_proxy_temp_path: prefix.join(NGINX_HTTP_PROXY_TEMP_SUFFIX),
68+
http_fastcgi_temp_path: prefix.join(NGINX_HTTP_FASTCGI_TEMP_SUFFIX),
69+
http_uwsgi_temp_path: prefix.join(NGINX_HTTP_UWSGI_TEMP_SUFFIX),
70+
http_scgi_temp_path: prefix.join(NGINX_HTTP_SCGI_TEMP_SUFFIX),
71+
prefix,
72+
}
73+
}
74+
75+
/// execute nginx process with arguments
76+
pub fn cmd(&mut self, args: &[&str]) -> Result<Output> {
77+
let result = Command::new(&self.sbin_path).args(args).output();
78+
79+
match result {
80+
Err(e) => Err(e),
81+
82+
Ok(output) => {
83+
println!("status: {}", output.status);
84+
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
85+
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
86+
Ok(output)
87+
}
88+
}
89+
}
90+
91+
/// complete stop the nginx binary
92+
pub fn stop(&mut self) -> Result<Output> {
93+
self.cmd(&["-s", "stop"])
94+
}
95+
96+
/// start the nginx binary
97+
pub fn start(&mut self) -> Result<Output> {
98+
self.cmd(&[])
99+
}
100+
101+
/// make sure we stop existing nginx and start new master process
102+
/// intentinally ignore failure in stop
103+
pub fn restart(&mut self) -> Result<Output> {
104+
let _ = self.stop();
105+
self.start()
106+
}
107+
108+
/// replace config with another config
109+
pub fn copy_config(&mut self, conf_path_from: &Path) -> Result<u64> {
110+
let conf_path_to = self
111+
.conf_prefix
112+
.join(conf_path_from.file_name().unwrap_or(OsStr::new("unknown_conf")));
113+
println!(
114+
"copying config from: {} to: {}",
115+
conf_path_to.display(),
116+
conf_path_from.display()
117+
); // replace with logging
118+
fs::copy(conf_path_from, conf_path_to)
119+
}
120+
/// create config from &str
121+
pub fn create_config_from_str(&mut self, conf_suffix: &str, conf_content: &str) -> Result<()> {
122+
let conf_path_to = self.conf_prefix.join(conf_suffix);
123+
println!(
124+
"creating config to: {} content: {}",
125+
conf_path_to.display(),
126+
conf_content
127+
); // replace with logging
128+
fs::write(conf_path_to, conf_content)
129+
}
130+
/// ensure the existance module dir
131+
fn ensure_module_dir(&mut self) -> Result<()> {
132+
fs::create_dir_all(&self.modules_path)
133+
}
134+
/// copy or replace module
135+
pub fn copy_module(&mut self, module_path_from: &Path) -> Result<u64> {
136+
self.ensure_module_dir()?;
137+
let module_path_to = self
138+
.modules_path
139+
.join(module_path_from.file_name().unwrap_or(OsStr::new("unknown_module")));
140+
println!(
141+
"copying module from: {} to: {}",
142+
module_path_to.display(),
143+
module_path_from.display()
144+
); // replace with logging
145+
fs::copy(module_path_from, module_path_to)
146+
}
147+
/// return prefix
148+
pub fn prefix(&mut self) -> &Path {
149+
&self.prefix
150+
}
151+
}
152+
153+
#[cfg(target_os = "macos")]
154+
fn target_cands() -> Option<Vec<PathBuf>> {
155+
match std::env::var("DYLD_FALLBACK_LIBRARY_PATH") {
156+
Ok(cands) => Some(cands.split(':').map(PathBuf::from).collect()),
157+
Err(_) => None,
158+
}
159+
}
160+
#[cfg(target_os = "linux")]
161+
fn target_dir_cands() -> Option<Vec<PathBuf>> {
162+
match std::env::var("LD_LIBRARY_PATH") {
163+
Ok(cands) => Some(cands.split(':').map(PathBuf::from).collect()),
164+
Err(_) => None,
165+
}
166+
}
167+
168+
/// search path and return the path to the target
169+
pub fn target_path(target_name: &str) -> std::io::Result<PathBuf> {
170+
if let Some(cands) = target_cands() {
171+
for dir in cands {
172+
if let Ok(iter) = read_dir(dir) {
173+
for entry in iter {
174+
if let Ok(entry) = entry {
175+
if entry.file_name() == target_name {
176+
return Ok(entry.path());
177+
}
178+
}
179+
}
180+
}
181+
}
182+
}
183+
Err(std::io::ErrorKind::NotFound.into())
184+
}

tests/log_test.rs

Lines changed: 6 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,27 @@
1-
use std::fs;
2-
use std::io::Result;
3-
use std::process::Command;
4-
use std::process::Output;
5-
6-
const NGINX_BIN: &str = "sbin/nginx";
7-
const NGINX_CONFIG: &str = "conf/nginx.conf";
8-
9-
/// harness to test nginx
10-
pub struct Nginx {
11-
pub install_path: String,
12-
}
13-
14-
impl Default for Nginx {
15-
/// create nginx with default
16-
fn default() -> Nginx {
17-
Nginx {
18-
install_path: nginx_sys::metadata::NGINX_INSTALL_DIR.into(),
19-
}
20-
}
21-
}
22-
23-
impl Nginx {
24-
pub fn new(path: String) -> Nginx {
25-
Nginx { install_path: path }
26-
}
27-
28-
/// get bin path to nginx instance
29-
pub fn bin_path(&mut self) -> String {
30-
format!("{}/{}", self.install_path, NGINX_BIN)
31-
}
32-
33-
/// start nginx process with arguments
34-
pub fn cmd(&mut self, args: &[&str]) -> Result<Output> {
35-
let bin_path = self.bin_path();
36-
let result = Command::new(bin_path).args(args).output();
37-
38-
match result {
39-
Err(e) => Err(e),
40-
41-
Ok(output) => {
42-
println!("status: {}", output.status);
43-
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
44-
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
45-
Ok(output)
46-
}
47-
}
48-
}
49-
50-
/// complete stop the nginx binary
51-
pub fn stop(&mut self) -> Result<Output> {
52-
self.cmd(&["-s", "stop"])
53-
}
54-
55-
/// start the nginx binary
56-
pub fn start(&mut self) -> Result<Output> {
57-
self.cmd(&[])
58-
}
59-
60-
// make sure we stop existing nginx and start new master process
61-
// intentinally ignore failure in stop
62-
pub fn restart(&mut self) -> Result<Output> {
63-
let _ = self.stop();
64-
self.start()
65-
}
66-
67-
// replace config with another config
68-
pub fn replace_config(&mut self, from: &str) -> Result<u64> {
69-
let config_path = format!("{}/{}", self.install_path, NGINX_CONFIG);
70-
println!("copying config from: {} to: {}", from, config_path); // replace with logging
71-
fs::copy(from, config_path)
72-
}
73-
}
74-
751
#[cfg(test)]
762
mod tests {
77-
use super::*;
78-
use std::env;
3+
use ngx::test_util::Nginx;
4+
use std::env::current_dir;
795

806
const TEST_NGINX_CONFIG: &str = "tests/nginx.conf";
817

828
#[test]
839
fn test() {
8410
let mut nginx = Nginx::default();
8511

86-
let current_dir = env::current_dir().expect("Unable to get current directory");
12+
let current_dir = current_dir().expect("Unable to get current directory");
8713
let test_config_path = current_dir.join(TEST_NGINX_CONFIG);
8814

8915
assert!(
90-
test_config_path.exists(),
16+
test_config_path.is_file(),
9117
"Config file not found: {}\nCurrent directory: {}",
9218
test_config_path.to_string_lossy(),
9319
current_dir.to_string_lossy()
9420
);
9521

9622
nginx
97-
.replace_config(&test_config_path.to_string_lossy())
98-
.expect(format!("Unable to load config file: {}", test_config_path.to_string_lossy()).as_str());
23+
.copy_config(&test_config_path)
24+
.expect(format!("Unable to load config file: {}", test_config_path.display()).as_str());
9925
let output = nginx.restart().expect("Unable to restart NGINX");
10026
assert!(output.status.success());
10127

0 commit comments

Comments
 (0)