Skip to content

test: Link unit tests with nginx library. #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ vendored = ["nginx-sys/vendored"]
maintenance = { status = "experimental" }

[dev-dependencies]
nginx-sys = { path = "nginx-sys", version = "0.5.0-beta", features = ["unittest"]}
tempfile = { version = "3.20.0", default-features = false }
4 changes: 4 additions & 0 deletions nginx-src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ homepage.workspace = true
repository.workspace = true
rust-version.workspace = true

[features]
# Builds nginx library from vendored sources for unit tests.
unittest = []

[dependencies]
duct = "1"
flate2 = "1"
Expand Down
5 changes: 5 additions & 0 deletions nginx-src/libnginx/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# Copyright (C) Nginx, Inc.


ngx_addon_name="libnginx"
73 changes: 73 additions & 0 deletions nginx-src/libnginx/config.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

# Copyright (C) Nginx, Inc.


ngx_addon_name=libnginx
ngx_module=$ngx_addon_name
ngx_module_c=$ngx_addon_dir/libnginx.c

ngx_ar="\$(AR)"
ngx_libext=.a
ngx_libout="r "

case "$NGX_CC_NAME" in

msvc)
ngx_ar=lib
ngx_libext=.lib
ngx_libout="/OUT:"
;;

esac

if test -n "$NGX_PCH"; then
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS)"
fi

ngx_module_objs=
for ngx_src in $ngx_module_c
do
ngx_obj="addon/`basename \`dirname $ngx_src\``"

test -d $NGX_OBJS/$ngx_obj || mkdir -p $NGX_OBJS/$ngx_obj

ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
| sed -e "s/\//$ngx_regex_dirsep/g" \
-e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g"`

ngx_module_objs="$ngx_module_objs $ngx_obj"

cat << END >> $NGX_MAKEFILE

$ngx_obj: \$(CORE_DEPS)$ngx_cont$ngx_src
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END

done

ngx_objs=`echo $ngx_module_objs $ngx_modules_obj $ngx_all_objs \
| sed -e "s/[^ ]*\\/nginx\\.$ngx_objext//g" \
-e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`

ngx_deps=`echo $ngx_module_objs $ngx_modules_obj $ngx_all_objs \
| sed -e "s/[^ ]*\\/nginx\\.$ngx_objext//g" \
-e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`

ngx_obj=$NGX_OBJS$ngx_dirsep$ngx_module$ngx_libext

cat << END >> $NGX_MAKEFILE

modules: $ngx_obj

$ngx_obj: $ngx_deps$ngx_spacer
$ngx_ar $ngx_long_start$ngx_libout$ngx_obj$ngx_long_cont$ngx_objs
$ngx_long_end

LIBNGINX_LDFLAGS = $NGX_LD_OPT $CORE_LIBS

END
187 changes: 187 additions & 0 deletions nginx-src/libnginx/libnginx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@

/*
* Copyright (C) Nginx, Inc.
*/


#include <ngx_config.h>
#include <ngx_core.h>
#include <nginx.h>

#include "libnginx.h"


/*
* We need to build nginx.c to correctly initialize ngx_core_module,
* but exclude an existing definition of main.
*/
#define main main_unused
#include "nginx.c"
#undef main


static ngx_int_t libngx_write_temp_conf_file(ngx_cycle_t *cycle,
ngx_str_t *data, ngx_str_t *name);


