#!/usr/bin/perl # (C) Dmitry Volyntsev # (C) Nginx, Inc. # Async tests for http njs module. ############################################################################### 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 rewrite/) ->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% daemon off; events { } http { %%TEST_GLOBALS_HTTP%% js_set $test_async test.set_timeout; js_set $context_var test.context_var; js_set $test_set_rv_var test.set_rv_var; js_import test.js; server { listen 127.0.0.1:8080; server_name localhost; location /njs { js_content test.njs; } location /async_var { return 200 $test_async; } location /shared_ctx { add_header H $context_var; js_content test.shared_ctx; } location /set_timeout { js_content test.set_timeout; } location /set_timeout_many { js_content test.set_timeout_many; } location /set_timeout_data { postpone_output 0; js_content test.set_timeout_data; } location /limit_rate { postpone_output 0; sendfile_max_chunk 5; js_content test.limit_rate; } location /async_content { js_content test.async_content; } location /set_rv_var { return 200 $test_set_rv_var; } location /await_reject { js_content test.await_reject; } } } EOF $t->write_file('test.js', < {resolve(x)}).then(v => v).then(v => v); } async function async_content(r) { const a1 = await pr('A'); const a2 = await pr('B'); r.return(200, `retval: \${a1 + a2}`); } async function set_rv_var(r) { const a1 = await pr(10); const a2 = await pr(20); r.setReturnValue(`retval: \${a1 + a2}`); } async function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => { reject(new Error('timeout')); }, ms); }); } async function await_reject(r) { let v = await timeout(1); r.return(200); } export default {njs:test_njs, set_timeout, set_timeout_data, set_timeout_many, context_var, shared_ctx, limit_rate, async_content, set_rv_var, await_reject}; EOF $t->try_run('no njs available')->plan(10); ############################################################################### like(http_get('/set_timeout'), qr/Content-Type: foo/, 'setTimeout'); like(http_get('/set_timeout_many'), qr/Content-Type: reply/, 'setTimeout many'); like(http_get('/set_timeout_data'), qr/123456789/, 'setTimeout data'); like(http_get('/shared_ctx?a=xxx'), qr/H: xxx/, 'shared context'); like(http_get('/limit_rate'), qr/A{50}/, 'limit_rate'); like(http_get('/async_content'), qr/retval: AB/, 'async content'); like(http_get('/set_rv_var'), qr/retval: 30/, 'set return value variable'); http_get('/async_var'); http_get('/await_reject'); $t->stop(); ok(index($t->read_file('error.log'), 'pending events') > 0, 'pending js events'); ok(index($t->read_file('error.log'), 'async operation inside') > 0, 'async op in var handler'); ok(index($t->read_file('error.log'), 'js unhandled rejection') > 0, 'unhandled rejection'); ###############################################################################