From 02e65ecc39393a756f01875fecd3038625c921ad Mon Sep 17 00:00:00 2001 From: Aleksei Konovkin Date: Fri, 19 Apr 2019 12:31:05 +0300 Subject: [PATCH] add tests --- build.sh | 2 + ngx_zookeeper_upstream_module.c | 8 +- t/exclue.t | 113 +++++++++++++++++++++++ t/filter.t | 153 ++++++++++++++++++++++++++++++++ t/simple.t | 112 +++++++++++++++++++++++ t/sync.t | 121 +++++++++++++++++++++++++ t/sync_path_multi.t | 117 ++++++++++++++++++++++++ t/unlock.t | 129 +++++++++++++++++++++++++++ t/with_params.t | 103 +++++++++++++++++++++ tests.sh | 31 +++++++ 10 files changed, 886 insertions(+), 3 deletions(-) create mode 100644 t/exclue.t create mode 100644 t/filter.t create mode 100644 t/simple.t create mode 100644 t/sync.t create mode 100644 t/sync_path_multi.t create mode 100644 t/unlock.t create mode 100644 t/with_params.t create mode 100755 tests.sh diff --git a/build.sh b/build.sh index 2570217..1af4e99 100755 --- a/build.sh +++ b/build.sh @@ -223,6 +223,7 @@ function build_release() { --with-stream \ --with-cc-opt="-Wno-error=unused-value $ADDITIONAL_INCLUDES" \ --with-ld-opt="$ADDITIONAL_LIBS" \ + --add-module=../echo-nginx-module \ --add-module=../ngx_dynamic_upstream \ --add-module=../ngx_dynamic_healthcheck \ --add-module=../.. >> $BUILD_LOG 2>>$ERR_LOG @@ -320,6 +321,7 @@ function download() { download_module ZigzagAK ngx_dynamic_upstream master download_module ZigzagAK ngx_dynamic_healthcheck master + download_module openresty echo-nginx-module master cd .. } diff --git a/ngx_zookeeper_upstream_module.c b/ngx_zookeeper_upstream_module.c index 63c8c7c..5852eca 100644 --- a/ngx_zookeeper_upstream_module.c +++ b/ngx_zookeeper_upstream_module.c @@ -1969,12 +1969,14 @@ zookeeper_sync_list_handler(ngx_http_request_t *r) if (out->buf->last == out->buf->end) return NGX_HTTP_INTERNAL_SERVER_ERROR; - if (j == zoo.len - 1) - out->buf->last -= 3; - content_length += out->buf->last - out->buf->start; } + if (content_length > 2) { + out->buf->last-=3; + content_length-=3; + } + out->next = ngx_pcalloc(r->pool, sizeof(ngx_chain_t)); if (out->next == NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; diff --git a/t/exclue.t b/t/exclue.t new file mode 100644 index 0000000..c35d989 --- /dev/null +++ b/t/exclue.t @@ -0,0 +1,113 @@ +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/app1'); +create('/test_upstream/app1/nodes'); +create('/test_upstream/app2'); +create('/test_upstream/app2/nodes'); +create('/test_upstream/app1/nodes/127.0.0.1:5555'); +create('/test_upstream/app1/nodes/127.0.0.2:5555'); +create('/test_upstream/app1/nodes/global-exclude-host1.com'); +create('/test_upstream/app1/nodes/1.2.3.4'); +create('/test_upstream/app2/nodes/127.0.0.3:4444'); +create('/test_upstream/app2/nodes/localhost:4444'); +create('/test_upstream/app2/nodes/global-exclude-host2.com'); +create('/test_upstream/app2/nodes/1.2.3.4'); +create('/test_upstream/.locks'); +create('/test_upstream/.locks/app2'); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + zookeeper_sync_global_exclude global-exclude-host1.com; + zookeeper_sync_global_exclude global-exclude-host2.com; + zookeeper_sync_global_exclude 1.2.3.4; + + upstream app1 { + zone shm_app1 128k; + zookeeper_sync_path /test_upstream/app1/nodes; + zookeeper_sync_file app1.peers; + zookeeper_sync_exclude 127.0.0.2; + } + + upstream app2 { + zone shm_app2 128k; + zookeeper_sync_path /test_upstream/app2/nodes; + zookeeper_sync_lock /test_upstream/.locks/app2; + zookeeper_sync_file app2.peers; + zookeeper_sync_exclude localhost; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /dynamic { + dynamic_upstream; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"app1","lock":"","params_tag":"\@params","filter":""},\r +{"name":"app2","lock":"\/test_upstream\/.locks\/app2\/.+","params_tag":"\@params","filter":""}\]/ + + +=== STEP 3: Check peers +--- request eval +["GET /dynamic?upstream=app1","GET /dynamic?upstream=app2"] +--- response_body eval +["server 127.0.0.1:5555 addr=127.0.0.1:5555; +", +"server 127.0.0.3:4444 addr=127.0.0.3:4444; +"] + + diff --git a/t/filter.t b/t/filter.t new file mode 100644 index 0000000..9bbdedc --- /dev/null +++ b/t/filter.t @@ -0,0 +1,153 @@ + +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/app1'); +create('/test_upstream/app1/nodes'); +create('/test_upstream/app2'); +create('/test_upstream/app2/nodes'); +create('/test_upstream/app1/nodes/127.0.1.1:5555'); +create('/test_upstream/app1/nodes/127.0.0.1:5555', '@all'); +create('/test_upstream/app1/nodes/127.0.0.2:5555', '@a'); +create('/test_upstream/app1/nodes/127.0.0.3:5555', '@b'); +create('/test_upstream/app2/nodes/127.0.1.4:4444'); +create('/test_upstream/app2/nodes/127.0.0.4:4444', '@all'); +create('/test_upstream/app2/nodes/127.0.0.5:4444', '@a'); +create('/test_upstream/app2/nodes/127.0.0.6:4444', '@b'); +create('/test_upstream/.locks'); +create('/test_upstream/.locks/app2'); +create('/test_upstream/.locks/app2-a'); +create('/test_upstream/.locks/app2-b'); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + upstream app1 { + zone shm_app1 128k; + zookeeper_sync_path /test_upstream/app1/nodes; + zookeeper_sync_file app1.peers; + } + + upstream app1-a { + zone shm_app1-a 128k; + zookeeper_sync_path /test_upstream/app1/nodes; + zookeeper_sync_file app1.peers; + zookeeper_sync_filter @a; + } + + upstream app1-b { + zone shm_app1-b 128k; + zookeeper_sync_path /test_upstream/app1/nodes; + zookeeper_sync_file app1.peers; + zookeeper_sync_filter @b; + } + + upstream app2 { + zone shm_app2 128k; + zookeeper_sync_path /test_upstream/app2/nodes; + zookeeper_sync_lock /test_upstream/.locks/app2; + zookeeper_sync_file app2.peers; + } + + upstream app2-a { + zone shm_app2-a 128k; + zookeeper_sync_path /test_upstream/app2/nodes; + zookeeper_sync_lock /test_upstream/.locks/app2-a; + zookeeper_sync_file app2.peers; + zookeeper_sync_filter @a; + } + + upstream app2-b { + zone shm_app2-b 128k; + zookeeper_sync_path /test_upstream/app2/nodes; + zookeeper_sync_lock /test_upstream/.locks/app2-b; + zookeeper_sync_file app2.peers; + zookeeper_sync_filter @b; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /dynamic { + dynamic_upstream; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"app1","lock":"","params_tag":"\@params","filter":""},\r +{"name":"app1-a","lock":"","params_tag":"\@params","filter":"\@a"},\r +{"name":"app1-b","lock":"","params_tag":"\@params","filter":"\@b"},\r +{"name":"app2","lock":"\/test_upstream\/.locks\/app2\/.+","params_tag":"\@params","filter":""},\r +{"name":"app2-a","lock":"\/test_upstream\/.locks\/app2-a\/.+","params_tag":"\@params","filter":"\@a"},\r +{"name":"app2-b","lock":"\/test_upstream\/.locks\/app2-b\/.+","params_tag":"\@params","filter":"\@b"}\]/ + + +=== STEP 3: Check peers +--- request eval +[ +"GET /dynamic?upstream=app1", +"GET /dynamic?upstream=app1-a", +"GET /dynamic?upstream=app1-b", +"GET /dynamic?upstream=app2", +"GET /dynamic?upstream=app2-a", +"GET /dynamic?upstream=app2-b" +] +--- response_body_like eval +[ +qr/(server 127\.0\.[01]\.[123]:5555 addr=127\.0\.[01]\.[123]:5555;\n){4}/, +qr/(server 127\.0\.[01]\.[12]:5555 addr=127\.0\.[01]\.[12]:5555;\n){2}/, +qr/(server 127\.0\.[01]\.[13]:5555 addr=127\.0\.[01]\.[13]:5555;\n){2}/, +qr/(server 127\.0\.[01]\.[456]:4444 addr=127\.0\.[01].[456]:4444;\n){4}/, +qr/(server 127\.0\.[01]\.[45]:4444 addr=127\.0\.[01]\.[45]:4444;\n){2}/, +qr/(server 127\.0\.[01]\.[46]:4444 addr=127\.0\.[01]\.[46]:4444;\n){2}/ +] diff --git a/t/simple.t b/t/simple.t new file mode 100644 index 0000000..4fdf998 --- /dev/null +++ b/t/simple.t @@ -0,0 +1,112 @@ +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/simple1'); +create('/test_upstream/simple1/nodes'); +create('/test_upstream/simple2'); +create('/test_upstream/simple2/nodes'); +create('/test_upstream/simple1/nodes/127.0.0.1:5555'); +create('/test_upstream/simple1/nodes/127.0.0.2:5555'); +create('/test_upstream/simple2/nodes/127.0.0.3:4444'); +create('/test_upstream/simple2/nodes/127.0.0.4:4444'); +create('/test_upstream/.locks'); +create('/test_upstream/.locks/simple2'); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + upstream simple1 { + zone shm_simple1 128k; + zookeeper_sync_path /test_upstream/simple1/nodes; + zookeeper_sync_file simple1.peers; + } + + upstream simple2 { + zone shm_simple2 128k; + zookeeper_sync_path /test_upstream/simple2/nodes; + zookeeper_sync_lock /test_upstream/.locks/simple2; + zookeeper_sync_file simple2.peers; + } + + upstream xxx { + zone shm_simple1 128k; + server 0.0.0.0:1; + } + + upstream yyy { + server 0.0.0.0:1; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /dynamic { + dynamic_upstream; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"simple1","lock":"","params_tag":"\@params","filter":""},\r +{"name":"simple2","lock":"\/test_upstream\/.locks\/simple2\/.+","params_tag":"\@params","filter":""}\]/ + + +=== STEP 3: Check peers +--- request eval +["GET /dynamic?upstream=simple1","GET /dynamic?upstream=simple2"] +--- response_body_like eval +[qr/server 127\.0\.0\.[12]:5555 addr=127\.0\.0\.[12]:5555; +server 127\.0\.0\.[12]:5555 addr=127\.0\.0\.[12]:5555; +/, + qr/server 127\.0\.0\.[34]:4444 addr=127\.0\.0\.[34]:4444; +server 127\.0\.0\.[34]:4444 addr=127\.0\.0\.[34]:4444; +/] diff --git a/t/sync.t b/t/sync.t new file mode 100644 index 0000000..dc70e16 --- /dev/null +++ b/t/sync.t @@ -0,0 +1,121 @@ +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup_childrens { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } +} + +sub cleanup { + my ($path) = @_; + cleanup_childrens($path); + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/simple'); +create('/test_upstream/simple/nodes'); +create('/test_upstream/simple/nodes/127.0.0.1:4444'); +create('/test_upstream/simple/nodes/127.0.0.2:4444'); +create('/test_upstream/simple/nodes/127.0.0.3:4444'); + +add_block_preprocessor(sub { + my $block = shift; + if ($block->name =~ /STEP 4/) { + create('/test_upstream/simple/nodes/127.0.0.4:4444'); + create('/test_upstream/simple/nodes/127.0.0.5:4444'); + $zkh->delete('/test_upstream/simple/nodes/127.0.0.2:4444'); + $zkh->delete('/test_upstream/simple/nodes/127.0.0.3:4444'); + } +}); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + upstream simple { + zone shm_simple 128k; + zookeeper_sync_path /test_upstream/simple/nodes; + zookeeper_sync_file simple.peers; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /dynamic { + dynamic_upstream; + } + + location = /sleep { + echo_sleep $arg_delay; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"simple","lock":"","params_tag":"\@params","filter":""}\]/ + + +=== STEP 3: Check peers +--- request +GET /dynamic?upstream=simple +--- response_body_like eval +qr/(server 127\.0\.0\.[123]:4444 addr=127\.0\.0\.[123]:4444;\n){3}/ + + +=== STEP 4: Update & recheck +--- request eval +[ +"GET /sleep?delay=11", +"GET /dynamic?upstream=simple" +] +--- response_body_like eval +[ +"", +qr/(server 127\.0\.0\.[145]:4444 addr=127\.0\.0\.[145]:4444; +){3}/ +] +--- timeout: 12 + + diff --git a/t/sync_path_multi.t b/t/sync_path_multi.t new file mode 100644 index 0000000..8ef5fe5 --- /dev/null +++ b/t/sync_path_multi.t @@ -0,0 +1,117 @@ + +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/multi1'); +create('/test_upstream/multi1/nodes1'); +create('/test_upstream/multi1/nodes2'); +create('/test_upstream/multi2'); +create('/test_upstream/multi2/nodes1'); +create('/test_upstream/multi2/nodes2'); +create('/test_upstream/multi1/nodes1/127.0.0.1:5555'); +create('/test_upstream/multi1/nodes2/127.0.0.2:5555'); +create('/test_upstream/multi2/nodes1/127.0.0.3:4444'); +create('/test_upstream/multi2/nodes2/127.0.0.4:4444'); +create('/test_upstream/.locks'); +create('/test_upstream/.locks/multi2'); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + upstream multi1 { + zone shm_multi1 128k; + zookeeper_sync_path /test_upstream/multi1/nodes1; + zookeeper_sync_path /test_upstream/multi1/nodes2; + zookeeper_sync_file multi1.peers; + } + + upstream multi2 { + zone shm_multi2 128k; + zookeeper_sync_path /test_upstream/multi2/nodes1; + zookeeper_sync_path /test_upstream/multi2/nodes2; + zookeeper_sync_lock /test_upstream/.locks/multi2; + zookeeper_sync_file multi2.peers; + } + + upstream xxx { + zone shm_multi1 128k; + server 0.0.0.0:1; + } + + upstream yyy { + server 0.0.0.0:1; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /dynamic { + dynamic_upstream; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"multi1","lock":"","params_tag":"\@params","filter":""},\r +{"name":"multi2","lock":"\/test_upstream\/.locks\/multi2\/.+","params_tag":"\@params","filter":""}\]/ + + +=== STEP 3: Check peers +--- request eval +["GET /dynamic?upstream=multi1","GET /dynamic?upstream=multi2"] +--- response_body_like eval +[qr/server 127\.0\.0\.[12]:5555 addr=127\.0\.0\.[12]:5555; +server 127\.0\.0\.[12]:5555 addr=127\.0\.0\.[12]:5555; +/, + qr/server 127\.0\.0\.[34]:4444 addr=127\.0\.0\.[34]:4444; +server 127\.0\.0\.[34]:4444 addr=127\.0\.0\.[34]:4444; +/] diff --git a/t/unlock.t b/t/unlock.t new file mode 100644 index 0000000..03e7fb4 --- /dev/null +++ b/t/unlock.t @@ -0,0 +1,129 @@ +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup_childrens { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } +} + +sub cleanup { + my ($path) = @_; + cleanup_childrens($path); + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/simple'); +create('/test_upstream/simple/nodes'); +create('/test_upstream/simple/nodes/127.0.0.1:4444'); +create('/test_upstream/simple/nodes/127.0.0.2:4444'); +create('/test_upstream/simple/nodes/127.0.0.3:4444'); +create('/test_upstream/.locks'); +create('/test_upstream/.locks/simple'); + +add_block_preprocessor(sub { + my $block = shift; + if ($block->name =~ /STEP 4/) { + create('/test_upstream/simple/nodes/127.0.0.4:4444'); + create('/test_upstream/simple/nodes/127.0.0.5:4444'); + $zkh->delete('/test_upstream/simple/nodes/127.0.0.2:4444'); + $zkh->delete('/test_upstream/simple/nodes/127.0.0.3:4444'); + } +}); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + upstream simple { + zone shm_simple 128k; + zookeeper_sync_path /test_upstream/simple/nodes; + zookeeper_sync_lock /test_upstream/.locks/simple; + zookeeper_sync_file simple.peers; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /unlock { + zookeeper_sync_unlock; + } + + location = /dynamic { + dynamic_upstream; + } + + location = /sleep { + echo_sleep $arg_delay; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"simple","lock":"\/test_upstream\/.locks\/simple\/.+","params_tag":"\@params","filter":""}\]/ + + +=== STEP 3: Check peers +--- request +GET /dynamic?upstream=simple +--- response_body_like eval +qr/(server 127\.0\.0\.[123]:4444 addr=127\.0\.0\.[123]:4444;\n){3}/ + + +=== STEP 4: Update & recheck +--- request eval +[ +"GET /unlock?upstream=simple&local=", +"GET /sleep?delay=11", +"GET /dynamic?upstream=simple" +] +--- response_body_like eval +[ +"", +"", +qr/(server 127\.0\.0\.[145]:4444 addr=127\.0\.0\.[145]:4444; +){3}/ +] +--- timeout: 12 + diff --git a/t/with_params.t b/t/with_params.t new file mode 100644 index 0000000..97bf6f0 --- /dev/null +++ b/t/with_params.t @@ -0,0 +1,103 @@ +use Test::Nginx::Socket 'no_plan'; +use Net::ZooKeeper qw(:node_flags :acls); + +$ENV{TEST_NGINX_ZOOKEEPER_PORT} ||= 2181; + +# prepare zoo data + +my $zkh = Net::ZooKeeper->new('127.0.0.1:' . $ENV{TEST_NGINX_ZOOKEEPER_PORT}); + +sub create { + my ($path, $val) = @_; + $zkh->create($path, $val || '', 'acl' => ZOO_OPEN_ACL_UNSAFE) or + die("unable to create node " . $path . ", err:" . $zkh->get_error()); +} + +sub cleanup { + my ($path) = @_; + foreach my $znode ($zkh->get_children($path)) { + cleanup($path . '/' . $znode); + } + $zkh->delete($path); +} + +cleanup('/test_upstream'); + +create('/test_upstream'); +create('/test_upstream/app1'); +create('/test_upstream/app1/nodes'); +create('/test_upstream/app2'); +create('/test_upstream/app2/nodes'); +create('/test_upstream/app1/nodes/127.0.0.1:5555', '@params max_conns=55 max_fails=44 fail_timeout=4s'); +create('/test_upstream/app1/nodes/127.0.0.2:5555', '@params max_conns=55 max_fails=44 fail_timeout=4s'); +create('/test_upstream/app2/nodes/127.0.0.3:4444', '@params max_conns=88 max_fails=99 fail_timeout=9s'); +create('/test_upstream/app2/nodes/127.0.0.4:4444', '@params max_conns=88 max_fails=99 fail_timeout=9s'); +create('/test_upstream/.locks'); +create('/test_upstream/.locks/app2'); + +add_cleanup_handler(sub { + cleanup('/test_upstream'); +}); + +no_shuffle(); +run_tests(); + +__DATA__ + +=== STEP 1: Init +--- http_config + + zookeeper_upstream 127.0.0.1:$TEST_NGINX_ZOOKEEPER_PORT; + zookeeper_upstream_log_level debug; + zookeeper_upstream_recv_timeout 5000; + + upstream app1 { + zone shm_app1 128k; + zookeeper_sync_path /test_upstream/app1/nodes; + zookeeper_sync_file app1.peers; + } + + upstream app2 { + zone shm_app2 128k; + zookeeper_sync_path /test_upstream/app2/nodes; + zookeeper_sync_lock /test_upstream/.locks/app2; + zookeeper_sync_file app2.peers; + } + +--- config + + location = /test { + return 200; + } + + location = /list { + zookeeper_sync_list; + } + + location = /dynamic { + dynamic_upstream; + } + +--- request + GET /test +--- wait: 3 + + +=== STEP 2: Check list +--- request + GET /list +--- response_body_like eval +qr/\[{"name":"app1","lock":"","params_tag":"\@params","filter":""},\r +{"name":"app2","lock":"\/test_upstream\/.locks\/app2\/.+","params_tag":"\@params","filter":""}\]/ + + +=== STEP 3: Check peers with params +--- request eval +["GET /dynamic?upstream=app1&verbose=","GET /dynamic?upstream=app2&verbose="] +--- response_body_like eval +[qr/server 127\.0\.0\.[12]:5555 addr=127\.0\.0\.[12]:5555 weight=1 max_fails=44 fail_timeout=4000 max_conns=55 conns=0; +server 127\.0\.0\.[12]:5555 addr=127\.0\.0\.[12]:5555 weight=1 max_fails=44 fail_timeout=4000 max_conns=55 conns=0; +/, + qr/server 127\.0\.0\.[34]:4444 addr=127\.0\.0\.[34]:4444 weight=1 max_fails=99 fail_timeout=9000 max_conns=88 conns=0; +server 127\.0\.0\.[34]:4444 addr=127\.0\.0\.[34]:4444 weight=1 max_fails=99 fail_timeout=9000 max_conns=88 conns=0; +/] \ No newline at end of file diff --git a/tests.sh b/tests.sh new file mode 100755 index 0000000..530b931 --- /dev/null +++ b/tests.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +ulimit -c unlimited + +DIR=$(pwd) +nginx_fname=$(ls -1 $DIR/install/*.tar.gz) + +[ -d install/tmp ] || mkdir install/tmp +tar zxf $nginx_fname -C install/tmp + +folder="$(ls -1 $DIR/install/tmp | grep nginx)" + +export PATH=$DIR/install/tmp/$folder/sbin:$PATH +export LD_LIBRARY_PATH=$DIR/install/tmp/$folder/lib + +ret=0 + +for t in $(ls t/*.t) +do + echo "Tests : "$t + prove $t + if [ $? -ne 0 ]; then + ret=$? + exit $ret + fi +done + +rm -rf t/servroot +rm -rf install/tmp + +exit $ret \ No newline at end of file