Skip to content

Commit fe1ca87

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 1b802cd commit fe1ca87

File tree

12 files changed

+528
-9
lines changed

12 files changed

+528
-9
lines changed

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
members = [
33
"nginx-src",
44
"nginx-sys",
5+
"nginx-unittest",
56
"examples",
67
]
78

@@ -40,7 +41,7 @@ targets = []
4041
allocator-api2 = { version = "0.3.1", default-features = false }
4142
async-task = { version = "4.7.1", optional = true }
4243
lock_api = "0.4.13"
43-
nginx-sys = { path = "nginx-sys", version = "0.5.0"}
44+
nginx-sys = { path = "nginx-sys", version = "0.5.0" }
4445
pin-project-lite = { version = "0.2.16", optional = true }
4546

4647
[features]
@@ -70,3 +71,7 @@ maintenance = { status = "experimental" }
7071

7172
[dev-dependencies]
7273
tempfile = { version = "3.20.0", default-features = false }
74+
75+
[target.'cfg(not(windows))'.dev-dependencies]
76+
nginx-sys = { path = "nginx-sys", version = "0.5.0", features = ["unittest"] }
77+
nginx-unittest = { path = "nginx-unittest", version = "0.1.0" }

nginx-src/libnginx/config

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

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: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
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, init_cycle;
31+
static ngx_atomic_t lock;
32+
33+
ngx_log_t *log;
34+
char *const argv[] = { "nginx" };
35+
36+
ngx_rwlock_wlock(&lock);
37+
38+
if (cycle != NULL) {
39+
ngx_rwlock_unlock(&lock);
40+
return cycle;
41+
}
42+
43+
ngx_conf_params = (u_char *) "daemon off; master_process off;";
44+
ngx_error_log = (u_char *) "";
45+
ngx_prefix = prefix;
46+
47+
ngx_debug_init();
48+
49+
if (ngx_strerror_init() != NGX_OK) {
50+
goto error;
51+
}
52+
53+
ngx_max_sockets = -1;
54+
55+
ngx_time_init();
56+
57+
#if (NGX_PCRE)
58+
ngx_regex_init();
59+
#endif
60+
61+
ngx_pid = ngx_getpid();
62+
ngx_parent = ngx_getppid();
63+
64+
log = ngx_log_init(ngx_prefix, ngx_error_log);
65+
if (log == NULL) {
66+
goto error;
67+
}
68+
69+
log->log_level = NGX_LOG_INFO;
70+
71+
#if (NGX_OPENSSL)
72+
ngx_ssl_init(log);
73+
#endif
74+
75+
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
76+
init_cycle.log = log;
77+
init_cycle.log_use_stderr = 1;
78+
ngx_cycle = &init_cycle;
79+
80+
init_cycle.pool = ngx_create_pool(1024, log);
81+
if (init_cycle.pool == NULL) {
82+
goto error;
83+
}
84+
85+
if (ngx_save_argv(&init_cycle, sizeof(argv)/sizeof(argv[0]), argv)
86+
!= NGX_OK)
87+
{
88+
goto error;
89+
}
90+
91+
if (ngx_process_options(&init_cycle) != NGX_OK) {
92+
goto error;
93+
}
94+
95+
if (ngx_os_init(log) != NGX_OK) {
96+
goto error;
97+
}
98+
99+
if (ngx_crc32_table_init() != NGX_OK) {
100+
goto error;
101+
}
102+
103+
ngx_slab_sizes_init();
104+
105+
if (ngx_preinit_modules() != NGX_OK) {
106+
goto error;
107+
}
108+
109+
cycle = &init_cycle;
110+
ngx_rwlock_unlock(&lock);
111+
return cycle;
112+
113+
error:
114+
ngx_rwlock_unlock(&lock);
115+
return NULL;
116+
}
117+
118+
119+
ngx_int_t
120+
libngx_create_cycle(ngx_cycle_t *cycle, ngx_str_t *conf)
121+
{
122+
ngx_str_t conf_file;
123+
124+
ngx_cycle = cycle;
125+
126+
if (libngx_write_temp_conf_file(cycle, conf, &conf_file) != NGX_OK) {
127+
return NGX_ERROR;
128+
}
129+
130+
ngx_conf_file = conf_file.data;
131+
132+
if (ngx_process_options(cycle) != NGX_OK) {
133+
return NGX_ERROR;
134+
}
135+
136+
cycle = ngx_init_cycle(cycle);
137+
if (cycle == NULL) {
138+
return NGX_ERROR;
139+
}
140+
141+
ngx_cycle = cycle;
142+
143+
return NGX_OK;
144+
}
145+
146+
147+
static ngx_int_t
148+
libngx_write_temp_conf_file(ngx_cycle_t *cycle, ngx_str_t *data,
149+
ngx_str_t *name)
150+
{
151+
ngx_int_t rc;
152+
ngx_path_t *path;
153+
ngx_temp_file_t tf;
154+
155+
path = ngx_pcalloc(cycle->pool, sizeof(ngx_path_t));
156+
if (path == NULL) {
157+
return NGX_ERROR;
158+
}
159+
160+
ngx_memzero(&tf, sizeof(ngx_temp_file_t));
161+
162+
tf.file.fd = NGX_INVALID_FILE;
163+
tf.file.log = cycle->log;
164+
tf.access = NGX_FILE_OWNER_ACCESS;
165+
tf.clean = 1;
166+
tf.path = path;
167+
tf.pool = cycle->pool;
168+
tf.persistent = 1;
169+
170+
ngx_str_set(&path->name, "conf");
171+
172+
rc = ngx_conf_full_name(cycle, &path->name, 0);
173+
if (rc != NGX_OK) {
174+
return rc;
175+
}
176+
177+
if (ngx_create_dir(path->name.data, ngx_dir_access(tf.access))
178+
== NGX_FILE_ERROR)
179+
{
180+
return ngx_errno;
181+
}
182+
183+
rc = ngx_create_temp_file(&tf.file, tf.path, tf.pool, tf.persistent,
184+
tf.clean, tf.access);
185+
if (rc != NGX_OK) {
186+
return rc;
187+
}
188+
189+
if (ngx_write_file(&tf.file, data->data, data->len, 0) == NGX_ERROR) {
190+
return NGX_ERROR;
191+
}
192+
193+
*name = tf.file.name;
194+
195+
return NGX_OK;
196+
}

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

116+
nginx_opts.push(format!(
117+
"--add-module={}/libnginx",
118+
env!("CARGO_MANIFEST_DIR")
119+
));
120+
116121
nginx_opts
117122
}
118123

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"]

0 commit comments

Comments
 (0)