Skip to content
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

test: integration tests for example modules #95

Merged
merged 9 commits into from
Oct 30, 2024
Merged
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
66 changes: 25 additions & 41 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ name: Rust
on: [ push, pull_request ]

env:
CARGO_TERM_COLOR: always
CARGO_TERM_COLOR: 'always'
CARGO_TERM_VERBOSE: 'true'
RUSTDOCFLAGS: '-Dwarnings'

jobs:
test-linux:
Expand Down Expand Up @@ -36,8 +38,25 @@ jobs:
.cache/*.tar.sig
key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }}
restore-keys: ${{ runner.os }}-deps-
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: build
id: build
run: cargo build --workspace --all-targets --all-features

- name: run clippy
if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds
run: cargo clippy --workspace --all-targets --all-features -- -Dwarnings

- name: run tests
run: cargo test --verbose
if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds
run: cargo test --workspace --all-features

- name: rustdoc
if: ${{ !cancelled() && steps.build.outcome == 'success' }} # always run if build succeeds
run: cargo doc --no-deps

examples-linux:
name: Examples (Linux)
Expand Down Expand Up @@ -70,7 +89,7 @@ jobs:
key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }}
restore-keys: ${{ runner.os }}-deps-
- name: compile examples
run: cargo build --release --package examples --examples --verbose
run: cargo build --release --package examples --examples --all-features

test-macos:
name: Test (MacOS)
Expand Down Expand Up @@ -109,9 +128,9 @@ jobs:
- name: disable ipv6 for gpg
run: echo "disable-ipv6" > .cache/.gnupg/dirmngr.conf
- name: build
run: cargo build --verbose
run: cargo build
- name: run tests
run: cargo test --verbose
run: cargo test --workspace

fmt:
name: Rustfmt
Expand All @@ -124,39 +143,4 @@ jobs:
- name: rustfmt version
run: rustfmt --version
- name: cargo fmt
run: cargo fmt --all --verbose --check || true

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: set up cargo cache
uses: actions/cache@v4
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: set up nginx deps source cache
uses: actions/cache@v4
continue-on-error: false
with:
path: |
.cache/.gnupg
.cache/nginx
.cache/*.tar.gz
.cache/*.tar.asc
.cache/*.tar.sig
key: ${{ runner.os }}-deps-${{ hashFiles('**/nginx-sys/build.rs') }}
restore-keys: ${{ runner.os }}-deps-
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: run clippy
run: cargo clippy -- -D warnings
run: cargo fmt --all --check
96 changes: 96 additions & 0 deletions .github/workflows/nginx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: NGINX

on:
push:
branches:
- master
pull_request:

env:
CARGO_TERM_COLOR: 'always'
RUST_BACKTRACE: '1'
NGX_CONFIGURE: |
auto/configure
--with-compat
--with-debug
--with-http_realip_module
--with-http_ssl_module
--with-http_v2_module
--with-http_v3_module
--with-stream
--with-stream_realip_module
--with-stream_ssl_module
--with-threads

jobs:
test:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
module:
- static
- dynamic
nginx-ref:
# master
- stable-1.26

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
ref: ${{ matrix.nginx-ref }}
repository: 'nginx/nginx'
path: 'nginx'
- uses: actions/checkout@v4
with:
repository: 'nginx/nginx-tests'
path: 'nginx/tests'
sparse-checkout: |
lib

- uses: dtolnay/rust-toolchain@stable

- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
nginx/objs/ngx_rust_examples
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-

- name: Configure nginx with static modules
if: matrix.module == 'static'
working-directory: nginx
run: |
${NGX_CONFIGURE} \
--add-module=${{ github.workspace }}/examples

- name: Configure nginx with dynamic modules
if: matrix.module != 'static'
working-directory: nginx
env:
TEST_NGINX_GLOBALS: >-
load_module ${{ github.workspace }}/nginx/objs/ngx_http_awssigv4_module.so;
load_module ${{ github.workspace }}/nginx/objs/ngx_http_curl_module.so;
load_module ${{ github.workspace }}/nginx/objs/ngx_http_upstream_custom_module.so;
run: |
${NGX_CONFIGURE} \
--add-dynamic-module=${{ github.workspace }}/examples
echo "TEST_NGINX_GLOBALS=$TEST_NGINX_GLOBALS" >> $GITHUB_ENV

- name: Build nginx
working-directory: nginx
run: make -j$(nproc)

