Skip to content

Commit 05a67cb

Browse files
committed
test: Link unit tests with nginx library.
Some unit tests may use C functions from nginx. To support this scenario, special static library is built. Necessary linker flags are also added. Since these changes are needed for specific unit tests only, new feature "unittest" is defined.
1 parent 07ce1f7 commit 05a67cb

File tree

10 files changed

+481
-8
lines changed

10 files changed

+481
-8
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,5 @@ vendored = ["nginx-sys/vendored"]
6969
maintenance = { status = "experimental" }
7070

7171
[dev-dependencies]
72+
nginx-sys = { path = "nginx-sys", version = "0.5.0-beta", features = ["unittest"]}
7273
tempfile = { version = "3.20.0", default-features = false }

nginx-src/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ homepage.workspace = true
1212
repository.workspace = true
1313
rust-version.workspace = true
1414

15+
[features]
16+
# Builds nginx library from vendored sources for unit tests.
17+
unittest = []
18+
1519
[dependencies]
1620
duct = "1"
1721
flate2 = "1"

nginx-src/libnginx/config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
# Copyright (C) Nginx, Inc.
3+
4+
5+
ngx_addon_name="libnginx"

nginx-src/libnginx/config.make

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
# Copyright (C) Nginx, Inc.
3+
4+
5+
ngx_addon_name=libnginx
6+
ngx_module=$ngx_addon_name
7+
ngx_module_c=$ngx_addon_dir/libnginx.c
8+
9+
ngx_ar="\$(AR)"
10+
ngx_libext=.a
11+
ngx_libout="r "
12+
13+
case "$NGX_CC_NAME" in
14+
15+
msvc)
16+
ngx_ar=lib
17+
ngx_libext=.lib
18+
ngx_libout="/OUT:"
19+
;;
20+
21+
esac
22+
23+
if test -n "$NGX_PCH"; then
24+
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
25+
else
26+
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS)"
27+
fi
28+
29+
ngx_module_objs=
30+
for ngx_src in $ngx_module_c
31+
do
32+
ngx_obj="addon/`basename \`dirname $ngx_src\``"
33+
34+
test -d $NGX_OBJS/$ngx_obj || mkdir -p $NGX_OBJS/$ngx_obj
35+
36+
ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
37+
| sed -e "s/\//$ngx_regex_dirsep/g" \
38+
-e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g"`
39+
40+
ngx_module_objs="$ngx_module_objs $ngx_obj"
41+
42+
cat << END >> $NGX_MAKEFILE
43+
44+
$ngx_obj: \$(CORE_DEPS)$ngx_cont$ngx_src
45+
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
46+
47+
END
48+
49+
done
50+
51+
ngx_objs=`echo $ngx_module_objs $ngx_modules_obj $ngx_all_objs \
52+
| sed -e "s/[^ ]*\\/nginx\\.$ngx_objext//g" \
53+
-e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
54+
-e "s/\//$ngx_regex_dirsep/g"`
55+
56+
ngx_deps=`echo $ngx_module_objs $ngx_modules_obj $ngx_all_objs \
57+
| sed -e "s/[^ ]*\\/nginx\\.$ngx_objext//g" \
58+
-e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
59+
-e "s/\//$ngx_regex_dirsep/g"`
60+
61+
ngx_obj=$NGX_OBJS$ngx_dirsep$ngx_module$ngx_libext
62+
63+
cat << END >> $NGX_MAKEFILE
64+
65+
modules: $ngx_obj
66+
67+
$ngx_obj: $ngx_deps$ngx_spacer
68+
$ngx_ar $ngx_long_start$ngx_libout$ngx_obj$ngx_long_cont$ngx_objs
69+
$ngx_long_end
70+
71+
LIBNGINX_LDFLAGS = $NGX_LD_OPT $CORE_LIBS
72+
73+
END

