diff options
author | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
commit | 3f33461e4948bf05e60bdff35ec6c57a649c7860 (patch) | |
tree | 284c2ba95a41536ae1bff6bea710db0709a64739 /ngx_postgres-1.0/t | |
download | openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.tar.gz openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.zip |
openresty bundle
Diffstat (limited to 'ngx_postgres-1.0/t')
-rw-r--r-- | ngx_postgres-1.0/t/000_init.t | 174 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/auth.t | 110 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/bigpipe.t | 141 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/errors.t | 141 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/escape.t | 361 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/eval.t | 75 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/form.t | 71 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/methods.t | 335 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/output.t | 447 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/restful.t | 338 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/restful_json.t | 244 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/rewrites.t | 348 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/sanity.t | 298 | ||||
-rw-r--r-- | ngx_postgres-1.0/t/variables.t | 407 |
14 files changed, 3490 insertions, 0 deletions
diff --git a/ngx_postgres-1.0/t/000_init.t b/ngx_postgres-1.0/t/000_init.t new file mode 100644 index 0000000..832244e --- /dev/null +++ b/ngx_postgres-1.0/t/000_init.t @@ -0,0 +1,174 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(1); + +plan tests => repeat_each() * 2 * blocks(); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +no_shuffle(); +run_tests(); + +__DATA__ + +=== TEST 1: cats - drop table +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "DROP TABLE cats"; + error_page 500 = /ignore; + } + + location /ignore { echo "ignore"; } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 2: cats - create table +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "CREATE TABLE cats (id integer, name text)"; + } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 3: cats - insert value +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "INSERT INTO cats (id) VALUES (2)"; + } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 4: cats - insert value +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "INSERT INTO cats (id, name) VALUES (3, 'bob')"; + } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 5: numbers - drop table +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "DROP TABLE numbers"; + error_page 500 = /ignore; + } + + location /ignore { echo "ignore"; } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 6: numbers - create table +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "CREATE TABLE numbers (number integer)"; + } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 7: users - drop table +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "DROP TABLE users"; + error_page 500 = /ignore; + } + + location /ignore { echo "ignore"; } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 8: users - create table +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "CREATE TABLE users (login text, pass text)"; + } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] + + + +=== TEST 9: users - insert value +--- http_config eval: $::http_config +--- config + location = /init { + postgres_pass database; + postgres_query "INSERT INTO users (login, pass) VALUES ('ngx_test', 'ngx_test')"; + } +--- request +GET /init +--- error_code: 200 +--- timeout: 10 +--- no_error_log +[error] diff --git a/ngx_postgres-1.0/t/auth.t b/ngx_postgres-1.0/t/auth.t new file mode 100644 index 0000000..40468e4 --- /dev/null +++ b/ngx_postgres-1.0/t/auth.t @@ -0,0 +1,110 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3 - 2 * 1); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: authorized (auth basic) +--- http_config eval: $::http_config +--- config + location = /auth { + internal; + postgres_escape $user $remote_user; + postgres_escape $pass $remote_passwd; + postgres_pass database; + postgres_query "select login from users where login=$user and pass=$pass"; + postgres_rewrite no_rows 403; + postgres_set $login 0 0 required; + postgres_output none; + } + + location /test { + auth_request /auth; + auth_request_set $auth_user $login; + echo -n "hi, $auth_user!"; + } +--- more_headers +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +hi, ngx_test! +--- timeout: 10 + + + +=== TEST 2: unauthorized (auth basic) +--- http_config eval: $::http_config +--- config + location = /auth { + internal; + postgres_escape $user $remote_user; + postgres_escape $pass $remote_passwd; + postgres_pass database; + postgres_query "select login from users where login=$user and pass=$pass"; + postgres_rewrite no_rows 403; + postgres_set $login 0 0 required; + postgres_output none; + } + + location /test { + auth_request /auth; + auth_request_set $auth_user $login; + echo -n "hi, $auth_user!"; + } +--- more_headers +Authorization: Basic bW9udHk6c29tZV9wYXNz +--- request +GET /test +--- error_code: 403 +--- response_headers +Content-Type: text/html +--- timeout: 10 + + + +=== TEST 3: unauthorized (no authorization header) +--- http_config eval: $::http_config +--- config + location = /auth { + internal; + postgres_escape $user $remote_user; + postgres_escape $pass $remote_passwd; + postgres_pass database; + postgres_query "select login from users where login=$user and pass=$pass"; + postgres_rewrite no_rows 403; + postgres_set $login 0 0 required; + postgres_output none; + } + + location /test { + auth_request /auth; + auth_request_set $auth_user $login; + echo -n "hi, $auth_user!"; + } +--- request +GET /test +--- error_code: 403 +--- response_headers +Content-Type: text/html +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/bigpipe.t b/ngx_postgres-1.0/t/bigpipe.t new file mode 100644 index 0000000..4ee951d --- /dev/null +++ b/ngx_postgres-1.0/t/bigpipe.t @@ -0,0 +1,141 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 2); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: synchronous +--- http_config eval: $::http_config +--- config + location /bigpipe { + echo "<html>(...template with javascript and divs...)"; + echo -n "<script type=\"text/javascript\">loader.load("; + echo_location /_query1; + echo ")</script>"; + echo -n "<script type=\"text/javascript\">loader.load("; + echo_location /_query2; + echo ")</script>"; + echo "</html>"; + } + + location /_query1 { + internal; + postgres_pass database; + postgres_query "SELECT * FROM cats ORDER BY id ASC"; + rds_json on; + } + + location /_query2 { + internal; + postgres_pass database; + postgres_query "SELECT * FROM cats ORDER BY id DESC"; + rds_json on; + } +--- request +GET /bigpipe +--- error_code: 200 +--- response_body +<html>(...template with javascript and divs...) +<script type="text/javascript">loader.load([{"id":2,"name":null},{"id":3,"name":"bob"}])</script> +<script type="text/javascript">loader.load([{"id":3,"name":"bob"},{"id":2,"name":null}])</script> +</html> +--- timeout: 10 +--- skip_nginx: 2: < 0.7.46 + + + +=== TEST 2: asynchronous (without echo filter) +--- http_config eval: $::http_config +--- config + location /bigpipe { + echo "<html>(...template with javascript and divs...)"; + echo -n "<script type=\"text/javascript\">loader.load("; + echo_location_async /_query1; + echo ")</script>"; + echo -n "<script type=\"text/javascript\">loader.load("; + echo_location_async /_query2; + echo ")</script>"; + echo "</html>"; + } + + location /_query1 { + internal; + postgres_pass database; + postgres_query "SELECT * FROM cats ORDER BY id ASC"; + rds_json on; + } + + location /_query2 { + internal; + postgres_pass database; + postgres_query "SELECT * FROM cats ORDER BY id DESC"; + rds_json on; + } +--- request +GET /bigpipe +--- error_code: 200 +--- response_body +<html>(...template with javascript and divs...) +<script type="text/javascript">loader.load([{"id":2,"name":null},{"id":3,"name":"bob"}])</script> +<script type="text/javascript">loader.load([{"id":3,"name":"bob"},{"id":2,"name":null}])</script> +</html> +--- timeout: 10 +--- skip_nginx: 2: < 0.7.46 + + + +=== TEST 3: asynchronous (with echo filter) +--- http_config eval: $::http_config +--- config + location /bigpipe { + echo_before_body "<html>(...template with javascript and divs...)"; + echo_before_body -n "<script type=\"text/javascript\">loader.load("; + echo -n " "; # XXX we need this to help our echo filters + echo_location_async /_query1; + echo ")</script>"; + echo -n "<script type=\"text/javascript\">loader.load("; + echo_location_async /_query2; + echo_after_body ")</script>"; + echo_after_body "</html>"; + } + + location /_query1 { + internal; + postgres_pass database; + postgres_query "SELECT * FROM cats ORDER BY id ASC"; + rds_json on; + } + + location /_query2 { + internal; + postgres_pass database; + postgres_query "SELECT * FROM cats ORDER BY id DESC"; + rds_json on; + } +--- request +GET /bigpipe +--- error_code: 200 +--- response_body +<html>(...template with javascript and divs...) +<script type="text/javascript">loader.load( [{"id":2,"name":null},{"id":3,"name":"bob"}])</script> +<script type="text/javascript">loader.load([{"id":3,"name":"bob"},{"id":2,"name":null}])</script> +</html> +--- timeout: 10 +--- skip_nginx: 2: < 0.7.46 diff --git a/ngx_postgres-1.0/t/errors.t b/ngx_postgres-1.0/t/errors.t new file mode 100644 index 0000000..a502203 --- /dev/null +++ b/ngx_postgres-1.0/t/errors.t @@ -0,0 +1,141 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * blocks(); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: bad query +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "i'm bad"; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 2: wrong credentials +--- http_config + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=wrong_pass; + } +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set name='bob' where name='bob'"; + } +--- request +GET /postgres +--- error_code: 502 +--- timeout: 10 + + + +=== TEST 3: no database +--- http_config + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:1 dbname=ngx_test + user=ngx_test password=ngx_test; + } +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set name='bob' where name='bob'"; + } +--- request +GET /postgres +--- error_code: 502 +--- timeout: 10 + + + +=== TEST 4: multiple queries +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats; select * from cats"; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 5: missing query +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 6: empty query +--- http_config eval: $::http_config +--- config + location /postgres { + set $query ""; + postgres_pass database; + postgres_query $query; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 7: empty pass +--- http_config eval: $::http_config +--- config + location /postgres { + set $database ""; + postgres_pass $database; + postgres_query "update cats set name='bob' where name='bob'"; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 8: non-existing table +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update table_that_doesnt_exist set name='bob'"; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/escape.t b/ngx_postgres-1.0/t/escape.t new file mode 100644 index 0000000..8dad7f0 --- /dev/null +++ b/ngx_postgres-1.0/t/escape.t @@ -0,0 +1,361 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3); + +run_tests(); + +__DATA__ + +=== TEST 1: ' +--- config + location /test { + set $test "he'llo"; + postgres_escape $escaped $test; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'he''llo' +--- timeout: 10 + + + +=== TEST 2: \ +--- config + location /test { + set $test "he\\llo"; + postgres_escape $escaped $test; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'he\\llo' +--- timeout: 10 + + + +=== TEST 3: \' +--- config + location /test { + set $test "he\\'llo"; + postgres_escape $escaped $test; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'he\\''llo' +--- timeout: 10 + + + +=== TEST 4: NULL +--- config + location /test { + postgres_escape $escaped $remote_user; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +NULL +--- timeout: 10 + + + +=== TEST 5: empty string +--- config + location /test { + set $empty ""; + postgres_escape $escaped $empty; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +NULL +--- timeout: 10 + + + +=== TEST 6: UTF-8 +--- config + location /test { + set $utf8 "你好"; + postgres_escape $escaped $utf8; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'你好' +--- timeout: 10 + + + +=== TEST 7: user arg +--- config + location /test { + postgres_escape $escaped $arg_say; + echo $escaped; + } +--- request +GET /test?say=he'llo! +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'he''llo!' +--- timeout: 10 + + + +=== TEST 8: NULL (empty) +--- config + location /test { + postgres_escape $escaped =$remote_user; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'' +--- timeout: 10 + + + +=== TEST 9: empty string (empty) +--- config + location /test { + set $empty ""; + postgres_escape $escaped =$empty; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'' +--- timeout: 10 + + + +=== TEST 10: in-place escape +--- config + location /test { + set $test "t'\\est"; + postgres_escape $test; + echo $test; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'t''\\est' +--- timeout: 10 + + + +=== TEST 11: re-useable variable name (test1) +--- config + location /test1 { + set $a "a"; + postgres_escape $escaped $a; + echo $escaped; + } + location /test2 { + set $b "b"; + postgres_escape $escaped $b; + echo $escaped; + } +--- request +GET /test1 +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'a' +--- timeout: 10 + + + +=== TEST 12: re-useable variable name (test2) +--- config + location /test1 { + set $a "a"; + postgres_escape $escaped $a; + echo $escaped; + } + location /test2 { + set $b "b"; + postgres_escape $escaped $b; + echo $escaped; + } +--- request +GET /test2 +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'b' +--- timeout: 10 + + + +=== TEST 13: concatenate multiple sources +--- config + location /test { + set $test "t'\\est"; + set $hello " he'llo"; + postgres_escape $escaped "$test$hello world!"; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'t''\\est he''llo world!' +--- timeout: 10 + + + +=== TEST 14: concatenate multiple empty sources +--- config + location /test { + set $a ""; + set $b ""; + postgres_escape $escaped "$a$b"; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +NULL +--- timeout: 10 + + + +=== TEST 15: concatenate multiple empty sources (empty) +--- config + location /test { + set $a ""; + set $b ""; + postgres_escape $escaped "=$a$b"; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'' +--- timeout: 10 + + + +=== TEST 16: in-place escape on empty string +--- config + location /test { + set $test ""; + postgres_escape $test; + echo $test; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +NULL +--- timeout: 10 + + + +=== TEST 17: in-place escape on empty string (empty) +--- config + location /test { + set $test ""; + postgres_escape =$test; + echo $test; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'' +--- timeout: 10 + + + +=== TEST 18: escape anonymous regex capture +--- config + location ~ /(.*) { + postgres_escape $escaped $1; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'test' +--- timeout: 10 + + + +=== TEST 19: escape named regex capture +--- config + location ~ /(?<test>.*) { + postgres_escape $escaped $test; + echo $escaped; + } +--- request +GET /test +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body +'test' +--- timeout: 10 +--- skip_nginx: 3: < 0.8.25 diff --git a/ngx_postgres-1.0/t/eval.t b/ngx_postgres-1.0/t/eval.t new file mode 100644 index 0000000..c87761d --- /dev/null +++ b/ngx_postgres-1.0/t/eval.t @@ -0,0 +1,75 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::http_config +--- config + location /eval { + eval_subrequest_in_memory off; + + eval $backend { + postgres_pass database; + postgres_query "select '$scheme://127.0.0.1:$server_port/echo'"; + postgres_output value; + } + + proxy_pass $backend; + } + + location /echo { + echo -n "it works!"; + } +--- request +GET /eval +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +it works! +--- timeout: 10 +--- skip_nginx: 3: < 0.8.25 + + + +=== TEST 2: sanity (simple case) +--- http_config eval: $::http_config +--- config + location /eval { + eval_subrequest_in_memory off; + + eval $echo { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_output value; + } + + echo -n $echo; + } +--- request +GET /eval +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +test +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/form.t b/ngx_postgres-1.0/t/form.t new file mode 100644 index 0000000..4771232 --- /dev/null +++ b/ngx_postgres-1.0/t/form.t @@ -0,0 +1,71 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + set_form_input $sql 'sql'; + set_unescape_uri $sql; + postgres_query $sql; + } +--- more_headers +Content-Type: application/x-www-form-urlencoded +--- request +POST /postgres +sql=select%20*%20from%20cats; +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{02}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{02}\x{00}". # col name len +"id". # col name data +"\x{06}\x{80}". # std col type (varchar/str) +"\x{19}\x{00}". # driver col type +"\x{04}\x{00}". # col name len +"name". # col name data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"2". # field data +"\x{ff}\x{ff}\x{ff}\x{ff}". # field len +"". # field data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"3". # field data +"\x{03}\x{00}\x{00}\x{00}". # field len +"bob". # field data +"\x{00}" # row list terminator +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/methods.t b/ngx_postgres-1.0/t/methods.t new file mode 100644 index 0000000..93b80e8 --- /dev/null +++ b/ngx_postgres-1.0/t/methods.t @@ -0,0 +1,335 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3 - 2 * 2); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: default query +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'default' as echo"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{07}\x{00}\x{00}\x{00}". # field len +"default". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 2: method-specific query +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query LOCK GET UNLOCK "select 'GET' as echo"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"GET". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 3: method-specific complex query (check 1) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"GET". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 4: method-specific complex query (check 2) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + } +--- request +LOCK /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{04}\x{00}\x{00}\x{00}". # field len +"LOCK". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 5: method-specific complex query (using not allowed method) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + } +--- request +HEAD /postgres +--- error_code: 405 +--- timeout: 10 + + + +=== TEST 6: method-specific query and default query (using defined method) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'default' as echo"; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"GET". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 7: method-specific query and default query (using other method) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'default' as echo"; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + } +--- request +POST /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{07}\x{00}\x{00}\x{00}". # field len +"default". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 8: inheritance +--- http_config eval: $::http_config +--- config + postgres_query "select 'default' as echo"; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + + location /postgres { + postgres_pass database; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"GET". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 9: inheritance (mixed, don't inherit) +--- http_config eval: $::http_config +--- config + postgres_query "select 'default' as echo"; + + location /postgres { + postgres_pass database; + postgres_query LOCK GET UNLOCK "select '$request_method' as echo"; + } +--- request +HEAD /postgres +--- error_code: 405 +--- timeout: 10 + + + +=== TEST 10: HTTP PATCH request method +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query PATCH "select '$request_method' as echo"; + } +--- request +PATCH /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{05}\x{00}\x{00}\x{00}". # field len +"PATCH". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- skip_nginx: 3: < 0.8.41 diff --git a/ngx_postgres-1.0/t/output.t b/ngx_postgres-1.0/t/output.t new file mode 100644 index 0000000..b4ba503 --- /dev/null +++ b/ngx_postgres-1.0/t/output.t @@ -0,0 +1,447 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3 - 4 * 2); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: none - sanity +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_output none; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +! Content-Type +--- response_body eval +"" +--- timeout: 10 + + + +=== TEST 2: value - sanity +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +test +--- timeout: 10 + + + +=== TEST 3: value - sanity (with different default_type) +--- http_config eval: $::http_config +--- config + default_type text/html; + + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/html +--- response_body chomp +test +--- timeout: 10 + + + +=== TEST 4: value - NULL value +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select NULL as echo"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 5: value - empty value +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select '' as echo"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 6: text - sanity +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select 'a', 'b', 'c', 'd'"; + postgres_output text; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body eval +"a". +"\x{0a}". # new line - delimiter +"b". +"\x{0a}". # new line - delimiter +"c". +"\x{0a}". # new line - delimiter +"d" +--- timeout: 10 + + + +=== TEST 7: rds - sanity (configured) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'default' as echo"; + postgres_output rds; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{07}\x{00}\x{00}\x{00}". # field len +"default". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 8: rds - sanity (default) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'default' as echo"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{07}\x{00}\x{00}\x{00}". # field len +"default". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 9: inheritance +--- http_config eval: $::http_config +--- config + default_type text/plain; + postgres_output value; + + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +test +--- timeout: 10 + + + +=== TEST 10: inheritance (mixed, don't inherit) +--- http_config eval: $::http_config +--- config + postgres_output text; + + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_output none; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +! Content-Type +--- response_body eval +"" +--- timeout: 10 + + + +=== TEST 11: value - sanity (request with known extension) +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_output value; + } +--- request +GET /postgres.jpg +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +test +--- timeout: 10 + + + +=== TEST 12: value - bytea returned in text format +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select E'\\001'::bytea as res"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body_like chomp +^(?:\\001|\\x01)$ +--- timeout: 10 + + + +=== TEST 13: binary value - bytea returned in binary format +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select E'\\001'::bytea as res"; + postgres_output binary_value; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body eval +"\1" +--- timeout: 10 + + + +=== TEST 14: binary value - int2 returned in binary format +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select 3::int2 as res"; + postgres_output binary_value; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body eval +"\0\3" +--- timeout: 10 + + + +=== TEST 15: value - "if" pseudo-location +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + if ($arg_foo) { + postgres_pass database; + postgres_query "select id from cats order by id limit 1"; + postgres_output value; + break; + } + + return 404; + } +--- request +GET /postgres?foo=1 +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body chomp +2 +--- timeout: 10 + + + +=== TEST 16: text - NULL value +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select * from cats order by id"; + postgres_output text; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body eval +"2". +"\x{0a}". # new line - delimiter +"(null)". +"\x{0a}". # new line - delimiter +"3". +"\x{0a}". # new line - delimiter +"bob" +--- timeout: 10 + + + +=== TEST 17: text - empty result +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select * from cats where id=1"; + postgres_output text; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: text/plain +--- response_body eval +"" +--- timeout: 10 + + + +=== TEST 18: value - empty result +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select * from cats where id=1"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 19: value - too many values +--- http_config eval: $::http_config +--- config + default_type text/plain; + + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_output value; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/restful.t b/ngx_postgres-1.0/t/restful.t new file mode 100644 index 0000000..74b111b --- /dev/null +++ b/ngx_postgres-1.0/t/restful.t @@ -0,0 +1,338 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(1); + +plan tests => repeat_each() * (blocks() * 3); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +our $config = <<'_EOC_'; + set $random 123; + + location = /auth { + internal; + + postgres_escape $user $remote_user; + postgres_escape $pass $remote_passwd; + + postgres_pass database; + postgres_query "SELECT login FROM users WHERE login=$user AND pass=$pass"; + postgres_rewrite no_rows 403; + postgres_output none; + } + + location = /numbers/ { + auth_request /auth; + postgres_pass database; + + postgres_query HEAD GET "SELECT * FROM numbers"; + + postgres_query POST "INSERT INTO numbers VALUES('$random') RETURNING *"; + postgres_rewrite POST changes 201; + + postgres_query DELETE "DELETE FROM numbers"; + postgres_rewrite DELETE no_changes 204; + postgres_rewrite DELETE changes 204; + } + + location ~ /numbers/(\d+) { + auth_request /auth; + postgres_pass database; + + postgres_query HEAD GET "SELECT * FROM numbers WHERE number='$1'"; + postgres_rewrite HEAD GET no_rows 410; + + postgres_query PUT "UPDATE numbers SET number='$1' WHERE number='$1' RETURNING *"; + postgres_rewrite PUT no_changes 410; + + postgres_query DELETE "DELETE FROM numbers WHERE number='$1'"; + postgres_rewrite DELETE no_changes 410; + postgres_rewrite DELETE changes 204; + } +_EOC_ + +our $request_headers = <<'_EOC_'; +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +_EOC_ + +no_shuffle(); +run_tests(); + +__DATA__ + +=== TEST 1: clean collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +DELETE /numbers/ +--- error_code: 204 +--- response_headers +! Content-Type +--- response_body eval +"" +--- timeout: 10 + + + +=== TEST 2: list empty collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/ +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{06}\x{00}". # col name len +"number". # col name data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 3: insert resource into collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +POST /numbers/ +--- error_code: 201 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{01}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{06}\x{00}". # col name len +"number". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"123". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 4: list collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/ +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{06}\x{00}". # col name len +"number". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"123". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 5: get resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/123 +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{06}\x{00}". # col name len +"number". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"123". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 6: update resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +Content-Length: 0 +--- request +PUT /numbers/123 +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{01}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{06}\x{00}". # col name len +"number". # col name data +"\x{01}". # valid row flag +"\x{03}\x{00}\x{00}\x{00}". # field len +"123". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 7: remove resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +DELETE /numbers/123 +--- error_code: 204 +--- response_headers +! Content-Type +--- response_body eval +"" +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 8: update non-existing resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +Content-Length: 0 +--- request +PUT /numbers/123 +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- response_body_like: 410 Gone +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 9: get non-existing resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/123 +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- response_body_like: 410 Gone +--- timeout: 10 + + + +=== TEST 10: remove non-existing resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +DELETE /numbers/123 +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- response_body_like: 410 Gone +--- timeout: 10 + + + +=== TEST 11: list empty collection (done) +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/ +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{06}\x{00}". # col name len +"number". # col name data +"\x{00}" # row list terminator +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/restful_json.t b/ngx_postgres-1.0/t/restful_json.t new file mode 100644 index 0000000..aae262b --- /dev/null +++ b/ngx_postgres-1.0/t/restful_json.t @@ -0,0 +1,244 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(1); + +plan tests => repeat_each() * (blocks() * 3); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +our $config = <<'_EOC_'; + set $random 123; + + location = /auth { + internal; + + postgres_escape $user $remote_user; + postgres_escape $pass $remote_passwd; + + postgres_pass database; + postgres_query "SELECT login FROM users WHERE login=$user AND pass=$pass"; + postgres_rewrite no_rows 403; + postgres_output none; + } + + location = /numbers/ { + auth_request /auth; + postgres_pass database; + rds_json on; + + postgres_query HEAD GET "SELECT * FROM numbers"; + + postgres_query POST "INSERT INTO numbers VALUES('$random') RETURNING *"; + postgres_rewrite POST changes 201; + + postgres_query DELETE "DELETE FROM numbers"; + postgres_rewrite DELETE no_changes 204; + postgres_rewrite DELETE changes 204; + } + + location ~ /numbers/(\d+) { + auth_request /auth; + postgres_pass database; + rds_json on; + + postgres_query HEAD GET "SELECT * FROM numbers WHERE number='$1'"; + postgres_rewrite HEAD GET no_rows 410; + + postgres_query PUT "UPDATE numbers SET number='$1' WHERE number='$1' RETURNING *"; + postgres_rewrite PUT no_changes 410; + + postgres_query DELETE "DELETE FROM numbers WHERE number='$1'"; + postgres_rewrite DELETE no_changes 410; + postgres_rewrite DELETE changes 204; + } +_EOC_ + +our $request_headers = <<'_EOC_'; +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +_EOC_ + +no_shuffle(); +run_tests(); + +__DATA__ + +=== TEST 1: clean collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +DELETE /numbers/ +--- error_code: 204 +--- response_headers +! Content-Type +--- response_body eval +"" +--- timeout: 10 + + + +=== TEST 2: list empty collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/ +--- error_code: 200 +--- response_headers +Content-Type: application/json +--- response_body chomp +[] +--- timeout: 10 + + + +=== TEST 3: insert resource into collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +POST /numbers/ +--- error_code: 201 +--- response_headers +Content-Type: application/json +--- response_body chomp +[{"number":123}] +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 4: list collection +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/ +--- error_code: 200 +--- response_headers +Content-Type: application/json +--- response_body chomp +[{"number":123}] +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 5: get resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/123 +--- error_code: 200 +--- response_headers +Content-Type: application/json +--- response_body chomp +[{"number":123}] +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 6: update resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +Content-Length: 0 +--- request +PUT /numbers/123 +--- error_code: 200 +--- response_headers +Content-Type: application/json +--- response_body chomp +[{"number":123}] +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 7: remove resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +DELETE /numbers/123 +--- error_code: 204 +--- response_headers +! Content-Type +--- response_body eval +"" +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 8: update non-existing resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers +Authorization: Basic bmd4X3Rlc3Q6bmd4X3Rlc3Q= +Content-Length: 0 +--- request +PUT /numbers/123 +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- response_body_like: 410 Gone +--- timeout: 10 +--- skip_slave: 3: CentOS + + + +=== TEST 9: get non-existing resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/123 +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- response_body_like: 410 Gone +--- timeout: 10 + + + +=== TEST 10: remove non-existing resource +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +DELETE /numbers/123 +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- response_body_like: 410 Gone +--- timeout: 10 + + + +=== TEST 11: list empty collection (done) +--- http_config eval: $::http_config +--- config eval: $::config +--- more_headers eval: $::request_headers +--- request +GET /numbers/ +--- error_code: 200 +--- response_headers +Content-Type: application/json +--- response_body chomp +[] +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/rewrites.t b/ngx_postgres-1.0/t/rewrites.t new file mode 100644 index 0000000..3cc191e --- /dev/null +++ b/ngx_postgres-1.0/t/rewrites.t @@ -0,0 +1,348 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 2 + 1 * 1); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: no changes (SELECT) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 2: no changes (UPDATE) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='noone'"; + postgres_rewrite no_changes 206; + postgres_rewrite changes 500; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 3: one change +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='bob'"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 206; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 4: rows +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite rows 206; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 5: no rows +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats where name='noone'"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite rows 206; + } +--- request +GET /postgres +--- error_code: 410 +--- response_headers +Content-Type: text/html +--- timeout: 10 + + + +=== TEST 6: inheritance +--- http_config eval: $::http_config +--- config + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite rows 206; + + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 7: inheritance (mixed, don't inherit) +--- http_config eval: $::http_config +--- config + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite rows 206; + + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite rows 206; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 8: rows (method-specific) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite POST PUT rows 201; + postgres_rewrite HEAD GET rows 206; + postgres_rewrite rows 206; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 9: rows (default) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite POST PUT rows 201; + postgres_rewrite rows 206; + } +--- request +GET /postgres +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 10: rows (none) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite POST PUT rows 201; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 11: no changes (UPDATE) with 202 response +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='noone'"; + postgres_rewrite no_changes 202; + postgres_rewrite changes 500; + } +--- request +GET /postgres +--- error_code: 202 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 +--- skip_nginx: 2: < 0.8.41 + + + +=== TEST 12: no changes (UPDATE) with 409 response +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='noone'"; + postgres_rewrite no_changes 409; + postgres_rewrite changes 500; + } +--- request +GET /postgres +--- error_code: 409 +--- response_headers +Content-Type: text/html +--- timeout: 10 + + + +=== TEST 13: no changes (UPDATE) with 409 status and our body +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='noone'"; + postgres_rewrite no_changes =409; + postgres_rewrite changes 500; + } +--- request +GET /postgres +--- error_code: 409 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 + + + +=== TEST 14: rows with 409 status and our body (with integrity check) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_rows 500; + postgres_rewrite rows =409; + } +--- request +GET /postgres +--- error_code: 409 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{02}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{02}\x{00}". # col name len +"id". # col name data +"\x{06}\x{80}". # std col type (varchar/str) +"\x{19}\x{00}". # driver col type +"\x{04}\x{00}". # col name len +"name". # col name data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"2". # field data +"\x{ff}\x{ff}\x{ff}\x{ff}". # field len +"". # field data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"3". # field data +"\x{03}\x{00}\x{00}\x{00}". # field len +"bob". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 15: rows - "if" pseudo-location +--- http_config eval: $::http_config +--- config + location /postgres { + if ($arg_foo) { + postgres_pass database; + postgres_query "select * from cats"; + postgres_rewrite no_changes 500; + postgres_rewrite changes 500; + postgres_rewrite no_rows 410; + postgres_rewrite rows 206; + break; + } + + return 404; + } +--- request +GET /postgres?foo=1 +--- error_code: 206 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- timeout: 10 diff --git a/ngx_postgres-1.0/t/sanity.t b/ngx_postgres-1.0/t/sanity.t new file mode 100644 index 0000000..25c3d7e --- /dev/null +++ b/ngx_postgres-1.0/t/sanity.t @@ -0,0 +1,298 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 5); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + postgres_keepalive off; + } +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{02}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{02}\x{00}". # col name len +"id". # col name data +"\x{06}\x{80}". # std col type (varchar/str) +"\x{19}\x{00}". # driver col type +"\x{04}\x{00}". # col name len +"name". # col name data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"2". # field data +"\x{ff}\x{ff}\x{ff}\x{ff}". # field len +"". # field data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"3". # field data +"\x{03}\x{00}\x{00}\x{00}". # field len +"bob". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- no_error_log +[alert] +[error] + + + +=== TEST 2: keep-alive +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{02}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{02}\x{00}". # col name len +"id". # col name data +"\x{06}\x{80}". # std col type (varchar/str) +"\x{19}\x{00}". # driver col type +"\x{04}\x{00}". # col name len +"name". # col name data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"2". # field data +"\x{ff}\x{ff}\x{ff}\x{ff}". # field len +"". # field data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"3". # field data +"\x{03}\x{00}\x{00}\x{00}". # field len +"bob". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- no_error_log +[alert] +[error] + + + +=== TEST 3: update +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set name='bob' where name='bob'"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{01}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{01}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{00}\x{00}" # col count +--- timeout: 10 +--- no_error_log +[alert] +[error] + + + +=== TEST 4: select empty result +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats where name='tom'"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{02}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{02}\x{00}". # col name len +"id". # col name data +"\x{06}\x{80}". # std col type (varchar/str) +"\x{19}\x{00}". # driver col type +"\x{04}\x{00}". # col name len +"name". # col name data +"\x{00}" # row list terminator +--- timeout: 10 +--- no_error_log +[alert] +[error] + + + +=== TEST 5: variables in postgres_pass +--- http_config eval: $::http_config +--- config + location /postgres { + set $backend database; + postgres_pass $backend; + postgres_query "update cats set name='bob' where name='bob'"; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{01}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{01}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{00}\x{00}" # col count +--- timeout: 10 +--- no_error_log +[alert] +[error] + + + +=== TEST 6: HEAD request +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select * from cats"; + } +--- request +HEAD /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"" +--- timeout: 10 +--- no_error_log +[alert] +[error] + + + +=== TEST 7: "if" pseudo-location +--- http_config eval: $::http_config +--- config + location /postgres { + if ($arg_foo) { + postgres_pass database; + postgres_query "select * from cats"; + break; + } + + return 404; + } +--- request +GET /postgres?foo=1 +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{02}\x{00}". # col count +"\x{09}\x{00}". # std col type (integer/int) +"\x{17}\x{00}". # driver col type +"\x{02}\x{00}". # col name len +"id". # col name data +"\x{06}\x{80}". # std col type (varchar/str) +"\x{19}\x{00}". # driver col type +"\x{04}\x{00}". # col name len +"name". # col name data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"2". # field data +"\x{ff}\x{ff}\x{ff}\x{ff}". # field len +"". # field data +"\x{01}". # valid row flag +"\x{01}\x{00}\x{00}\x{00}". # field len +"3". # field data +"\x{03}\x{00}\x{00}\x{00}". # field len +"bob". # field data +"\x{00}" # row list terminator +--- timeout: 10 +--- no_error_log +[alert] +[error] diff --git a/ngx_postgres-1.0/t/variables.t b/ngx_postgres-1.0/t/variables.t new file mode 100644 index 0000000..8938411 --- /dev/null +++ b/ngx_postgres-1.0/t/variables.t @@ -0,0 +1,407 @@ +# vi:filetype=perl + +use lib 'lib'; +use Test::Nginx::Socket; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3 + 1 * 4 + 1 * 1 - 5 * 2); + +$ENV{TEST_NGINX_POSTGRESQL_HOST} ||= '127.0.0.1'; +$ENV{TEST_NGINX_POSTGRESQL_PORT} ||= 5432; + +our $http_config = <<'_EOC_'; + upstream database { + postgres_server $TEST_NGINX_POSTGRESQL_HOST:$TEST_NGINX_POSTGRESQL_PORT + dbname=ngx_test user=ngx_test password=ngx_test; + } +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_set $test 0 0; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Test: test +--- response_body eval +"\x{00}". # endian +"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3 +"\x{00}". # result type +"\x{00}\x{00}". # std errcode +"\x{02}\x{00}". # driver errcode +"\x{00}\x{00}". # driver errstr len +"". # driver errstr data +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected +"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id +"\x{01}\x{00}". # col count +"\x{00}\x{80}". # std col type (unknown/str) +"\x{c1}\x{02}". # driver col type +"\x{04}\x{00}". # col name len +"echo". # col name data +"\x{01}". # valid row flag +"\x{04}\x{00}\x{00}\x{00}". # field len +"test". # field data +"\x{00}" # row list terminator +--- timeout: 10 + + + +=== TEST 2: out-of-range value (optional) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_set $test 0 1; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +! X-Test +--- timeout: 10 + + + +=== TEST 3: NULL value (optional) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select NULL as echo"; + postgres_set $test 0 0; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +! X-Test +--- timeout: 10 + + + +=== TEST 4: zero-length value (optional) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select '' as echo"; + postgres_set $test 0 0; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +! X-Test +--- timeout: 10 + + + +=== TEST 5: out-of-range value (required) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_set $test 0 1 required; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 6: NULL value (required) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select NULL as echo"; + postgres_set $test 0 0 required; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 7: zero-length value (required) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select '' as echo"; + postgres_set $test 0 0 required; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 8: $postgres_columns +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'a', 'b', 'c'"; + add_header "X-Columns" $postgres_columns; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Columns: 3 +--- timeout: 10 + + + +=== TEST 9: $postgres_rows +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'a', 'b', 'c'"; + add_header "X-Rows" $postgres_rows; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Rows: 1 +--- timeout: 10 + + + +=== TEST 10: $postgres_query (simple value) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + add_header "X-Query" $postgres_query; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Query: select 'test' as echo +--- timeout: 10 + + + +=== TEST 11: $postgres_query (simple value) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select '$request_method' as echo"; + add_header "X-Query" $postgres_query; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Query: select 'GET' as echo +--- timeout: 10 + + + +=== TEST 12: variables used in non-ngx_postgres location +--- http_config +--- config + location /etc { + root /; + add_header "X-Columns" $postgres_columns; + add_header "X-Rows" $postgres_rows; + add_header "X-Affected" $postgres_affected; + add_header "X-Query" $postgres_query; + postgres_set $pg 0 0 required; + add_header "X-Custom" $pg; + } +--- request +GET /etc/passwd +--- error_code: 200 +--- response_headers +Content-Type: text/plain +! X-Columns +! X-Rows +! X-Affected +! X-Query +! X-Custom +--- timeout: 10 + + + +=== TEST 13: $postgres_affected (SELECT) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select '$request_method' as echo"; + add_header "X-Affected" $postgres_affected; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +! X-Affected +--- timeout: 10 + + + +=== TEST 14: $postgres_affected (UPDATE, no changes) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='noone'"; + add_header "X-Affected" $postgres_affected; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Affected: 0 +--- timeout: 10 + + + +=== TEST 15: $postgres_affected (UPDATE, one change) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "update cats set id=3 where name='bob'"; + add_header "X-Affected" $postgres_affected; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Affected: 1 +--- timeout: 10 + + + +=== TEST 16: inheritance +--- http_config eval: $::http_config +--- config + postgres_set $test 0 0 required; + + location /postgres { + postgres_pass database; + postgres_query "select NULL as echo"; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 + + + +=== TEST 17: inheritance (mixed, don't inherit) +--- http_config eval: $::http_config +--- config + postgres_set $test 0 0 required; + + location /postgres { + postgres_pass database; + postgres_query "select NULL as echo"; + postgres_set $test2 2 2; + add_header "X-Test" $test2; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +! X-Test +--- timeout: 10 + + + +=== TEST 18: column by name (existing) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_set $test 0 "echo"; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +X-Test: test +--- timeout: 10 + + + +=== TEST 19: column by name (not existing, optional) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_set $test 0 "test" optional; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 200 +--- response_headers +Content-Type: application/x-resty-dbd-stream +! X-Test +--- timeout: 10 + + + +=== TEST 20: column by name (not existing, required) +--- http_config eval: $::http_config +--- config + location /postgres { + postgres_pass database; + postgres_query "select 'test' as echo"; + postgres_set $test 0 "test" required; + add_header "X-Test" $test; + } +--- request +GET /postgres +--- error_code: 500 +--- timeout: 10 |