Mercurial > hg > monetdb-java
diff tests/tests.md @ 789:88c5b678e974 monetdbs
URL parser passes the tests.
Some tests had to change to accomodate Java.
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Wed, 29 Nov 2023 13:28:52 +0100 (16 months ago) |
parents | |
children | 547eca89fc5e |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/tests/tests.md @@ -0,0 +1,1458 @@ +# Tests + +This document contains a large number of test cases. +They are embedded in the Markdown source, in <code>```test</code> +. . .</code>```</code> blocks. + + +The tests are written in a mini language with the following +keywords: + +* `PARSE url`: parse the URL, this should succeed. The validity checks need + not be satisfied. + +* `ACCEPT url`: parse the URL, this should succeed. The validity checks + should pass. + +* `REJECT url`: parse the URL, it should be rejected either in the parsing stage + or by the validity checks. + +* `SET key=value`: modify a parameter, can occur before or after parsing the URL. + Used to model command line parameters, Java Properties objects, etc. + +* `EXPECT key=value`: verify that the given parameter now has the given + value. Fail the test case if the value is different. + +* `ONLY pymonetdb`: only process the rest of the block when testing + pymonetdb, ignore it for other implementations. + +* `NOT pymonetdb`: ignore the rest of the block when testing pymonetdb, + do process it for other implementations. + +At the start of each block the parameters are reset to their default values. + +The EXPECT clause can verify all parameters listen in the Parameters section of +the spec, all 'virtual parameters' and also the special case `valid` which is a +boolean indicating whether all validity rules in section 'Interpreting the +parameters' hold. + +Note: an `EXPECT` of the virtual parameters implies `EXPECT valid=true`. + +TODO before 1.0 does the above explanation make sense? + + +## Tests from the examples + +```test +ACCEPT monetdb:///demo +EXPECT database=demo +EXPECT connect_scan=true +``` + +```test +ACCEPT monetdb://localhost/demo +EXPECT connect_scan=true +EXPECT database=demo +``` + +```test +ACCEPT monetdb://localhost./demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=localhost +EXPECT connect_port=50000 +EXPECT tls=off +EXPECT database=demo +``` + +```test +ACCEPT monetdb://localhost.:12345/demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=localhost +EXPECT connect_port=12345 +EXPECT tls=off +EXPECT database=demo +``` + +```test +ACCEPT monetdb://localhost:12345/demo +EXPECT connect_scan=false +EXPECT connect_unix=/tmp/.s.monetdb.12345 +EXPECT connect_tcp=localhost +EXPECT connect_port=12345 +EXPECT tls=off +EXPECT database=demo +``` + +```test +ACCEPT monetdb:///demo?user=monetdb&password=monetdb +EXPECT connect_scan=true +EXPECT database=demo +EXPECT user=monetdb +EXPECT password=monetdb +``` + +```test +ACCEPT monetdb://mdb.example.com:12345/demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=mdb.example.com +EXPECT connect_port=12345 +EXPECT tls=off +EXPECT database=demo +``` + +```test +ACCEPT monetdb://192.168.13.4:12345/demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=192.168.13.4 +EXPECT connect_port=12345 +EXPECT tls=off +EXPECT database=demo +``` + +```test +ACCEPT monetdb://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:12345/demo +EXPECT host=2001:0db8:85a3:0000:0000:8a2e:0370:7334 +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=2001:0db8:85a3:0000:0000:8a2e:0370:7334 +EXPECT connect_port=12345 +EXPECT tls=off +EXPECT database=demo +``` + +```test +ACCEPT monetdb://localhost/ +EXPECT connect_unix=/tmp/.s.monetdb.50000 +EXPECT connect_scan=false +EXPECT connect_tcp=localhost +EXPECT tls=off +EXPECT database= +``` + +```test +ACCEPT monetdb://localhost +EXPECT connect_scan=false +EXPECT connect_unix=/tmp/.s.monetdb.50000 +EXPECT connect_tcp=localhost +EXPECT tls=off +EXPECT database= +``` + +```test +ACCEPT monetdbs://mdb.example.com/demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=mdb.example.com +EXPECT connect_port=50000 +EXPECT tls=on +EXPECT connect_tls_verify=system +EXPECT database=demo +``` + +```test +ACCEPT monetdbs:///demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=localhost +EXPECT connect_port=50000 +EXPECT tls=on +EXPECT connect_tls_verify=system +EXPECT database=demo +``` + +```test +ACCEPT monetdbs://mdb.example.com/demo?cert=/home/user/server.crt +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=mdb.example.com +EXPECT connect_port=50000 +EXPECT tls=on +EXPECT connect_tls_verify=cert +EXPECT cert=/home/user/server.crt +EXPECT database=demo +``` + +```test +ACCEPT monetdbs://mdb.example.com/demo?certhash=sha256:fb:67:20:aa:00:9f:33:4c +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=mdb.example.com +EXPECT connect_port=50000 +EXPECT tls=on +EXPECT connect_tls_verify=hash +EXPECT certhash=sha256:fb:67:20:aa:00:9f:33:4c +EXPECT connect_certhash_digits=fb6720aa009f334c +EXPECT database=demo +``` + +```test +ACCEPT monetdb:///demo?sock=/var/monetdb/_sock&user=dbuser +EXPECT connect_scan=false +EXPECT connect_unix=/var/monetdb/_sock +EXPECT connect_tcp= +EXPECT tls=off +EXPECT database=demo +EXPECT user=dbuser +EXPECT password= +``` + +```test +ACCEPT monetdb://localhost/demo?sock=/var/monetdb/_sock&user=dbuser +EXPECT connect_scan=false +EXPECT connect_unix=/var/monetdb/_sock +EXPECT connect_tcp= +EXPECT tls=off +EXPECT database=demo +EXPECT user=dbuser +EXPECT password= +``` + + +## Parameter tests + +Tests derived from the parameter section. Test data types and defaults. + +Everything can be SET and EXPECTed + +```test +SET tls=on +EXPECT tls=on +SET host=bananahost +EXPECT host=bananahost +SET port=123 +EXPECT port=123 +SET database=bananadatabase +EXPECT database=bananadatabase +SET tableschema=bananatableschema +EXPECT tableschema=bananatableschema +SET table=bananatable +EXPECT table=bananatable +SET sock=c:\foo.txt +EXPECT sock=c:\foo.txt +SET cert=c:\foo.txt +EXPECT cert=c:\foo.txt +SET certhash=bananacerthash +EXPECT certhash=bananacerthash +SET clientkey=c:\foo.txt +EXPECT clientkey=c:\foo.txt +SET clientcert=c:\foo.txt +EXPECT clientcert=c:\foo.txt +SET user=bananauser +EXPECT user=bananauser +SET password=bananapassword +EXPECT password=bananapassword +SET language=bananalanguage +EXPECT language=bananalanguage +SET autocommit=on +EXPECT autocommit=on +SET schema=bananaschema +EXPECT schema=bananaschema +SET timezone=123 +EXPECT timezone=123 +SET binary=bananabinary +EXPECT binary=bananabinary +SET replysize=123 +EXPECT replysize=123 +SET fetchsize=123 +EXPECT fetchsize=123 +``` + +### core defaults + +```test +EXPECT tls=false +EXPECT host= +EXPECT port=-1 +EXPECT database= +EXPECT tableschema= +EXPECT table= +EXPECT binary=on +``` + +### sock + +Not supported on Windows, but they should still parse. + +```test +EXPECT sock= +ACCEPT monetdb:///?sock=/tmp/sock +EXPECT sock=/tmp/sock +ACCEPT monetdb:///?sock=C:/TEMP/sock +EXPECT sock=C:/TEMP/sock +NOT jdbc +ACCEPT monetdb:///?sock=C:\TEMP\sock +EXPECT sock=C:\TEMP\sock +``` + +### sockdir + +```test +EXPECT sockdir=/tmp +ACCEPT monetdb:///demo?sockdir=/tmp/nonstandard +EXPECT sockdir=/tmp/nonstandard +EXPECT connect_unix=/tmp/nonstandard/.s.monetdb.50000 +``` + +### cert + +```test +EXPECT cert= +ACCEPT monetdbs:///?cert=/tmp/cert.pem +EXPECT cert=/tmp/cert.pem +ACCEPT monetdbs:///?cert=C:/TEMP/cert.pem +EXPECT cert=C:/TEMP/cert.pem +NOT jdbc +ACCEPT monetdbs:///?cert=C:\TEMP\cert.pem +EXPECT cert=C:\TEMP\cert.pem +``` + +### certhash + +```test +EXPECT certhash= +ACCEPT monetdbs:///?certhash=sha256:001122ff +ACCEPT monetdbs:///?certhash=sha256:00:11:22:ff +ACCEPT monetdbs:///?certhash=sha256:::::aa::ff::::: +ACCEPT monetdbs:///?certhash=sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +``` + +This string of hexdigits is longer than the length of a SHA-256 digest. +It still parses, it will just never match. + +```test +ACCEPT monetdbs:///?certhash=sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8550 +ACCEPT monetdbs:///?certhash=sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855000000000000000000000000000000000000000001 +``` + +```test +REJECT monetdbs:///?certhash=001122ff +REJECT monetdbs:///?certhash=Sha256:001122ff +REJECT monetdbs:///?certhash=sha256:001122gg +REJECT monetdbs:///?certhash=sha +REJECT monetdbs:///?certhash=sha1:aabbcc +REJECT monetdbs:///?certhash=sha1: +REJECT monetdbs:///?certhash=sha1:X +REJECT monetdbs:///?certhash=sha99:aabbcc +REJECT monetdbs:///?certhash=sha99: +REJECT monetdbs:///?certhash=sha99:X +``` + +### clientkey, clientcert + +```test +EXPECT clientkey= +EXPECT clientcert= +ACCEPT monetdbs:///?clientkey=/tmp/clientkey.pem +EXPECT clientkey=/tmp/clientkey.pem +ACCEPT monetdbs:///?clientkey=C:/TEMP/clientkey.pem +EXPECT clientkey=C:/TEMP/clientkey.pem +NOT jdbc +ACCEPT monetdbs:///?clientkey=C:\TEMP\clientkey.pem +EXPECT clientkey=C:\TEMP\clientkey.pem +``` + +```test +EXPECT connect_clientkey= +EXPECT connect_clientcert= +``` + +```test +SET clientkey=/tmp/key.pem +SET clientcert=/tmp/cert.pem +EXPECT valid=true +EXPECT connect_clientkey=/tmp/key.pem +EXPECT connect_clientcert=/tmp/cert.pem +``` + +```test +SET clientkey=/tmp/key.pem +EXPECT valid=true +EXPECT connect_clientkey=/tmp/key.pem +EXPECT connect_clientcert=/tmp/key.pem +``` + +```test +SET clientcert=/tmp/cert.pem +EXPECT valid=false +``` + +```test +SET clientkey=dummy +EXPECT clientcert= +ACCEPT monetdbs:///?clientcert=/tmp/clientcert.pem +EXPECT clientcert=/tmp/clientcert.pem +ACCEPT monetdbs:///?clientcert=C:/TEMP/clientcert.pem +EXPECT clientcert=C:/TEMP/clientcert.pem +NOT jdbc +ACCEPT monetdbs:///?clientcert=C:\TEMP\clientcert.pem +EXPECT clientcert=C:\TEMP\clientcert.pem +``` + +### user, password + +Not testing the default because they are (unfortunately) +implementation specific. + +```test +ACCEPT monetdb:///?user=monetdb +EXPECT user=monetdb +ACCEPT monetdb:///?user=me&password=? +EXPECT user=me +EXPECT password=? +``` + +### language + +```test +EXPECT language=sql +ACCEPT monetdb:///?language=msql +EXPECT language=msql +ACCEPT monetdb:///?language=sql +EXPECT language=sql +``` + +### autocommit + +```test +ACCEPT monetdb:///?autocommit=true +EXPECT autocommit=true +ACCEPT monetdb:///?autocommit=on +EXPECT autocommit=true +ACCEPT monetdb:///?autocommit=yes +EXPECT autocommit=true +``` + +```test +ACCEPT monetdb:///?autocommit=false +EXPECT autocommit=false +ACCEPT monetdb:///?autocommit=off +EXPECT autocommit=false +ACCEPT monetdb:///?autocommit=no +EXPECT autocommit=false +``` + +```test +REJECT monetdb:///?autocommit= +REJECT monetdb:///?autocommit=banana +REJECT monetdb:///?autocommit=0 +REJECT monetdb:///?autocommit=1 +``` + +### schema, timezone + +Must be accepted, no constraints on content + +```test +EXPECT schema= +ACCEPT monetdb:///?schema=foo +EXPECT schema=foo +ACCEPT monetdb:///?schema= +EXPECT schema= +ACCEPT monetdb:///?schema=foo +``` + +```test +ACCEPT monetdb:///?timezone=0 +EXPECT timezone=0 +ACCEPT monetdb:///?timezone=120 +EXPECT timezone=120 +ACCEPT monetdb:///?timezone=-120 +EXPECT timezone=-120 +REJECT monetdb:///?timezone=banana +REJECT monetdb:///?timezone= +``` + +### replysize and fetchsize + +Note we never check `EXPECT fetchsize=`, it doesn't exist. + +```test +ACCEPT monetdb:///?replysize=150 +EXPECT replysize=150 +ACCEPT monetdb:///?fetchsize=150 +EXPECT replysize=150 +ACCEPT monetdb:///?fetchsize=100&replysize=200 +EXPECT replysize=200 +ACCEPT monetdb:///?replysize=100&fetchsize=200 +EXPECT replysize=200 +REJECT monetdb:///?replysize= +REJECT monetdb:///?fetchsize= +``` + +### binary + +```test +EXPECT binary=on +EXPECT connect_binary=65535 +``` + +```test +ACCEPT monetdb:///?binary=on +EXPECT connect_binary=65535 + +ACCEPT monetdb:///?binary=yes +EXPECT connect_binary=65535 + +ACCEPT monetdb:///?binary=true +EXPECT connect_binary=65535 + +ACCEPT monetdb:///?binary=yEs +EXPECT connect_binary=65535 +``` + +```test +ACCEPT monetdb:///?binary=off +EXPECT connect_binary=0 + +ACCEPT monetdb:///?binary=no +EXPECT connect_binary=0 + +ACCEPT monetdb:///?binary=false +EXPECT connect_binary=0 +``` + +```test +ACCEPT monetdb:///?binary=0 +EXPECT connect_binary=0 + +ACCEPT monetdb:///?binary=5 +EXPECT connect_binary=5 + +ACCEPT monetdb:///?binary=0100 +EXPECT connect_binary=100 +``` + +```test +REJECT monetdb:///?binary= +REJECT monetdb:///?binary=-1 +REJECT monetdb:///?binary=1.0 +REJECT monetdb:///?binary=banana +``` + +### unknown parameters + +```test +REJECT monetdb:///?banana=bla +``` + +```test +ACCEPT monetdb:///?ban_ana=bla +ACCEPT monetdb:///?hash=sha1 +ACCEPT monetdb:///?debug=true +ACCEPT monetdb:///?logfile=banana +``` + +Unfortunately we can't easily test that it won't allow us +to SET banana. + +```test +SET ban_ana=bla +SET hash=sha1 +SET debug=true +SET logfile=banana +``` + +## Combining sources + +The defaults have been tested in the previous section. + +Rule: If there is overlap, later sources take precedence. + +```test +SET schema=a +ACCEPT monetdb:///db1?schema=b +EXPECT schema=b +EXPECT database=db1 +EXPECT tls=off +ACCEPT monetdbs:///db2?schema=c +EXPECT tls=on +EXPECT database=db2 +EXPECT schema=c +``` + +Rule: a source that sets user must set password or clear. + +```skiptest +ACCEPT monetdb:///?user=foo +EXPECT user=foo +EXPECT password= +SET password=banana +EXPECT user=foo +EXPECT password=banana +SET user=bar +EXPECT password= +``` + +Rule: fetchsize is an alias for replysize, last occurrence counts + +```test +SET replysize=200 +ACCEPT monetdb:///?fetchsize=400 +EXPECT replysize=400 +ACCEPT monetdb:///?replysize=500&fetchsize=600 +EXPECT replysize=600 +``` + +```test +NOT jdbc +SET replysize=200 +SET fetchsize=300 +EXPECT replysize=300 +``` + + + +Rule: parsing a URL sets all of tls, host, port and database +even if left out of the URL + +```test +SET tls=on +SET host=banana +SET port=12345 +SET database=foo +SET timezone=120 +ACCEPT monetdb:/// +EXPECT tls=off +EXPECT host= +EXPECT port=-1 +EXPECT database= +``` + +```test +SET tls=on +SET host=banana +SET port=12345 +SET database=foo +SET timezone=120 +ACCEPT monetdb://dbhost/dbdb +EXPECT tls=off +EXPECT host=dbhost +EXPECT port=-1 +EXPECT database=dbdb +``` + +Careful around passwords + +```test +SET user=alan +SET password=turing +ACCEPT monetdbs:/// +EXPECT user=alan +EXPECT password=turing +``` + +```test +SET user=alan +SET password=turing +ACCEPT monetdbs:///?user=mathison +EXPECT user=mathison +EXPECT password= +``` + +The rule is, "if **user** is set", not "if **user** is changed". + +```test +SET user=alan +SET password=turing +ACCEPT monetdbs:///?user=alan +EXPECT user=alan +EXPECT password= +``` + +## URL syntax + +General form + +```test +REJECT monetdb: +REJECT monetdbs: +REJECT monetdb:/ +REJECT monetdbs:/ +REJECT monetdb:// +REJECT monetdbs:// +ACCEPT monetdb:/// +ACCEPT monetdbs:/// +``` + + +```test +ACCEPT monetdb://host:12345/db1/schema2/table3?user=mr&password=bean +EXPECT tls=off +EXPECT host=host +EXPECT port=12345 +EXPECT database=db1 +EXPECT tableschema=schema2 +EXPECT table=table3 +EXPECT user=mr +EXPECT password=bean +``` + +Also, TLS and percent-escapes + +```test +ACCEPT monetdbs://h%6Fst:12345/db%31/schema%32/table%33?user=%6Dr&p%61ssword=bean +EXPECT tls=on +EXPECT host=host +EXPECT port=12345 +EXPECT database=db1 +EXPECT tableschema=schema2 +EXPECT table=table3 +EXPECT user=mr +EXPECT password=bean +``` + +Port number + +```test +REJECT monetdb://banana:0/ +REJECT monetdb://banana:-1/ +REJECT monetdb://banana:65536/ +REJECT monetdb://banana:100000/ +``` + +Trailing slash can be left off + +```test +ACCEPT monetdb://host?user=claude&password=m%26ms +EXPECT host=host +EXPECT user=claude +EXPECT password=m&ms +``` + +Error to set tls, host, port, database, tableschema and table as query parameters. + +```test +REJECT monetdb://foo:1/bar?tls=off +REJECT monetdb://foo:1/bar?host=localhost +REJECT monetdb://foo:1/bar?port=12345 +REJECT monetdb://foo:1/bar?database=allmydata +REJECT monetdb://foo:1/bar?tableschema=banana +REJECT monetdb://foo:1/bar?table=tabularity +``` + +Last wins, already tested elsewhere but for completeness + +```test +ACCEPT monetdbs:///?timezone=10&timezone=20 +EXPECT timezone=20 +``` + +Interesting case: setting user must clear the password but does +that also happen with repetitions within a URL? +Not sure. For the time being, no. This makes it easier for +situations where for example the query parameters come in +alphabetical order + +```test +ACCEPT monetdb:///?user=foo&password=banana&user=bar +EXPECT user=bar +EXPECT password=banana +``` + +Similar but even simpler: user comes after password but does not +clear it. + +```test +ACCEPT monetdb:///?password=pw&user=foo +EXPECT user=foo +EXPECT password=pw +``` + +Ways of writing booleans and the binary property have already been tested above. + +Ip numbers: + +```test +ACCEPT monetdb://192.168.1.1:12345/foo +EXPECT connect_unix= +EXPECT connect_tcp=192.168.1.1 +EXPECT database=foo +``` + +```test +ACCEPT monetdb://[::1]:12345/foo +EXPECT connect_unix= +EXPECT connect_tcp=::1 +EXPECT database=foo +``` + +Bad percent escapes: + +```test +REJECT monetdb:///m%xxbad +``` + + +## Interpreting + +Testing the validity constraints. +They apply both when parsing a URL and with ad-hoc settings. + +Rule 1, the type constraints, has already been tested in [Section Parameter +tests](#parameter-tests). + +Rule 2, interaction between **sock** and **host** is tested below in +[the next subsection](#interaction-between-tls-host-sock-and-database). + +Rule 3, about **binary**, is tested in [Subsection Binary](#binary). + +Rule 4, **sock** vs **tls** is tested below in [the next +subsection](#interaction-between-tls-host-sock-and-database). + +Rule 5, **certhash** syntax, is tested in [Subsection Certhash](#certhash). + +Rule 6, **tls** **cert** **certhash** interaction, is tested +in [Subsection Interaction between tls, cert and certhash](#interaction-between-tls-cert-and-certhash). + +Rule 7, **database**, **tableschema**, **table** is tested in [Subsection +Database, schema, table name +constraints](#database-schema-table-name-constraints). + +Here are some tests for Rule 8, **port**. + +```test +SET port=1 +EXPECT valid=true +SET port=10 +EXPECT valid=true +SET port=000010 +EXPECT valid=true +SET port=65535 +EXPECT valid=true +SET port=-1 +EXPECT valid=true +SET port=0 +EXPECT valid=false +SET port=-2 +EXPECT valid=false +SET port=65536 +EXPECT valid=false +``` + +### Database, schema, table name constraints + +```test +SET database= +EXPECT valid=yes +SET database=banana +EXPECT valid=yes +SET database=UPPERCASE +EXPECT valid=yes +SET database=_under_score_ +EXPECT valid=yes +SET database=with-dashes +EXPECT valid=yes +``` + +```test +SET database=with/slash +EXPECT valid=no +SET database=-flag +EXPECT valid=no +SET database=with space +EXPECT valid=no +SET database=with.period +EXPECT valid=yes +SET database=with%percent +EXPECT valid=no +SET database=with!exclamation +EXPECT valid=no +SET database=with?questionmark +EXPECT valid=no +``` + +```test +SET database=demo +SET tableschema= +EXPECT valid=yes +SET tableschema=banana +EXPECT valid=yes +SET tableschema=UPPERCASE +EXPECT valid=yes +SET tableschema=_under_score_ +EXPECT valid=yes +SET tableschema=with-dashes +EXPECT valid=yes +``` + +```test +SET database=demo +SET tableschema=with/slash +EXPECT valid=no +SET tableschema=-flag +EXPECT valid=no +SET tableschema=with space +EXPECT valid=no +SET tableschema=with.period +EXPECT valid=yes +SET tableschema=with%percent +EXPECT valid=no +SET tableschema=with!exclamation +EXPECT valid=no +SET tableschema=with?questionmark +EXPECT valid=no +``` + +```test +SET database=demo +SET tableschema=sys +SET table= +EXPECT valid=yes +SET table=banana +EXPECT valid=yes +SET table=UPPERCASE +EXPECT valid=yes +SET table=_under_score_ +EXPECT valid=yes +SET table=with-dashes +EXPECT valid=yes +``` + +```test +SET database=demo +SET tableschema=sys +SET table=with/slash +EXPECT valid=no +SET table=-flag +EXPECT valid=no +SET table=with space +EXPECT valid=no +SET table=with.period +EXPECT valid=yes +SET table=with%percent +EXPECT valid=no +SET table=with!exclamation +EXPECT valid=no +SET table=with?questionmark +EXPECT valid=no +``` + +### Interaction between tls, cert and certhash + +```test +ACCEPT monetdbs:///?cert=/a/path +EXPECT connect_tls_verify=cert +ACCEPT monetdbs:///?certhash=sha256:aa +EXPECT connect_tls_verify=hash +ACCEPT monetdbs:///?cert=/a/path&certhash=sha256:aa +EXPECT connect_tls_verify=hash +REJECT monetdb:///?cert=/a/path +REJECT monetdb:///?certhash=sha256:aa +``` + +```test +SET tls=off +SET cert= +SET certhash= +EXPECT valid=yes +EXPECT connect_tls_verify= +``` + +```test +SET tls=off +SET cert= +SET certhash=sha256:abcdef +EXPECT valid=no +``` + +```test +SET tls=off +SET cert=/foo +SET certhash= +EXPECT valid=no +``` + +```test +SET tls=off +SET cert=/foo +SET certhash=sha256:abcdef +EXPECT valid=no +``` + +```test +SET tls=on +SET cert= +SET certhash= +EXPECT valid=yes +EXPECT connect_tls_verify=system +``` + +```test +SET tls=on +SET cert= +SET certhash=sha256:abcdef +EXPECT valid=yes +EXPECT connect_tls_verify=hash +``` + +```test +SET tls=on +SET cert=/foo +SET certhash= +EXPECT valid=yes +EXPECT connect_tls_verify=cert +``` + +```test +SET tls=on +SET cert=/foo +SET certhash=sha256:abcdef +EXPECT valid=yes +EXPECT connect_tls_verify=hash +``` + + +### Interaction between tls, host, sock and database + +The following tests should exhaustively test all variants. + +```test +ACCEPT monetdb:/// +EXPECT connect_scan=off +EXPECT connect_unix=/tmp/.s.monetdb.50000 +EXPECT connect_tcp=localhost +``` + +```test +ACCEPT monetdb:///?sock=/a/path +EXPECT connect_scan=off +EXPECT connect_unix=/a/path +EXPECT connect_tcp= +``` + +```test +ACCEPT monetdb://localhost/ +EXPECT connect_scan=off +EXPECT connect_unix=/tmp/.s.monetdb.50000 +EXPECT connect_tcp=localhost +``` + +```test +ACCEPT monetdb://localhost/?sock=/a/path +EXPECT connect_scan=off +EXPECT connect_unix=/a/path +EXPECT connect_tcp= +``` + +```test +ACCEPT monetdb://localhost./ +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdb://localhost./?sock=/a/path +``` + +```test +ACCEPT monetdb://not.localhost/ +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=not.localhost +``` + +```test +REJECT monetdb://not.localhost/?sock=/a/path +``` + +```test +ACCEPT monetdbs:/// +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdbs:///?sock=/a/path +``` + +```test +ACCEPT monetdbs://localhost/ +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdbs://localhost/?sock=/a/path +``` + +```test +ACCEPT monetdbs://localhost./ +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdbs://localhost./?sock=/a/path +``` + +```test +ACCEPT monetdbs://not.localhost/ +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=not.localhost +``` + +```test +REJECT monetdbs://not.localhost/?sock=/a/path +``` + +```test +ACCEPT monetdb:///demo +EXPECT connect_scan=on +``` + +```test +ACCEPT monetdb:///demo?sock=/a/path +EXPECT connect_scan=off +EXPECT connect_unix=/a/path +EXPECT connect_tcp= +``` + +```test +ACCEPT monetdb://localhost/demo +EXPECT connect_scan=on +``` + +```test +ACCEPT monetdb://localhost/demo?sock=/a/path +EXPECT connect_scan=off +EXPECT connect_unix=/a/path +EXPECT connect_tcp= +``` + +```test +ACCEPT monetdb://localhost./demo +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdb://localhost./?sock=/a/path +``` + +```test +ACCEPT monetdb://not.localhost/demo +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=not.localhost +``` + +```test +REJECT monetdb://not.localhost/?sock=/a/path +``` + +```test +ACCEPT monetdbs:///demo +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdbs:///?sock=/a/path +``` + +```test +ACCEPT monetdbs://localhost/demo +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdbs://localhost/?sock=/a/path +``` + +```test +ACCEPT monetdbs://localhost./demo +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +REJECT monetdbs://localhost./?sock=/a/path +``` + +```test +ACCEPT monetdbs://not.localhost/demo +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=not.localhost +``` + +```test +REJECT monetdbs://not.localhost/?sock=/a/path +``` + +### sock and sockdir + +Sockdir only applies to implicit Unix domain sockets, +not to ones that are given explicitly + +```test +EXPECT sockdir=/tmp +EXPECT port=-1 +EXPECT host= +EXPECT connect_unix=/tmp/.s.monetdb.50000 +SET sockdir=/somewhere/else +EXPECT connect_unix=/somewhere/else/.s.monetdb.50000 +SET port=12345 +EXPECT connect_unix=/somewhere/else/.s.monetdb.12345 +``` + +## Legacy URL's + +```test +REJECT mapi: +REJECT mapi:monetdb +REJECT mapi:monetdb: +REJECT mapi:monetdb:/ +``` + +```test +ACCEPT mapi:monetdb://monet.db:12345/demo +EXPECT host=monet.db +EXPECT port=12345 +EXPECT database=demo +EXPECT tls=off +EXPECT language=sql +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=monet.db +``` + +This one is the golden standard: + +```test +ACCEPT mapi:monetdb://localhost:12345/demo +EXPECT host=localhost +EXPECT port=12345 +EXPECT database=demo +EXPECT tls=off +EXPECT language=sql +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +ACCEPT mapi:monetdb://localhost:12345/ +EXPECT host=localhost +EXPECT port=12345 +EXPECT database= +EXPECT tls=off +EXPECT language=sql +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +ACCEPT mapi:monetdb://localhost:12345 +EXPECT host=localhost +EXPECT port=12345 +EXPECT database= +EXPECT tls=off +EXPECT language=sql +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=localhost +``` + +```test +ACCEPT mapi:monetdb://localhost/demo +EXPECT connect_scan=false +EXPECT connect_unix= +EXPECT connect_tcp=localhost +EXPECT connect_port=50000 +``` + +```test +ACCEPT mapi:monetdb://:12345/demo +EXPECT host= +EXPECT port=12345 +EXPECT database=demo +EXPECT tls=off +EXPECT language=sql +EXPECT connect_scan=off +EXPECT connect_unix=/tmp/.s.monetdb.12345 +EXPECT connect_tcp=localhost +``` + +```test +ACCEPT mapi:monetdb://127.0.0.1:12345/demo +EXPECT host=127.0.0.1 +EXPECT port=12345 +EXPECT database=demo +EXPECT tls=off +EXPECT language=sql +EXPECT connect_scan=off +EXPECT connect_unix= +EXPECT connect_tcp=127.0.0.1 +``` + +Database parameter allowed, overrides path + +```test +ACCEPT mapi:monetdb://localhost:12345/demo?database=foo +EXPECT database=foo +``` + +User, username and password parameters are ignored: + +```test +SET user=alan +SET password=turing +ACCEPT mapi:monetdb://localhost:12345/demo?user=foo +EXPECT user=alan +EXPECT password=turing +ACCEPT mapi:monetdb://localhost:12345/demo?password=foo +EXPECT user=alan +EXPECT password=turing +``` + +Pymonetdb used to accept user name and password before +the host name and should continue to do so. + + +```test +ONLY pymonetdb +SET user=alan +SET password=turing +ACCEPT mapi:monetdb://foo:bar@localhost:12345/demo +EXPECT user=foo +EXPECT password=bar +ACCEPT mapi:monetdb://banana@localhost:12345/demo +EXPECT user=banana +EXPECT password= +``` + +```test +NOT pymonetdb +SET user=alan +SET password=turing +REJECT mapi:monetdb://foo:bar@localhost:12345/demo +REJECT mapi:monetdb://banana@localhost:12345/demo +``` + +Unix domain sockets + +```test +ACCEPT mapi:monetdb:///path/to/sock?database=demo +EXPECT host= +EXPECT sock=/path/to/sock +EXPECT port=-1 +EXPECT database=demo +EXPECT tls=off +EXPECT language=sql +EXPECT connect_unix=/path/to/sock +EXPECT connect_tcp= +``` + +```test +ACCEPT mapi:monetdb:///path/to/sock +EXPECT host= +EXPECT sock=/path/to/sock +EXPECT port=-1 +EXPECT database= +EXPECT tls=off +EXPECT language=sql +EXPECT connect_unix=/path/to/sock +EXPECT connect_tcp= +``` + +Corner case: both libmapi and pymonetdb interpret this as an attempt +to connect to socket '/'. This will fail of course but the URL does parse + +```test +ACCEPT mapi:monetdb:/// +EXPECT host= +EXPECT sock=/ +EXPECT connect_unix=/ +EXPECT connect_tcp= +``` + +```test +NOT pymonetdb +PARSE mapi:monetdb:///foo:bar@path/to/sock +EXPECT sock=/foo:bar@path/to/sock +REJECT mapi:monetdb://foo:bar@/path/to/sock +``` + +```test +ONLY pymonetdb +SET user=alan +SET password=turing +ACCEPT mapi:monetdb://foo:bar@/path/to/sock +EXPECT host= +EXPECT sock=/path/to/sock +EXPECT user=foo +EXPECT password=bar +EXPECT connect_unix=/path/to/sock +EXPECT connect_tcp= +``` + +```test +ONLY pymonetdb +SET user=alan +SET password=turing +ACCEPT mapi:monetdb://foo@/path/to/sock +EXPECT host= +EXPECT sock=/path/to/sock +EXPECT user=foo +EXPECT password= +EXPECT connect_unix=/path/to/sock +EXPECT connect_tcp= +``` + +Language is supported + +```test +SET language=sql +ACCEPT mapi:monetdb://localhost:12345?language=mal +EXPECT host=localhost +EXPECT sock= +EXPECT language=mal +SET language=sql +ACCEPT mapi:monetdb:///path/to/sock?language=mal +EXPECT host= +EXPECT sock=/path/to/sock +EXPECT language=mal +``` + +No percent decoding is performed + +```test +REJECT mapi:monetdb://localhost:1234%35/demo +PARSE mapi:monetdb://loc%61lhost:12345/d%61tabase +EXPECT host=loc%61lhost +EXPECT database=d%61tabase +EXPECT valid=no +``` + +```test +PARSE mapi:monetdb://localhost:12345/db?database=b%61r&language=m%61l +EXPECT database=b%61r +EXPECT language=m%61l +EXPECT valid=no +``` + +l%61nguage is an unknown parameter, thus ignored not rejected + +```test +SET language=sql +ACCEPT mapi:monetdb://localhost:12345/db?l%61nguage=mal +EXPECT language=sql +ACCEPT mapi:monetdb://localhost:12345/db?_l%61nguage=mal +``` +