diff options
author | Marko Kreen | 2009-02-13 11:43:01 +0000 |
---|---|---|
committer | Marko Kreen | 2009-02-13 13:20:42 +0000 |
commit | 38cd6baf484c0d9219f8bf3628da3e1acc100224 (patch) | |
tree | 0f0dce8608b0e8960801d3e4425b81d0dce98e16 | |
parent | e9b2296f9c273beac1b8cab548d08398914e4de3 (diff) |
new tests for cascading
28 files changed, 661 insertions, 1 deletions
diff --git a/tests/cascade/addcol.sql b/tests/cascade/addcol.sql new file mode 100644 index 00000000..7a0aa69d --- /dev/null +++ b/tests/cascade/addcol.sql @@ -0,0 +1,3 @@ + +alter table mydata add column foodata text; + diff --git a/tests/cascade/conf/londiste_db1.ini b/tests/cascade/conf/londiste_db1.ini new file mode 100644 index 00000000..d4ce0595 --- /dev/null +++ b/tests/cascade/conf/londiste_db1.ini @@ -0,0 +1,8 @@ +[londiste] +job_name = londiste_db1 +db = dbname=db1 +queue_name = replika +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + + diff --git a/tests/cascade/conf/londiste_db2.ini b/tests/cascade/conf/londiste_db2.ini new file mode 100644 index 00000000..9e3417e1 --- /dev/null +++ b/tests/cascade/conf/londiste_db2.ini @@ -0,0 +1,8 @@ +[londiste] +job_name = londiste_db2 +db = dbname=db2 +queue_name = replika +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + + diff --git a/tests/cascade/conf/londiste_db3.ini b/tests/cascade/conf/londiste_db3.ini new file mode 100644 index 00000000..44d8104a --- /dev/null +++ b/tests/cascade/conf/londiste_db3.ini @@ -0,0 +1,8 @@ +[londiste] +job_name = londiste_db3 +db = dbname=db3 +queue_name = replika +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + + diff --git a/tests/cascade/conf/nop_consumer.ini b/tests/cascade/conf/nop_consumer.ini new file mode 100644 index 00000000..4cf8f985 --- /dev/null +++ b/tests/cascade/conf/nop_consumer.ini @@ -0,0 +1,12 @@ +[nop_consumer] + +job_name = nop_consumer + +#_provider_db = dbname=db1 +dst_db = dbname=db2 + +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + +queue_name = fooqueue + diff --git a/tests/cascade/conf/setadm.ini b/tests/cascade/conf/setadm.ini new file mode 100644 index 00000000..23b1026f --- /dev/null +++ b/tests/cascade/conf/setadm.ini @@ -0,0 +1,6 @@ +[cascade_admin] + +node_db = dbname=db2 + +queue_name = fooqueue + diff --git a/tests/cascade/conf/ticker_branch.ini b/tests/cascade/conf/ticker_branch.ini new file mode 100644 index 00000000..f2258d4f --- /dev/null +++ b/tests/cascade/conf/ticker_branch.ini @@ -0,0 +1,21 @@ +[pgqadm] + +job_name = ticker_branch + +db = dbname=db_branch + +# how often to run maintenance [minutes] +maint_delay_min = 1 + +# how often to check for activity [secs] +loop_delay = 0.5 + +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + +use_skylog = 0 + +connection_lifetime = 21 + +queue_refresh_period = 10 + diff --git a/tests/cascade/conf/ticker_db1.ini b/tests/cascade/conf/ticker_db1.ini new file mode 100644 index 00000000..2a422bbe --- /dev/null +++ b/tests/cascade/conf/ticker_db1.ini @@ -0,0 +1,7 @@ +[pgqadm] +job_name = ticker_db1 +db = dbname=db1 +loop_delay = 0.5 +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + diff --git a/tests/cascade/conf/ticker_db2.ini b/tests/cascade/conf/ticker_db2.ini new file mode 100644 index 00000000..2b3d38e8 --- /dev/null +++ b/tests/cascade/conf/ticker_db2.ini @@ -0,0 +1,7 @@ +[pgqadm] +job_name = ticker_db2 +db = dbname=db2 +loop_delay = 0.5 +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + diff --git a/tests/cascade/conf/ticker_db3.ini b/tests/cascade/conf/ticker_db3.ini new file mode 100644 index 00000000..337575c6 --- /dev/null +++ b/tests/cascade/conf/ticker_db3.ini @@ -0,0 +1,7 @@ +[pgqadm] +job_name = ticker_db3 +db = dbname=db3 +loop_delay = 0.5 +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + diff --git a/tests/cascade/conf/worker_db1.ini b/tests/cascade/conf/worker_db1.ini new file mode 100644 index 00000000..c3e3d302 --- /dev/null +++ b/tests/cascade/conf/worker_db1.ini @@ -0,0 +1,11 @@ +[nop_worker] + +job_name = node1_worker + +dst_db = dbname=db1 + +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + +queue_name = fooqueue + diff --git a/tests/cascade/conf/worker_db2.ini b/tests/cascade/conf/worker_db2.ini new file mode 100644 index 00000000..e77ca20a --- /dev/null +++ b/tests/cascade/conf/worker_db2.ini @@ -0,0 +1,11 @@ +[nop_worker] + +job_name = node2_worker + +dst_db = dbname=db2 + +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + +queue_name = fooqueue + diff --git a/tests/cascade/conf/worker_db3.ini b/tests/cascade/conf/worker_db3.ini new file mode 100644 index 00000000..b44aa7e6 --- /dev/null +++ b/tests/cascade/conf/worker_db3.ini @@ -0,0 +1,11 @@ +[nop_worker] + +job_name = node3_worker + +dst_db = dbname=db3 + +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid + +queue_name = fooqueue + diff --git a/tests/cascade/footable.sql b/tests/cascade/footable.sql new file mode 100644 index 00000000..83316627 --- /dev/null +++ b/tests/cascade/footable.sql @@ -0,0 +1,8 @@ + +create table footable ( + id serial primary key, + username text not null, + utype int4 not null check (utype in (1,2,3)) +); +create index uindex on footable (username); + diff --git a/tests/cascade/init.sh b/tests/cascade/init.sh new file mode 100755 index 00000000..19df887a --- /dev/null +++ b/tests/cascade/init.sh @@ -0,0 +1,26 @@ +#! /bin/sh + +. ../env.sh + +dropdb db1 +dropdb db2 +dropdb db3 + +createdb db1 +createdb db2 +createdb db3 + +pgqadm.py conf/ticker_db1.ini install +pgqadm.py conf/ticker_db2.ini install +pgqadm.py conf/ticker_db3.ini install + +lst="part1 part2 part3 part4 full1 full2 full3 full4" + +for db in $lst; do + echo dropdb $db + dropdb $db +done +for db in $lst; do + echo createdb $db + createdb $db +done diff --git a/tests/cascade/plainconsumer.py b/tests/cascade/plainconsumer.py new file mode 100755 index 00000000..81bad948 --- /dev/null +++ b/tests/cascade/plainconsumer.py @@ -0,0 +1,14 @@ +#! /usr/bin/env python + +import sys, time, skytools + +from pgq.cascade.consumer import CascadedConsumer + +class PlainCascadedConsumer(CascadedConsumer): + def process_remote_event(self, src_curs, dst_curs, ev): + ev.tag_done() + +if __name__ == '__main__': + script = PlainCascadedConsumer('nop_consumer', 'dst_db', sys.argv[1:]) + script.start() + diff --git a/tests/cascade/plainworker.py b/tests/cascade/plainworker.py new file mode 100755 index 00000000..48f00530 --- /dev/null +++ b/tests/cascade/plainworker.py @@ -0,0 +1,15 @@ +#! /usr/bin/env python + +import sys, time, skytools + +from pgq.cascade.worker import CascadedWorker + +class PlainCascadedWorker(CascadedWorker): + def process_remote_event(self, src_db, dst_db, ev): + self.log.info("got events: %s / %s" % (ev.ev_type, ev.ev_data)) + ev.tag_done() + +if __name__ == '__main__': + script = PlainCascadedWorker('nop_worker', 'dst_db', sys.argv[1:]) + script.start() + diff --git a/tests/cascade/regen.sh b/tests/cascade/regen.sh new file mode 100755 index 00000000..7baf2136 --- /dev/null +++ b/tests/cascade/regen.sh @@ -0,0 +1,137 @@ +#! /bin/sh + +. ../env.sh + +mkdir -p log pid + +./zstop.sh + +v= +v=-v +v=-q + +cleardb() { + psql -q -d $db -c ' + set client_min_messages=warning; + drop schema if exists londiste cascade; + drop schema if exists pgq_node cascade; + drop schema if exists pgq cascade; + drop table if exists mydata; + drop table if exists footable; + drop sequence if exists footable_id_seq; + ' +} + +run() { + echo "$ $*" + "$@" +} + +for db in db1 db2 db3; do + pgqadm.py conf/ticker_$db.ini -k + cleardb $db +done + +run ./plainconsumer.py -s conf/nop_consumer.ini + +rm -f log/*.log + +set -e + +run cat conf/ticker_db1.ini + +#echo " # pgqadm install # " +run pgqadm.py $v conf/ticker_db1.ini install +run pgqadm.py $v conf/ticker_db2.ini install +run pgqadm.py $v conf/ticker_db3.ini install + +#echo " # pgqadm ticker # " +run pgqadm.py $v -d conf/ticker_db1.ini ticker +run pgqadm.py $v -d conf/ticker_db2.ini ticker +run pgqadm.py $v -d conf/ticker_db3.ini ticker + +if false; then + +#echo " # setadm create-node # " +run setadm.py $v --worker=node1_worker conf/setadm.ini create-root node1 'dbname=db1' +run setadm.py $v --worker=node2_worker conf/setadm.ini create-branch node2 'dbname=db2' --provider='dbname=db1' +run setadm.py $v --worker=node3_worker conf/setadm.ini create-branch node3 'dbname=db3' --provider='dbname=db2' + +#echo " # setadm status # " +run setadm.py $v conf/setadm.ini status + +#echo " # plainconsumer # " +run ./plainconsumer.py $v conf/nop_consumer.ini --register --provider='dbname=db1' +run ./plainconsumer.py $v -d conf/nop_consumer.ini + +#echo " # plainworker # " +run ./plainworker.py $v -d conf/worker_db1.ini +run ./plainworker.py $v -d conf/worker_db2.ini +run ./plainworker.py $v -d conf/worker_db3.ini + + +#echo " # insert_event() # " +run psql db1 -c "select pgq.insert_event('fooqueue', 'tmp', 'data')" + +fi + +grep -E 'ERR|WARN|CRIT' log/*.log || true + +#exit 0 + +# -- londiste + +for db in db1 db2 db3; do + run psql $db -c "create table mydata (id serial primary key, data text)" +done + +run cat conf/londiste_db1.ini + +run londiste.py $v conf/londiste_db1.ini create-root rnode1 'dbname=db1' +run londiste.py $v conf/londiste_db2.ini create-branch rnode2 'dbname=db2' --provider='dbname=db1' +run londiste.py $v conf/londiste_db3.ini create-branch rnode3 'dbname=db3' --provider='dbname=db2' + +run londiste.py $v -d conf/londiste_db1.ini replay +run londiste.py $v -d conf/londiste_db2.ini replay +run londiste.py $v -d conf/londiste_db3.ini replay + +run londiste.py $v conf/londiste_db1.ini add-table mydata +run londiste.py $v conf/londiste_db2.ini add-table mydata +run londiste.py $v conf/londiste_db3.ini add-table mydata + +run cat addcol.sql +run londiste.py $v conf/londiste_db1.ini execute addcol.sql + +run sleep 10 +run psql db3 -c '\d mydata' + +run londiste.py $v conf/londiste_db1.ini status +run londiste.py $v conf/londiste_db3.ini change-provider --provider=rnode1 +run londiste.py $v conf/londiste_db1.ini status +run londiste.py $v conf/londiste_db1.ini switchover --target=rnode2 +run londiste.py $v conf/londiste_db1.ini status + +run cat footable.sql + +run psql db2 -f footable.sql +run londiste.py $v conf/londiste_db2.ini add-seq footable_id_seq +run londiste.py $v conf/londiste_db2.ini add-table footable +run londiste.py $v conf/londiste_db1.ini add-seq footable_id_seq --create +run londiste.py $v conf/londiste_db1.ini add-table footable --create +run londiste.py $v conf/londiste_db3.ini add-seq footable_id_seq --create +run londiste.py $v conf/londiste_db3.ini add-table footable --create + +#run psql db2 -f footable.sql +#run londiste.py $v conf/londiste_db2.ini add-seq footable_id_seq +#run londiste.py $v conf/londiste_db2.ini add-table footable +#run londiste.py $v conf/londiste_db2.ini add-seq footable_id_seq --create +#run londiste.py $v conf/londiste_db1.ini add-table footable --create +#run londiste.py $v conf/londiste_db2.ini add-seq footable_id_seq --create +#run londiste.py $v conf/londiste_db3.ini add-table footable --create + +run psql db3 -c '\d footable' + +sleep 3 + +grep -E 'ERR|WARN|CRIT' log/*.log || echo "All OK" + diff --git a/tests/cascade/status.sh b/tests/cascade/status.sh new file mode 100755 index 00000000..9ff9d8d2 --- /dev/null +++ b/tests/cascade/status.sh @@ -0,0 +1,11 @@ +#! /bin/sh + +. ../env.sh + +pgqadm.py conf/ticker_db1.ini status +pgqadm.py conf/ticker_db2.ini status +pgqadm.py conf/ticker_db3.ini status + +setadm.py -v conf/setadm.ini status + + diff --git a/tests/cascade/zcheck.sh b/tests/cascade/zcheck.sh new file mode 100755 index 00000000..96f59aed --- /dev/null +++ b/tests/cascade/zcheck.sh @@ -0,0 +1,4 @@ +#! /bin/sh + +grep -E 'ERR|WARN|CRIT' log/*.log || echo "All OK" + diff --git a/tests/cascade/zstop.sh b/tests/cascade/zstop.sh new file mode 100755 index 00000000..69e574cb --- /dev/null +++ b/tests/cascade/zstop.sh @@ -0,0 +1,14 @@ +#! /bin/sh + +#. ../env.sh + +for p in pid/*.pid*; do + test -f "$p" || continue + pid=`cat "$p"` + test -d "/proc/$pid" || { + rm -f "$p" + continue + } + kill "$pid" +done + diff --git a/tests/cascade/ztest.sh b/tests/cascade/ztest.sh new file mode 100755 index 00000000..7ef0e79a --- /dev/null +++ b/tests/cascade/ztest.sh @@ -0,0 +1,7 @@ +#! /bin/sh + +. ../env.sh + +./plainconsumer.py -v conf/nop_consumer.ini --register +./plainconsumer.py -v conf/nop_consumer.ini + diff --git a/tests/env.sh b/tests/env.sh index 11d82a3c..d344ffcf 100644 --- a/tests/env.sh +++ b/tests/env.sh @@ -1,6 +1,8 @@ PYTHONPATH=../../python:$PYTHONPATH PATH=../../python:../../python/bin:../../scripts:$PATH -export PYTHONPATH PATH +#LD_LIBRARY_PATH=/opt/apps/py26/lib:$LD_LIBRARY_PATH +#PATH=/opt/apps/py26/bin:$PATH +export PYTHONPATH PATH LD_LIBRARY_PATH PATH diff --git a/tests/merge/init.sh b/tests/merge/init.sh new file mode 100755 index 00000000..3f992dc9 --- /dev/null +++ b/tests/merge/init.sh @@ -0,0 +1,14 @@ +#! /bin/sh + +. ../env.sh + +lst="part1 part2 part3 part4 full1 full2 full3 full4" + +for db in $lst; do + echo dropdb $db + dropdb $db +done +for db in $lst; do + echo createdb $db + createdb $db +done diff --git a/tests/merge/regen.sh b/tests/merge/regen.sh new file mode 100755 index 00000000..fad7463a --- /dev/null +++ b/tests/merge/regen.sh @@ -0,0 +1,173 @@ +#! /bin/sh + +. ../env.sh + +mkdir -p log pid conf + +./zstop.sh + +v= +v=-q +v=-v + +cleardb() { + echo "Clearing database $1" + psql -q -d $1 -c ' + set client_min_messages=warning; + drop schema if exists londiste cascade; + drop schema if exists pgq_node cascade; + drop schema if exists pgq cascade; + drop table if exists mydata; + drop table if exists footable; + drop sequence if exists footable_id_seq; + ' +} + +run() { + echo "$ $*" + "$@" +} + +part_list="part1 part2 part3 part4" +full_list="full1 full2 full3 full4" +merge_list="" +for dst in $full_list; do + for src in $part_list; do + merge_list="$merge_list ${src}_${dst}" + done +done +all_list="$part_list $full_list" + +echo " * create configs * " + +# create ticker conf +for db in $all_list; do +cat > conf/ticker_$db.ini << EOF +[pgqadm] +job_name = ticker_$db +db = dbname=$db +loop_delay = 0.5 +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid +EOF +done + +# partition replicas +for db in $part_list; do + +# londiste on part node +cat > conf/londiste_$db.ini << EOF +[londiste] +job_name = londiste_$db +db = dbname=$db +queue_name = replika_$db +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid +EOF + +# londiste on combined nodes +for dst in full1 full2; do +cat > conf/londiste_${db}_${dst}.ini << EOF +[londiste] +job_name = londiste_${db}_${dst} +db = dbname=$dst +queue_name = replika_$db +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid +EOF + +done +done + +# full replicas +for db in $full_list; do + +cat > conf/londiste_$db.ini << EOF +[londiste] +job_name = londiste_$db +db = dbname=$db +queue_name = replika +logfile = log/%(job_name)s.log +pidfile = pid/%(job_name)s.pid +EOF + +done + + + +for db in $part_list $full_list; do + cleardb $db +done + +echo "clean logs" +rm -f log/*.log + +set -e + +for db in $all_list; do + run pgqadm.py $v conf/ticker_$db.ini install +done + +run londiste.py $v conf/londiste_full1.ini create-root fnode1 'dbname=full1' +run londiste.py $v conf/londiste_full2.ini create-branch fnode2 'dbname=full2' --provider='dbname=full1' +run londiste.py $v conf/londiste_full3.ini create-branch fnode3 'dbname=full3' --provider='dbname=full1' +run londiste.py $v conf/londiste_full4.ini create-leaf fnode4 'dbname=full4' --provider='dbname=full2' + +run londiste.py $v conf/londiste_part1.ini create-root p1root 'dbname=part1' +run londiste.py $v conf/londiste_part2.ini create-root p2root 'dbname=part2' +run londiste.py $v conf/londiste_part3.ini create-root p3root 'dbname=part3' +run londiste.py $v conf/londiste_part4.ini create-root p4root 'dbname=part4' + + +for dst in full1 full2; do + for src in $part_list; do + run londiste.py $v conf/londiste_${src}_${dst}.ini \ + create-leaf merge_${src}_${dst} "dbname=$dst" \ + --provider="dbname=$src" --merge="replika" + done +done + +for db in $all_list; do + run pgqadm.py $v -d conf/ticker_$db.ini ticker + run londiste.py $v -d conf/londiste_$db.ini replay +done + +for dst in full1 full2; do + for src in $part_list; do + run londiste.py $v -d conf/londiste_${src}_${dst}.ini replay + done +done + +for db in $part_list; do + run psql $db -c "create table mydata (id int4 primary key, data text)" + run londiste.py $v conf/londiste_$db.ini add-table mydata +done +for n in 1 2 3 4; do + run psql -d part$n -c "insert into mydata values ($n, 'part$n')" +done + +for db in full1; do + run psql $db -c "create table mydata (id int4 primary key, data text)" + run londiste.py $v conf/londiste_$db.ini add-table mydata + for src in $part_list; do + run londiste.py $v conf/londiste_${src}_${db}.ini add-table mydata + done +done + +run sleep 10 + +for n in 1 2 3 4; do + run psql -d part$n -c "insert into mydata values (4 + $n, 'part$n')" +done + +run sleep 10 + +for db in full1; do +run psql -d $db -c "select * from mydata order by id" +run psql -d $db -c "select * from londiste.table_info order by queue_name" +done +run psql -d full1 -c "select * from londiste.get_table_list('replika_part1')" +run psql -d full1 -c "select * from londiste.get_table_list('replika_part2')" + +./zcheck.sh + diff --git a/tests/merge/zcheck.sh b/tests/merge/zcheck.sh new file mode 100755 index 00000000..96f59aed --- /dev/null +++ b/tests/merge/zcheck.sh @@ -0,0 +1,4 @@ +#! /bin/sh + +grep -E 'ERR|WARN|CRIT' log/*.log || echo "All OK" + diff --git a/tests/merge/zstop.sh b/tests/merge/zstop.sh new file mode 100755 index 00000000..69e574cb --- /dev/null +++ b/tests/merge/zstop.sh @@ -0,0 +1,14 @@ +#! /bin/sh + +#. ../env.sh + +for p in pid/*.pid*; do + test -f "$p" || continue + pid=`cat "$p"` + test -d "/proc/$pid" || { + rm -f "$p" + continue + } + kill "$pid" +done + diff --git a/tests/quoting/regtest.py b/tests/quoting/regtest.py new file mode 100755 index 00000000..bbe85c74 --- /dev/null +++ b/tests/quoting/regtest.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python + +import sys, time +import skytools.psycopgwrapper +import skytools._cquoting, skytools._pyquoting +from decimal import Decimal + +# create a DictCursor row +class fake_cursor: + index = {'id': 0, 'data': 1} + description = ['x', 'x'] +dbrow = skytools.psycopgwrapper._CompatRow(fake_cursor()) +dbrow[0] = '123' +dbrow[1] = 'value' + +def regtest(name, func, cases): + bad = 0 + for dat, res in cases: + res2 = func(dat) + if res != res2: + print("failure: %s(%s) = %s (expected %s)" % (name, repr(dat), repr(res2), repr(res))) + bad += 1 + if bad: + print("%-20s: failed" % name) + else: + print("%-20s: OK" % name) + + +sql_literal = [ + [None, "null"], + ["", "''"], + ["a'b", "'a''b'"], + [r"a\'b", r"E'a\\''b'"], + [1, "'1'"], + [True, "'True'"], + [Decimal(1), "'1'"], +] +regtest("quote_literal/c", skytools._cquoting.quote_literal, sql_literal) +regtest("quote_literal/py", skytools._pyquoting.quote_literal, sql_literal) + +sql_copy = [ + [None, "\\N"], + ["", ""], + ["a'\tb", "a'\\tb"], + [r"a\'b", r"a\\'b"], + [1, "1"], + [True, "True"], + [u"qwe", "qwe"], + [Decimal(1), "1"], +] +regtest("quote_copy/c", skytools._cquoting.quote_copy, sql_copy) +regtest("quote_copy/py", skytools._pyquoting.quote_copy, sql_copy) + +sql_bytea_raw = [ + [None, None], + ["", ""], + ["a'\tb", "a'\\011b"], + [r"a\'b", r"a\\'b"], + ["\t\344", r"\011\344"], +] +regtest("quote_bytea_raw/c", skytools._cquoting.quote_bytea_raw, sql_bytea_raw) +regtest("quote_bytea_raw/py", skytools._pyquoting.quote_bytea_raw, sql_bytea_raw) + +t_urlenc = [ + [{}, ""], + [{'a': 1}, "a=1"], + [{'a': None}, "a"], + [{'qwe': 1, u'zz': u"qwe"}, "qwe=1&zz=qwe"], + [{'a': '\000%&'}, "a=%00%25%26"], + [dbrow, 'data=value&id=123'], + [{'a': Decimal("1")}, "a=1"], +] +regtest("db_urlencode/c", skytools._cquoting.db_urlencode, t_urlenc) +regtest("db_urlencode/py", skytools._pyquoting.db_urlencode, t_urlenc) + +t_urldec = [ + ["", {}], + ["a=b&c", {'a': 'b', 'c': None}], + ["&&b=f&&", {'b': 'f'}], + [u"abc=qwe", {'abc': 'qwe'}], + ["b=", {'b': ''}], + ["b=%00%45", {'b': '\x00E'}], +] +regtest("db_urldecode/c", skytools._cquoting.db_urldecode, t_urldec) +regtest("db_urldecode/py", skytools._pyquoting.db_urldecode, t_urldec) + +t_unesc = [ + ["", ""], + ["\\N", "N"], + ["abc", "abc"], + [u"abc", "abc"], + [r"\0\000\001\01\1", "\0\000\001\001\001"], + [r"a\001b\tc\r\n", "a\001b\tc\r\n"], +] +regtest("unescape/c", skytools._cquoting.unescape, t_unesc) +regtest("unescape/py", skytools._pyquoting.unescape, t_unesc) + |