ngx_cycle_t *
libngx_init(u_char *prefix)
{
static ngx_cycle_t *cycle = NGX_CONF_UNSET_PTR, init_cycle;

ngx_log_t *log;
char *const argv[] = { "nginx" };

if (cycle != NGX_CONF_UNSET_PTR) {
return cycle;
}

cycle = NULL;

ngx_conf_params = (u_char *) "daemon off; master_process off;";
ngx_error_log = (u_char *) "";
ngx_prefix = prefix;

ngx_debug_init();

if (ngx_strerror_init() != NGX_OK) {
return cycle;
}

ngx_max_sockets = -1;

ngx_time_init();

#if (NGX_PCRE)
ngx_regex_init();
#endif

ngx_pid = ngx_getpid();
ngx_parent = ngx_getppid();

log = ngx_log_init(ngx_prefix, ngx_error_log);
if (log == NULL) {
return NULL;
}

log->log_level = NGX_LOG_INFO;

#if (NGX_OPENSSL)
ngx_ssl_init(log);
#endif

ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
init_cycle.log_use_stderr = 1;
ngx_cycle = &init_cycle;

init_cycle.pool = ngx_create_pool(1024, log);
if (init_cycle.pool == NULL) {
return NULL;
}

if (ngx_save_argv(&init_cycle, sizeof(argv)/sizeof(argv[0]), argv) != NGX_OK) {
return NULL;
}

if (ngx_process_options(&init_cycle) != NGX_OK) {
return NULL;
}

if (ngx_os_init(log) != NGX_OK) {
return NULL;
}

if (ngx_crc32_table_init() != NGX_OK) {
return NULL;
}

ngx_slab_sizes_init();

if (ngx_preinit_modules() != NGX_OK) {
return NULL;
}

cycle = &init_cycle;
return cycle;
}


ngx_int_t
libngx_create_cycle(ngx_cycle_t *cycle, ngx_str_t *conf)
{
ngx_str_t conf_file;

ngx_cycle = cycle;

if (libngx_write_temp_conf_file(cycle, conf, &conf_file) != NGX_OK) {
return NGX_ERROR;
}

ngx_conf_file = conf_file.data;

if (ngx_process_options(cycle) != NGX_OK) {
return NGX_ERROR;
}

cycle = ngx_init_cycle(cycle);
if (cycle == NULL) {
return NGX_ERROR;
}

ngx_cycle = cycle;

return NGX_OK;
}


static ngx_int_t
libngx_write_temp_conf_file(ngx_cycle_t *cycle, ngx_str_t *data,
ngx_str_t *name)
{
ngx_int_t rc;
ngx_path_t *path;
ngx_temp_file_t tf;

path = ngx_pcalloc(cycle->pool, sizeof(ngx_path_t));
if (path == NULL) {
return NGX_ERROR;
}

ngx_memzero(&tf, sizeof(ngx_temp_file_t));

tf.file.fd = NGX_INVALID_FILE;
tf.file.log = cycle->log;
tf.access = NGX_FILE_OWNER_ACCESS;
tf.clean = 1;
tf.path = path;
tf.pool = cycle->pool;
tf.persistent = 1;

ngx_str_set(&path->name, "conf");

rc = ngx_conf_full_name(cycle, &path->name, 0);
if (rc != NGX_OK) {
return rc;
}

if (ngx_create_dir(path->name.data, ngx_dir_access(tf.access))
== NGX_FILE_ERROR)
{
return ngx_errno;
}

rc = ngx_create_temp_file(&tf.file, tf.path, tf.pool, tf.persistent,
tf.clean, tf.access);
if (rc != NGX_OK) {
return rc;
}

if (ngx_write_file(&tf.file, data->data, data->len, 0) == NGX_ERROR) {
return NGX_ERROR;
}

*name = tf.file.name;

return NGX_OK;
}
14 changes: 14 additions & 0 deletions nginx-src/libnginx/libnginx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

/*
* Copyright (C) Nginx, Inc
*/


#ifndef _LIBNGINX_H_INCLUDED_
#define _LIBNGINX_H_INCLUDED_

ngx_cycle_t *libngx_init(u_char *prefix);
ngx_int_t libngx_create_cycle(ngx_cycle_t *cycle, ngx_str_t *conf);


#endif /* _LIBNGINX_H_INCLUDED_ */
6 changes: 6 additions & 0 deletions nginx-src/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ fn nginx_configure_flags(vendored: &[String]) -> Vec<String> {
nginx_opts.push(format!("--with-ld-opt={ldflags}"));
}

#[cfg(feature = "unittest")]
nginx_opts.push(format!(
"--add-dynamic-module={}/libnginx",
env!("CARGO_MANIFEST_DIR")
));

nginx_opts
}

Expand Down
1 change: 1 addition & 0 deletions nginx-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ shlex = "1.3"

[features]
vendored = ["dep:nginx-src"]
unittest = ["vendored", "nginx-src/unittest"]
Loading
Loading