nginx-src/libnginx/libnginx.c

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
2+
/*
3+
* Copyright (C) Nginx, Inc.
4+
*/
5+
6+
7+
#include <ngx_config.h>
8+
#include <ngx_core.h>
9+
#include <nginx.h>
10+
11+
#include "libnginx.h"
12+
13+
14+
/*
15+
* We need to build nginx.c to correctly initialize ngx_core_module,
16+
* but exclude an existing definition of main.
17+
*/
18+
#define main main_unused
19+
#include "nginx.c"
20+
#undef main
21+
22+
23+
static ngx_int_t libngx_write_temp_conf_file(ngx_cycle_t *cycle,
24+
ngx_str_t *data, ngx_str_t *name);
25+
26+
27+
ngx_cycle_t *
28+
libngx_init(u_char *prefix)
29+
{
30+
static ngx_cycle_t *cycle = NGX_CONF_UNSET_PTR, init_cycle;
31+
32+
ngx_log_t *log;
33+
char *const argv[] = { "nginx" };
34+
35+
if (cycle != NGX_CONF_UNSET_PTR) {
36+
return cycle;
37+
}
38+
39+
cycle = NULL;
40+
41+
ngx_conf_params = (u_char *) "daemon off; master_process off;";
42+
ngx_error_log = (u_char *) "";
43+
ngx_prefix = prefix;
44+
45+
ngx_debug_init();
46+
47+
if (ngx_strerror_init() != NGX_OK) {
48+
return cycle;
49+
}
50+
51+
ngx_max_sockets = -1;
52+
53+
ngx_time_init();
54+
55+
#if (NGX_PCRE)
56+
ngx_regex_init();
57+
#endif
58+
59+
ngx_pid = ngx_getpid();
60+
ngx_parent = ngx_getppid();
61+
62+
log = ngx_log_init(ngx_prefix, ngx_error_log);
63+
if (log == NULL) {
64+
return NULL;
65+
}
66+
67+
log->log_level = NGX_LOG_INFO;
68+
69+
#if (NGX_OPENSSL)
70+
ngx_ssl_init(log);
71+
#endif
72+
73+
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
74+
init_cycle.log = log;
75+
init_cycle.log_use_stderr = 1;
76+
ngx_cycle = &init_cycle;
77+
78+
init_cycle.pool = ngx_create_pool(1024, log);
79+
if (init_cycle.pool == NULL) {
80+
return NULL;
81+
}
82+
83+
if (ngx_save_argv(&init_cycle, sizeof(argv)/sizeof(argv[0]), argv) != NGX_OK) {
84+
return NULL;
85+
}
86+
87+
if (ngx_process_options(&init_cycle) != NGX_OK) {
88+
return NULL;
89+
}
90+
91+
if (ngx_os_init(log) != NGX_OK) {
92+
return NULL;
93+
}
94+
95+
if (ngx_crc32_table_init() != NGX_OK) {
96+
return NULL;
97+
}
98+
99+
ngx_slab_sizes_init();
100+
101+
if (ngx_preinit_modules() != NGX_OK) {
102+
return NULL;
103+
}
104+
105+
cycle = &init_cycle;
106+
return cycle;
107+
}
108+
109+
110+
ngx_int_t
111+
libngx_create_cycle(ngx_cycle_t *cycle, ngx_str_t *conf)
112+
{
113+
ngx_str_t conf_file;
114+
115+
ngx_cycle = cycle;
116+
117+
if (libngx_write_temp_conf_file(cycle, conf, &conf_file) != NGX_OK) {
118+
return NGX_ERROR;
119+
}
120+
121+
ngx_conf_file = conf_file.data;
122+
123+
if (ngx_process_options(cycle) != NGX_OK) {
124+
return NGX_ERROR;
125+
}
126+
127+
cycle = ngx_init_cycle(cycle);
128+
if (cycle == NULL) {
129+
return NGX_ERROR;
130+
}
131+
132+
ngx_cycle = cycle;
133+
134+
return NGX_OK;
135+
}
136+
137+
138+
static ngx_int_t
139+
libngx_write_temp_conf_file(ngx_cycle_t *cycle, ngx_str_t *data,
140+
ngx_str_t *name)
141+
{
142+
ngx_int_t rc;
143+
ngx_path_t *path;
144+
ngx_temp_file_t tf;
145+
146+
path = ngx_pcalloc(cycle->pool, sizeof(ngx_path_t));
147+
if (path == NULL) {
148+
return NGX_ERROR;
149+
}
150+
151+
ngx_memzero(&tf, sizeof(ngx_temp_file_t));
152+
153+
tf.file.fd = NGX_INVALID_FILE;
154+
tf.file.log = cycle->log;
155+
tf.access = NGX_FILE_OWNER_ACCESS;
156+
tf.clean = 1;
157+
tf.path = path;
158+
tf.pool = cycle->pool;
159+
tf.persistent = 1;
160+
161+
ngx_str_set(&path->name, "conf");
162+
163+
rc = ngx_conf_full_name(cycle, &path->name, 0);
164+
if (rc != NGX_OK) {
165+
return rc;
166+
}
167+
168+
if (ngx_create_dir(path->name.data, ngx_dir_access(tf.access))
169+
== NGX_FILE_ERROR)
170+
{
171+
return ngx_errno;
172+
}
173+
174+
rc = ngx_create_temp_file(&tf.file, tf.path, tf.pool, tf.persistent,
175+
tf.clean, tf.access);
176+
if (rc != NGX_OK) {
177+
return rc;
178+
}
179+
180+
if (ngx_write_file(&tf.file, data->data, data->len, 0) == NGX_ERROR) {
181+
return NGX_ERROR;
182+
}
183+
184+
*name = tf.file.name;
185+
186+
return NGX_OK;
187+
}

nginx-src/libnginx/libnginx.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
/*
3+
* Copyright (C) Nginx, Inc
4+
*/
5+
6+
7+
#ifndef _LIBNGINX_H_INCLUDED_
8+
#define _LIBNGINX_H_INCLUDED_
9+
10+
ngx_cycle_t *libngx_init(u_char *prefix);
11+
ngx_int_t libngx_create_cycle(ngx_cycle_t *cycle, ngx_str_t *conf);
12+
13+
14+
#endif /* _LIBNGINX_H_INCLUDED_ */

nginx-src/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ fn nginx_configure_flags(vendored: &[String]) -> Vec<String> {
113113
nginx_opts.push(format!("--with-ld-opt={ldflags}"));
114114
}
115115

116+
#[cfg(feature = "unittest")]
117+
nginx_opts.push(format!(
118+
"--add-dynamic-module={}/libnginx",
119+
env!("CARGO_MANIFEST_DIR")
120+
));
121+
116122
nginx_opts
117123
}
118124

nginx-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ shlex = "1.3"
3434

3535
[features]
3636
vendored = ["dep:nginx-src"]
37+
unittest = ["vendored", "nginx-src/unittest"]

0 commit comments

Comments
 (0)