changeset 1374:fd7766ab0a69

Tests: stream njs module refactored.
author Dmitry Volyntsev <xeioex@nginx.com>
date Tue, 11 Sep 2018 14:45:23 +0300
parents 0569baf0cc4a
children f168fc46c7a4
files stream_js.t
diffstat 1 files changed, 249 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/stream_js.t
+++ b/stream_js.t
@@ -1,6 +1,7 @@
 #!/usr/bin/perl
 
 # (C) Andrey Zelenkov
+# (C) Dmitry Volyntsev
 # (C) Nginx, Inc.
 
 # Tests for stream JavaScript module.
@@ -23,7 +24,7 @@ use Test::Nginx::Stream qw/ dgram stream
 select STDERR; $| = 1;
 select STDOUT; $| = 1;
 
-my $t = Test::Nginx->new()->has(qw/stream stream_return udp/)
+my $t = Test::Nginx->new()->has(qw/http proxy rewrite stream stream_return udp/)
 	->write_file_expand('nginx.conf', <<'EOF');
 
 %%TEST_GLOBALS%%
@@ -33,11 +34,36 @@ daemon off;
 events {
 }
 
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    js_include test.js;
+
+    server {
+        listen       127.0.0.1:8079;
+        server_name  localhost;
+
+        location /njs {
+            js_content test_njs;
+        }
+
+        location /p/ {
+            proxy_pass http://127.0.0.1:8095/;
+
+        }
+
+        location /return {
+            return 200 $http_foo;
+        }
+    }
+}
+
 stream {
     js_set $js_addr      js_addr;
     js_set $js_var       js_var;
     js_set $js_log       js_log;
     js_set $js_unk       js_unk;
+    js_set $js_req_line  js_req_line;
     js_set $js_sess_unk  js_sess_unk;
 
     js_include test.js;
@@ -74,30 +100,6 @@ stream {
 
     server {
         listen      127.0.0.1:8086;
-        js_access   js_access_allow;
-        return      'OK';
-    }
-
-    server {
-        listen      127.0.0.1:8087;
-        js_access   js_access_deny;
-        return      'OK';
-    }
-
-    server {
-        listen      127.0.0.1:8088;
-        js_preread  js_preread;
-        proxy_pass  127.0.0.1:8090;
-    }
-
-    server {
-        listen      127.0.0.1:8089;
-        js_filter   js_filter;
-        proxy_pass  127.0.0.1:8090;
-    }
-
-    server {
-        listen      127.0.0.1:8091;
         js_access   js_access_step;
         js_preread  js_preread_step;
         js_filter   js_filter_step;
@@ -105,21 +107,85 @@ stream {
     }
 
     server {
+        listen      127.0.0.1:8087;
+        js_access   js_access_undecided;
+        return      OK;
+    }
+
+    server {
+        listen      127.0.0.1:8088;
+        js_access   js_access_allow;
+        return      OK;
+    }
+
+    server {
+        listen      127.0.0.1:8089;
+        js_access   js_access_deny;
+        return      OK;
+    }
+
+    server {
+        listen      127.0.0.1:8091;
+        js_preread  js_preread_async;
+        proxy_pass  127.0.0.1:8090;
+    }
+
+    server {
         listen      127.0.0.1:8092;
-        js_filter   js_filter_except;
+        js_preread  js_preread_data;
         proxy_pass  127.0.0.1:8090;
     }
 
     server {
         listen      127.0.0.1:8093;
+        js_preread  js_preread_req_line;
+        return      $js_req_line;
+    }
+
+    server {
+        listen      127.0.0.1:8094;
+        js_filter   js_filter_empty;
+        proxy_pass  127.0.0.1:8090;
+    }
+
+    server {
+        listen      127.0.0.1:8095;
+        js_filter   js_filter_header_inject;
+        proxy_pass  127.0.0.1:8079;
+    }
+
+    server {
+        listen      127.0.0.1:8096;
+        js_filter   js_filter_search;
+        proxy_pass  127.0.0.1:8090;
+    }
+
+    server {
+        listen      127.0.0.1:8097;
+        js_access   js_access_except;
+        proxy_pass  127.0.0.1:8090;
+    }
+
+    server {
+        listen      127.0.0.1:8098;
         js_preread  js_preread_except;
         proxy_pass  127.0.0.1:8090;
     }
+
+    server {
+        listen      127.0.0.1:8099;
+        js_filter   js_filter_except;
+        proxy_pass  127.0.0.1:8090;
+    }
 }
 
 EOF
 
 $t->write_file('test.js', <<EOF);
+    function test_njs(r) {
+        r.return(200, njs.version);
+    }
+
     function js_addr(s) {
         return 'addr=' + s.remoteAddress;
     }
@@ -136,55 +202,142 @@ EOF
         s.log("SEE-THIS");
     }
 
+    var res = '';
+
+    function js_access_step(s) {
+        res += '1';
+
+        setTimeout(function() {
+            if (s.remoteAddress.match('127.0.0.1')) {
+                s.allow();
+            }
+        }, 1);
+    }
+
+    function js_preread_step(s) {
+        s.on('upload', function (data) {
+            res += '2';
+            if (res.length >= 3) {
+                s.done();
+            }
+        });
+    }
+
+    function js_filter_step(s) {
+        s.on('upload', function(data, flags) {
+            s.send(data);
+            res += '3';
+        });
+
+        s.on('download', function(data, flags) {
+
+            if (!flags.last) {
+                res += '4';
+                s.send(data);
+
+            } else {
+                res += '5';
+                s.send(res, {last:1});
+                s.off('download');
+            }
+        });
+    }
+
+    function js_access_undecided(s) {
+        s.decline();
+    }
+
     function js_access_allow(s) {
         if (s.remoteAddress.match('127.0.0.1')) {
-            return s.OK;
+            s.done();
+            return;
         }
+
+        s.abort();
     }
 
     function js_access_deny(s) {
         if (s.remoteAddress.match('127.0.0.1')) {
-            return s.ABORT;
-        }
-    }
-
-    function js_preread(s) {
-        var n = s.buffer.indexOf('z');
-        if (n == -1) {
-            return s.AGAIN;
-        }
-    }
-
-    function js_filter(s) {
-        if (s.fromUpstream) {
-            var n = s.buffer.search('y');
-            if (n != -1) {
-                s.buffer = 'z';
-            }
+            s.abort();
             return;
         }
 
-        n = s.buffer.search('x');
-        if (n != -1) {
-            s.buffer = 'y';
-        }
+        s.allow();
+    }
+
+
+    function js_preread_async(s) {
+        setTimeout(function() {
+            s.done();
+        }, 1);
+    }
+
+    function js_preread_data(s) {
+        s.on('upload', function (data, flags) {
+            if (data.indexOf('z') != -1) {
+                s.done();
+            }
+        });
     }
 
-    var res = '';
-    function js_access_step(s) {
-        res += '1';
+    var line = '';
+
+    function js_preread_req_line(s) {
+        s.on('upload', function (data, flags) {
+            var n = data.indexOf('\n');
+            if (n != -1) {
+                line = data.substr(0, n);
+                s.done();
+            }
+        });
+    }
+
+    function js_req_line(s) {
+        return line;
+    }
+
+    function js_filter_empty(s) {
     }
 
-    function js_preread_step(s) {
-        res += '2';
+    function js_filter_header_inject(s) {
+        var req = '';
+
+        s.on('upload', function(data, flags) {
+            req += data;
+
+            var n = req.search('\n');
+            if (n != -1) {
+                var rest = req.substr(n + 1);
+                req = req.substr(0, n + 1);
+
+                s.send(req + 'Foo: foo' + '\r\n' + rest, flags);
+
+                s.off('upload');
+            }
+        });
     }
 
-    function js_filter_step(s) {
-        if (s.eof) {
-            s.buffer = res;
-            return;
-        }
-        res += '3';
+    function js_filter_search(s) {
+        s.on('download', function(data, flags) {
+            var n = data.search('y');
+            if (n != -1) {
+                s.send('z');
+            }
+        });
+
+        s.on('upload', function(data, flags) {
+            var n = data.search('x');
+            if (n != -1) {
+                s.send('y');
+            }
+        });
+    }
+
+    function js_access_except(s) {
+        function done() {return s.a.a};
+
+        setTimeout(done, 1);
+        setTimeout(done, 2);
     }
 
     function js_preread_except(s) {
@@ -193,13 +346,13 @@ EOF
     }
 
     function js_filter_except(s) {
-        s.a.a;
+        s.on('unknown', function() {});
     }
 
 EOF
 
 $t->run_daemon(\&stream_daemon, port(8090));
-$t->try_run('no stream njs available')->plan(14);
+$t->try_run('no stream njs available')->plan(19);
 $t->waitforsocket('127.0.0.1:' . port(8090));
 
 ###############################################################################
@@ -214,22 +367,37 @@ is(stream('127.0.0.1:' . port(8082))->re
 is(stream('127.0.0.1:' . port(8083))->read(), '', 'stream js unknown function');
 is(stream('127.0.0.1:' . port(8084))->read(), 'sess_unk=undefined', 's.unk');
 
-is(stream('127.0.0.1:' . port(8086))->read(), 'OK', 'js_access allow');
-is(stream('127.0.0.1:' . port(8087))->read(), '', 'js_access deny');
-is(stream('127.0.0.1:' . port(8088))->io('xyz'), 'xyz', 'js_preread');
-is(stream('127.0.0.1:' . port(8089))->io('x'), 'z', 'js_filter');
-is(stream('127.0.0.1:' . port(8091))->io('0'), '01233', 'handlers order');
+TODO: {
+local $TODO = 'not yet'
+	unless get('/njs') =~ /^([.0-9]+)$/m && $1 ge '0.2.4';
+
+is(stream('127.0.0.1:' . port(8086))->io('0'), '0122345',
+	'async handlers order');
+is(stream('127.0.0.1:' . port(8087))->io('#'), 'OK', 'js_access_undecided');
+is(stream('127.0.0.1:' . port(8088))->io('#'), 'OK', 'js_access_allow');
+is(stream('127.0.0.1:' . port(8089))->io('#'), '', 'js_access_deny');
 
-stream('127.0.0.1:' . port(8092))->io('x');
-stream('127.0.0.1:' . port(8093))->io('x');
+is(stream('127.0.0.1:' . port(8091))->io('#'), '#', 'js_preread_async');
+is(stream('127.0.0.1:' . port(8092))->io('#z'), '#z', 'js_preread_async_data');
+is(stream('127.0.0.1:' . port(8093))->io("xy\na"), 'xy', 'js_preread_req_line');
+
+is(stream('127.0.0.1:' . port(8094))->io('x'), 'x', 'js_filter_empty');
+like(get('/p/return'), qr/foo/, 'js_filter_injected_header');
+is(stream('127.0.0.1:' . port(8096))->io('x'), 'z', 'js_filter_search');
+
+}
+
+stream('127.0.0.1:' . port(8097))->io('x');
+stream('127.0.0.1:' . port(8098))->io('x');
+stream('127.0.0.1:' . port(8099))->io('x');
 
 $t->stop();
 
 ok(index($t->read_file('error.log'), 'SEE-THIS') > 0, 'stream js log');
 ok(index($t->read_file('error.log'), 'at fs.readFileSync') > 0,
-   'stream js_preread backtrace');
+	'stream js_preread backtrace');
 ok(index($t->read_file('error.log'), 'at js_filter_except') > 0,
-   'stream js_filter backtrace');
+	'stream js_filter backtrace');
 
 ###############################################################################
 
@@ -265,4 +433,15 @@ sub log2i { Test::Nginx::log_core('|| <<
 sub log2o { Test::Nginx::log_core('|| >>', @_); }
 sub log2c { Test::Nginx::log_core('||', @_); }
 
+sub get {
+	my ($url, %extra) = @_;
+
+	my $s = IO::Socket::INET->new(
+		Proto => 'tcp',
+		PeerAddr => '127.0.0.1:' . port(8079)
+	) or die "Can't connect to nginx: $!\n";
+
+	return http_get($url, socket => $s);
+}
+
 ###############################################################################