- name: Run tests
env:
TEST_NGINX_BINARY: ${{ github.workspace }}/nginx/objs/nginx
TEST_NGINX_MODULES: ${{ github.workspace }}/nginx/objs
run: |
prove -v -j$(nproc) -Inginx/tests/lib --state=save examples/t \
|| prove -v -Inginx/tests/lib --state=failed
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ keywords = ["nginx", "module", "sys"]
nginx-sys = { path = "nginx-sys", version = "0.5.0"}

[features]
default = ["vendored"]
# Build our own copy of the NGINX by default.
# This could be disabled with `--no-default-features` to minimize the dependency tree
# when building against an existing copy of the NGINX with the NGX_OBJS variable.
default = ["nginx-sys/vendored"]
vendored = ["nginx-sys/vendored"]

[badges]
maintenance = { status = "experimental" }
Expand Down
6 changes: 3 additions & 3 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ edition = "2021"
license = "Apache-2.0"

[dev-dependencies]
ngx = { path = "../" }
ngx = { path = "../", default-features = false }
aws-sign-v4 = "0.3.0"
chrono = "0.4.23"
http = "1.1.0"
libc = "0.2.140"
tokio = { version = "1.33.0", features = ["full"] }

[[example]]
name = "curl"
Expand Down Expand Up @@ -39,10 +40,9 @@ path = "async.rs"
crate-type = ["cdylib"]

[dependencies]
tokio = { version = "1.33.0", features = ["full"] }

[features]
default = ["export-modules"]
default = ["export-modules", "ngx/vendored"]
# Generate `ngx_modules` table with module exports
# The exports table is required for building loadable modules with --crate-type cdylib
# outside of the NGINX buildsystem. However, cargo currently does not detect
Expand Down
9 changes: 3 additions & 6 deletions examples/awssig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,9 @@ http_request_handler!(awssigv4_header_handler, |request: &mut Request| {
// Copy only headers that will be used to sign the request
let mut headers = HeaderMap::new();
for (name, value) in request.headers_in_iterator() {
match name.to_lowercase().as_str() {
"host" => {
headers.insert(http::header::HOST, value.parse().unwrap());
}
&_ => {}
};
if name.to_lowercase() == "host" {
headers.insert(http::header::HOST, value.parse().unwrap());
}
}
headers.insert("X-Amz-Date", datetime_now.parse().unwrap());
ngx_log_debug_http!(request, "headers {:?}", headers);
Expand Down
4 changes: 2 additions & 2 deletions examples/config
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ngx_cargo_profile=ngx-module
if [ $HTTP = YES ]; then
ngx_module_type=HTTP

if :; then
if [ "$ngx_module_link" = DYNAMIC ]; then
ngx_module_name=ngx_http_async_module
ngx_module_lib=async

Expand All @@ -24,7 +24,7 @@ if [ $HTTP = YES ]; then

ngx_module_lib=$NGX_OBJS/$ngx_addon_name/$ngx_cargo_profile/examples/lib$ngx_module_lib.a
ngx_module_deps=$ngx_module_lib
ngx_module_libs=$ngx_module_lib
ngx_module_libs="$ngx_module_lib -lm"

# Module deps are usually added to the object file targets, but we don't have any
LINK_DEPS="$LINK_DEPS $ngx_module_lib"
Expand Down
4 changes: 2 additions & 2 deletions examples/httporigdst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ ngx::ngx_modules!(ngx_http_orig_dst_module);
#[no_mangle]
#[used]
pub static mut ngx_http_orig_dst_module: ngx_module_t = ngx_module_t {
ctx_index: ngx_uint_t::max_value(),
index: ngx_uint_t::max_value(),
ctx_index: ngx_uint_t::MAX,
index: ngx_uint_t::MAX,
name: std::ptr::null_mut(),
spare0: 0,
spare1: 0,
Expand Down
73 changes: 73 additions & 0 deletions examples/t/awssig.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/perl

# (C) Nginx, Inc

# Tests for ngx-rust example modules.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(1)
->write_file_expand('nginx.conf', <<"EOF");

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
%%TEST_GLOBALS_HTTP%%

server {
listen 127.0.0.1:8080;
server_name localhost;

awssigv4_access_key my-access-key;
awssigv4_secret_key my-secret-key;
awssigv4_s3_bucket my-bucket;
awssigv4_s3_endpoint s3.example.com;

location / {
awssigv4 on;
proxy_pass http://127.0.0.1:8081;
}
}

server {
listen 127.0.0.1:8081;
server_name localhost;

add_header x-amz-date \$http_x_amz_date;
add_header x-authorization \$http_authorization;

location / { }
}
}

EOF

$t->write_file('index.html', '');
$t->run();

###############################################################################

like(http_get('/'), qr/x-authorization: AWS4.*Credential=my-access-key/i,
'awssig header');

###############################################################################
Loading
Loading