details: https://github.com/nginx/njs/commit/89634204c4b12f17bbec826768d0d4e9dc5fae6c branches: master commit: 89634204c4b12f17bbec826768d0d4e9dc5fae6c user: Dmitry Volyntsev <xei...@nginx.com> date: Tue, 18 Feb 2025 22:53:54 -0800 description: Tests: splitting js_periodic tests into multiple files.
--- nginx/t/js_periodic.t | 92 +---------------- nginx/t/js_periodic_fetch.t | 138 +++++++++++++++++++++++++ nginx/t/js_periodic_file.t | 91 +++++++++++++++++ nginx/t/stream_js_periodic.t | 103 +------------------ nginx/t/stream_js_periodic_fetch.t | 201 +++++++++++++++++++++++++++++++++++++ nginx/t/stream_js_periodic_file.t | 144 ++++++++++++++++++++++++++ 6 files changed, 580 insertions(+), 189 deletions(-) diff --git a/nginx/t/js_periodic.t b/nginx/t/js_periodic.t index 63afe379..d6868935 100644 --- a/nginx/t/js_periodic.t +++ b/nginx/t/js_periodic.t @@ -59,46 +59,18 @@ http { js_periodic test.tick interval=30ms jitter=1ms; js_periodic test.timer interval=1s worker_affinity=all; js_periodic test.overrun interval=30ms; - js_periodic test.file interval=1s; - js_periodic test.fetch interval=40ms; - js_periodic test.multiple_fetches interval=1s; js_periodic test.affinity interval=50ms worker_affinity=0101; js_periodic test.vars interval=10s; - js_periodic test.fetch_exception interval=1s; js_periodic test.tick_exception interval=1s; js_periodic test.timer_exception interval=1s; js_periodic test.timeout_exception interval=30ms; } - location /engine { - js_content test.engine; - } - - location /fetch_ok { - return 200 'ok'; - } - - location /fetch_foo { - return 200 'foo'; - } - location /test_affinity { js_content test.test_affinity; } - location /test_fetch { - js_content test.test_fetch; - } - - location /test_file { - js_content test.test_file; - } - - location /test_multiple_fetches { - js_content test.test_multiple_fetches; - } - location /test_tick { js_content test.test_tick; } @@ -119,51 +91,15 @@ http { EOF -my $p0 = port(8080); - $t->write_file('test.js', <<EOF); - import fs from 'fs'; - - function engine(r) { - r.return(200, njs.engine); - } - function affinity() { ngx.shared.workers.set(ngx.worker_id, 1); } - async function fetch() { - let reply = await ngx.fetch('http://127.0.0.1:$p0/fetch_ok'); - let body = await reply.text(); - - let v = ngx.shared.strings.get('fetch') || ''; - ngx.shared.strings.set('fetch', v + body); - } - function js_set() { return 'JS-SET'; } - async function multiple_fetches() { - let reply = await ngx.fetch('http://127.0.0.1:$p0/fetch_ok'); - let reply2 = await ngx.fetch('http://127.0.0.1:$p0/fetch_foo'); - let body = await reply.text(); - let body2 = await reply2.text(); - - ngx.shared.strings.set('multiple_fetches', body + '\@' + body2); - } - - async function fetch_exception() { - let reply = await ngx.fetch('garbage'); - } - - async function file() { - let fh = await fs.promises.open(ngx.conf_prefix + 'file', 'a+'); - - await fh.write('abc'); - await fh.close(); - } - async function overrun() { setTimeout(() => {}, 100000); } @@ -214,20 +150,6 @@ $t->write_file('test.js', <<EOF); r.return(200, `[\${ngx.shared.workers.keys().toSorted()}]`); } - function test_fetch(r) { - r.return(200, ngx.shared.strings.get('fetch').startsWith('okok')); - } - - function test_file(r) { - r.return(200, - fs.readFileSync(ngx.conf_prefix + 'file').toString() == 'abc'); - } - - function test_multiple_fetches(r) { - r.return(200, ngx.shared.strings.get('multiple_fetches') - .startsWith('ok\@foo')); - } - function test_tick(r) { r.return(200, ngx.shared.nums.get('tick') >= 3); } @@ -244,19 +166,14 @@ $t->write_file('test.js', <<EOF); r.return(200, ngx.shared.strings.get('vars')); } - export default { affinity, fetch, fetch_exception, file, js_set, - multiple_fetches, overrun, vars, test_affinity, test_fetch, - test_file, test_multiple_fetches, test_tick, + export default { affinity, js_set, overrun, vars, test_affinity, test_tick, test_timeout_exception, test_timer, test_vars, tick, - tick_exception, timer, timer_exception, - timeout_exception, engine }; + tick_exception, timer, timer_exception, timeout_exception }; EOF $t->try_run('no js_periodic'); -plan(skip_all => 'not yet') if http_get('/engine') =~ /QuickJS$/m; - -$t->plan(9); +$t->plan(6); ############################################################################### @@ -265,9 +182,6 @@ select undef, undef, undef, 0.1; like(http_get('/test_affinity'), qr/\[1,3]/, 'affinity test'); like(http_get('/test_tick'), qr/true/, '3x tick test'); like(http_get('/test_timer'), qr/true/, 'timer test'); -like(http_get('/test_file'), qr/true/, 'file test'); -like(http_get('/test_fetch'), qr/true/, 'periodic fetch test'); -like(http_get('/test_multiple_fetches'), qr/true/, 'multiple fetch test'); like(http_get('/test_timeout_exception'), qr/true/, 'timeout exception test'); like(http_get('/test_vars'), qr/JS-VAR\|JS-SET\|MAP-VAR/, 'vars test'); diff --git a/nginx/t/js_periodic_fetch.t b/nginx/t/js_periodic_fetch.t new file mode 100644 index 00000000..d7bcfb76 --- /dev/null +++ b/nginx/t/js_periodic_fetch.t @@ -0,0 +1,138 @@ +#!/usr/bin/perl + +# (C) Dmitry Volyntsev +# (C) Nginx, Inc. + +# Tests for js_periodic directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use Socket qw/ CRLF /; + +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 rewrite/) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; +worker_processes 4; + +events { +} + +worker_shutdown_timeout 100ms; + +http { + %%TEST_GLOBALS_HTTP%% + + js_import test.js; + + js_shared_dict_zone zone=strings:32k; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location @periodic { + js_periodic test.fetch interval=40ms; + js_periodic test.multiple_fetches interval=1s; + + js_periodic test.fetch_exception interval=1s; + } + + location /engine { + js_content test.engine; + } + + location /fetch_ok { + return 200 'ok'; + } + + location /fetch_foo { + return 200 'foo'; + } + + location /test_fetch { + js_content test.test_fetch; + } + + location /test_multiple_fetches { + js_content test.test_multiple_fetches; + } + } +} + +EOF + +my $p0 = port(8080); + +$t->write_file('test.js', <<EOF); + function engine(r) { + r.return(200, njs.engine); + } + + async function fetch() { + let reply = await ngx.fetch('http://127.0.0.1:$p0/fetch_ok'); + let body = await reply.text(); + + let v = ngx.shared.strings.get('fetch') || ''; + ngx.shared.strings.set('fetch', v + body); + } + + async function multiple_fetches() { + let reply = await ngx.fetch('http://127.0.0.1:$p0/fetch_ok'); + let reply2 = await ngx.fetch('http://127.0.0.1:$p0/fetch_foo'); + let body = await reply.text(); + let body2 = await reply2.text(); + + ngx.shared.strings.set('multiple_fetches', body + '\@' + body2); + } + + async function fetch_exception() { + let reply = await ngx.fetch('garbage'); + } + + function test_fetch(r) { + r.return(200, ngx.shared.strings.get('fetch').startsWith('okok')); + } + + function test_multiple_fetches(r) { + r.return(200, ngx.shared.strings.get('multiple_fetches') + .startsWith('ok\@foo')); + } + + export default { fetch, fetch_exception, multiple_fetches, test_fetch, + test_multiple_fetches, engine }; +EOF + +$t->try_run('no js_periodic with fetch'); + +plan(skip_all => 'not yet') if http_get('/engine') =~ /QuickJS$/m; + +$t->plan(3); + +############################################################################### + +select undef, undef, undef, 0.1; + +like(http_get('/test_fetch'), qr/true/, 'periodic fetch test'); +like(http_get('/test_multiple_fetches'), qr/true/, 'multiple fetch test'); + +$t->stop(); + +unlike($t->read_file('error.log'), qr/\[error\].*should not be seen/, + 'check for not discadred events'); diff --git a/nginx/t/js_periodic_file.t b/nginx/t/js_periodic_file.t new file mode 100644 index 00000000..e8eb3070 --- /dev/null +++ b/nginx/t/js_periodic_file.t @@ -0,0 +1,91 @@ +#!/usr/bin/perl + +# (C) Dmitry Volyntsev +# (C) Nginx, Inc. + +# Tests for js_periodic directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use Socket qw/ CRLF /; + +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 rewrite/) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; +worker_processes 4; + +events { +} + +worker_shutdown_timeout 100ms; + +http { + %%TEST_GLOBALS_HTTP%% + + js_import test.js; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location @periodic { + js_periodic test.file interval=1s; + } + + location /test_file { + js_content test.test_file; + } + } +} + +EOF + +$t->write_file('test.js', <<EOF); + import fs from 'fs'; + + async function file() { + let fh = await fs.promises.open(ngx.conf_prefix + 'file', 'a+'); + + await fh.write('abc'); + await fh.close(); + } + + function test_file(r) { + r.return(200, + fs.readFileSync(ngx.conf_prefix + 'file').toString() == 'abc'); + } + + export default { file, test_file }; +EOF + +$t->try_run('no js_periodic with fs support'); + +$t->plan(2); + +############################################################################### + +select undef, undef, undef, 0.1; + +like(http_get('/test_file'), qr/true/, 'file test'); + +$t->stop(); + +unlike($t->read_file('error.log'), qr/\[error\].*should not be seen/, + 'check for not discadred events'); diff --git a/nginx/t/stream_js_periodic.t b/nginx/t/stream_js_periodic.t index 4b9e319b..ac64045e 100644 --- a/nginx/t/stream_js_periodic.t +++ b/nginx/t/stream_js_periodic.t @@ -58,13 +58,9 @@ stream { js_periodic test.tick interval=30ms jitter=1ms; js_periodic test.timer interval=1s worker_affinity=all; js_periodic test.overrun interval=30ms; - js_periodic test.file interval=1s; - js_periodic test.fetch interval=40ms; - js_periodic test.multiple_fetches interval=1s; js_periodic test.affinity interval=50ms worker_affinity=0101; js_periodic test.vars interval=10s; - js_periodic test.fetch_exception interval=1s; js_periodic test.tick_exception interval=1s; js_periodic test.timer_exception interval=1s; js_periodic test.timeout_exception interval=30ms; @@ -75,76 +71,17 @@ stream { } } -http { - %%TEST_GLOBALS_HTTP%% - - js_import test.js; - - server { - listen 127.0.0.1:8080; - server_name localhost; - - location /engine { - js_content test.engine; - } - - location /fetch_ok { - return 200 'ok'; - } - - location /fetch_foo { - return 200 'foo'; - } - } -} - EOF -my $p1 = port(8080); - $t->write_file('test.js', <<EOF); - import fs from 'fs'; - - function engine(r) { - r.return(200, njs.engine); - } - function affinity() { ngx.shared.workers.set(ngx.worker_id, 1); } - async function fetch() { - let reply = await ngx.fetch('http://127.0.0.1:$p1/fetch_ok'); - let body = await reply.text(); - - let v = ngx.shared.strings.get('fetch') || ''; - ngx.shared.strings.set('fetch', v + body); - } - - async function fetch_exception() { - let reply = await ngx.fetch('garbage'); - } - function js_set() { return 'JS-SET'; } - async function multiple_fetches() { - let reply = await ngx.fetch('http://127.0.0.1:$p1/fetch_ok'); - let reply2 = await ngx.fetch('http://127.0.0.1:$p1/fetch_foo'); - let body = await reply.text(); - let body2 = await reply2.text(); - - ngx.shared.strings.set('multiple_fetches', body + '\@' + body2); - } - - async function file() { - let fh = await fs.promises.open(ngx.conf_prefix + 'file', 'a+'); - - await fh.write('abc'); - await fh.close(); - } - async function overrun() { setTimeout(() => {}, 100000); } @@ -202,34 +139,6 @@ $t->write_file('test.js', <<EOF); return; } - break; - case 'fetch': - if (ngx.shared.strings.get('fetch').startsWith('okok')) { - s.done(); - return; - } - - break; - - case 'multiple_fetches': - if (ngx.shared.strings.get('multiple_fetches') - .startsWith('ok\@foo')) - { - s.done(); - return; - } - - break; - - case 'file': - let file_data = fs.readFileSync(ngx.conf_prefix + 'file') - .toString(); - - if (file_data == 'abc') { - s.done(); - return; - } - break; case 'tick': @@ -274,15 +183,13 @@ $t->write_file('test.js', <<EOF); }); } - export default { affinity, fetch, fetch_exception, js_set, multiple_fetches, - file, overrun, test, tick, tick_exception, timer, - timer_exception, timeout_exception, vars, engine }; + export default { affinity, js_set, overrun, test, tick, tick_exception, + timer, timer_exception, timeout_exception, vars }; EOF $t->run_daemon(\&stream_daemon, port(8090)); $t->try_run('no js_periodic'); -plan(skip_all => 'not yet') if http_get('/engine') =~ /QuickJS$/m; -$t->plan(9); +$t->plan(6); $t->waitforsocket('127.0.0.1:' . port(8090)); ############################################################################### @@ -293,10 +200,6 @@ is(stream('127.0.0.1:' . port(8081))->io('affinity'), 'affinity', 'affinity test'); is(stream('127.0.0.1:' . port(8081))->io('tick'), 'tick', '3x tick test'); is(stream('127.0.0.1:' . port(8081))->io('timer'), 'timer', 'timer test'); -is(stream('127.0.0.1:' . port(8081))->io('file'), 'file', 'file test'); -is(stream('127.0.0.1:' . port(8081))->io('fetch'), 'fetch', 'fetch test'); -is(stream('127.0.0.1:' . port(8081))->io('multiple_fetches'), - 'multiple_fetches', 'muliple fetches test'); is(stream('127.0.0.1:' . port(8081))->io('timeout_exception'), 'timeout_exception', 'timeout exception test'); is(stream('127.0.0.1:' . port(8081))->io('vars'), 'vars', 'vars test'); diff --git a/nginx/t/stream_js_periodic_fetch.t b/nginx/t/stream_js_periodic_fetch.t new file mode 100644 index 00000000..e88d69d5 --- /dev/null +++ b/nginx/t/stream_js_periodic_fetch.t @@ -0,0 +1,201 @@ +#!/usr/bin/perl + +# (C) Dmitry Volyntsev +# (C) Nginx, Inc. + +# Tests for stream njs module, js_periodic directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::Stream qw/ stream /; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite stream/) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; +worker_processes 4; + +events { +} + +worker_shutdown_timeout 100ms; + +stream { + %%TEST_GLOBALS_STREAM%% + + js_import test.js; + + js_shared_dict_zone zone=strings:32k; + + server { + listen 127.0.0.1:8081; + + js_periodic test.fetch interval=40ms; + js_periodic test.multiple_fetches interval=1s; + + js_periodic test.fetch_exception interval=1s; + + js_preread test.test; + + proxy_pass 127.0.0.1:8090; + } +} + +http { + %%TEST_GLOBALS_HTTP%% + + js_import test.js; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /engine { + js_content test.engine; + } + + location /fetch_ok { + return 200 'ok'; + } + + location /fetch_foo { + return 200 'foo'; + } + } +} + +EOF + +my $p1 = port(8080); + +$t->write_file('test.js', <<EOF); + function engine(r) { + r.return(200, njs.engine); + } + + async function fetch() { + let reply = await ngx.fetch('http://127.0.0.1:$p1/fetch_ok'); + let body = await reply.text(); + + let v = ngx.shared.strings.get('fetch') || ''; + ngx.shared.strings.set('fetch', v + body); + } + + async function fetch_exception() { + let reply = await ngx.fetch('garbage'); + } + + async function multiple_fetches() { + let reply = await ngx.fetch('http://127.0.0.1:$p1/fetch_ok'); + let reply2 = await ngx.fetch('http://127.0.0.1:$p1/fetch_foo'); + let body = await reply.text(); + let body2 = await reply2.text(); + + ngx.shared.strings.set('multiple_fetches', body + '\@' + body2); + } + + function test(s) { + s.on('upload', function (data) { + if (data.length > 0) { + switch (data) { + case 'fetch': + if (ngx.shared.strings.get('fetch').startsWith('okok')) { + s.done(); + return; + } + + break; + + case 'multiple_fetches': + if (ngx.shared.strings.get('multiple_fetches') + .startsWith('ok\@foo')) + { + s.done(); + return; + } + + break; + + default: + throw new Error(`Unknown test "\${data}"`); + } + + throw new Error(`Test "\${data}" failed`); + } + }); + } + + export default { engine, fetch, fetch_exception, test, multiple_fetches }; +EOF + +$t->run_daemon(\&stream_daemon, port(8090)); +$t->try_run('no js_periodic with fetch'); +plan(skip_all => 'not yet') if http_get('/engine') =~ /QuickJS$/m; +$t->plan(3); +$t->waitforsocket('127.0.0.1:' . port(8090)); + +############################################################################### + +select undef, undef, undef, 0.2; + +is(stream('127.0.0.1:' . port(8081))->io('fetch'), 'fetch', 'fetch test'); +is(stream('127.0.0.1:' . port(8081))->io('multiple_fetches'), + 'multiple_fetches', 'muliple fetches test'); + +$t->stop(); + +unlike($t->read_file('error.log'), qr/\[error\].*should not be seen/, + 'check for not discadred events'); + +############################################################################### + +sub stream_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:' . port(8090), + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + local $SIG{PIPE} = 'IGNORE'; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + log2c("(new connection $client)"); + + $client->sysread(my $buffer, 65536) or next; + + log2i("$client $buffer"); + + log2o("$client $buffer"); + + $client->syswrite($buffer); + + close $client; + } +} + +sub log2i { Test::Nginx::log_core('|| <<', @_); } +sub log2o { Test::Nginx::log_core('|| >>', @_); } +sub log2c { Test::Nginx::log_core('||', @_); } + +############################################################################### diff --git a/nginx/t/stream_js_periodic_file.t b/nginx/t/stream_js_periodic_file.t new file mode 100644 index 00000000..b41ce04c --- /dev/null +++ b/nginx/t/stream_js_periodic_file.t @@ -0,0 +1,144 @@ +#!/usr/bin/perl + +# (C) Dmitry Volyntsev +# (C) Nginx, Inc. + +# Tests for stream njs module, js_periodic directive. + +############################################################################### + +use warnings; +use strict; + +use Test::More; +use Socket qw/ CRLF /; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; +use Test::Nginx::Stream qw/ stream /; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +my $t = Test::Nginx->new()->has(qw/http rewrite stream/) + ->write_file_expand('nginx.conf', <<'EOF'); + +%%TEST_GLOBALS%% + +daemon off; +worker_processes 4; + +events { +} + +worker_shutdown_timeout 100ms; + +stream { + %%TEST_GLOBALS_STREAM%% + + js_import test.js; + + server { + listen 127.0.0.1:8081; + js_periodic test.file interval=1s; + + js_preread test.test; + + proxy_pass 127.0.0.1:8090; + } +} + +EOF + +$t->write_file('test.js', <<EOF); + import fs from 'fs'; + + async function file() { + let fh = await fs.promises.open(ngx.conf_prefix + 'file', 'a+'); + + await fh.write('abc'); + await fh.close(); + } + + function test(s) { + s.on('upload', function (data) { + if (data.length > 0) { + switch (data) { + case 'file': + let file_data = fs.readFileSync(ngx.conf_prefix + 'file') + .toString(); + + if (file_data == 'abc') { + s.done(); + return; + } + + break; + + default: + throw new Error(`Unknown test "\${data}"`); + } + + throw new Error(`Test "\${data}" failed`); + } + }); + } + + export default { file, test }; +EOF + +$t->run_daemon(\&stream_daemon, port(8090)); +$t->try_run('no js_periodic with fs support'); +$t->plan(2); +$t->waitforsocket('127.0.0.1:' . port(8090)); + +############################################################################### + +select undef, undef, undef, 0.2; + +is(stream('127.0.0.1:' . port(8081))->io('file'), 'file', 'file test'); + +$t->stop(); + +unlike($t->read_file('error.log'), qr/\[error\].*should not be seen/, + 'check for not discadred events'); + +############################################################################### + +sub stream_daemon { + my $server = IO::Socket::INET->new( + Proto => 'tcp', + LocalAddr => '127.0.0.1:' . port(8090), + Listen => 5, + Reuse => 1 + ) + or die "Can't create listening socket: $!\n"; + + local $SIG{PIPE} = 'IGNORE'; + + while (my $client = $server->accept()) { + $client->autoflush(1); + + log2c("(new connection $client)"); + + $client->sysread(my $buffer, 65536) or next; + + log2i("$client $buffer"); + + log2o("$client $buffer"); + + $client->syswrite($buffer); + + close $client; + } +} + +sub log2i { Test::Nginx::log_core('|| <<', @_); } +sub log2o { Test::Nginx::log_core('|| >>', @_); } +sub log2c { Test::Nginx::log_core('||', @_); } + +############################################################################### _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel