summary refs log tree commit diff stats
path: root/tests/untestable
diff options
context:
space:
mode:
Diffstat (limited to 'tests/untestable')
-rw-r--r--tests/untestable/gdb/gdb_pretty_printer_test.py34
-rw-r--r--tests/untestable/gdb/gdb_pretty_printer_test_output.txt3
-rw-r--r--tests/untestable/gdb/gdb_pretty_printer_test_program.nim13
-rwxr-xr-x[-rw-r--r--]tests/untestable/gdb/gdb_pretty_printer_test_run.sh20
-rw-r--r--tests/untestable/thttpclient_ssl_remotenetwork.nim193
-rw-r--r--tests/untestable/tpostgres.nim327
6 files changed, 150 insertions, 440 deletions
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test.py b/tests/untestable/gdb/gdb_pretty_printer_test.py
index 5b34bcb3d..aed0cfeb0 100644
--- a/tests/untestable/gdb/gdb_pretty_printer_test.py
+++ b/tests/untestable/gdb/gdb_pretty_printer_test.py
@@ -1,11 +1,14 @@
 import gdb
+import re
+import sys
 # this test should test the gdb pretty printers of the nim
 # library. But be aware this test is not complete. It only tests the
 # command line version of gdb. It does not test anything for the
 # machine interface of gdb. This means if if this test passes gdb
 # frontends might still be broken.
 
-gdb.execute("source ../../../tools/nim-gdb.py")
+gdb.execute("set python print-stack full")
+gdb.execute("source ../../../tools/debug/nim-gdb.py")
 # debug all instances of the generic function `myDebug`, should be 14
 gdb.execute("rbreak myDebug")
 gdb.execute("run")
@@ -16,7 +19,7 @@ outputs = [
   '"meTwo"',
   '{meOne, meThree}',
   'MyOtherEnum(1)',
-  '5',
+  '{MyOtherEnum(0), MyOtherEnum(2)}',
   'array = {1, 2, 3, 4, 5}',
   'seq(0, 0)',
   'seq(0, 10)',
@@ -25,15 +28,21 @@ outputs = [
   'seq(3, 3) = {"one", "two", "three"}',
   'Table(3, 64) = {[4] = "four", [5] = "five", [6] = "six"}',
   'Table(3, 8) = {["two"] = 2, ["three"] = 3, ["one"] = 1}',
+  '{a = 1, b = "some string"}',
+  '("hello", 42)'
 ]
 
+argRegex = re.compile("^.* = (?:No suitable Nim \$ operator found for type: \w+\s*)*(.*)$")
+# Remove this error message which can pop up
+noSuitableRegex = re.compile("(No suitable Nim \$ operator found for type: \w+\s*)")
+
 for i, expected in enumerate(outputs):
-  gdb.write(f"{i+1}) expecting: {expected}: ", gdb.STDLOG)
+  gdb.write(f"\x1b[38;5;105m{i+1}) expecting: {expected}: \x1b[0m", gdb.STDLOG)
   gdb.flush()
-
-  functionSymbol = gdb.selected_frame().block().function
-  assert functionSymbol.line == 21
-
+  currFrame = gdb.selected_frame()
+  functionSymbol = currFrame.block().function
+  assert functionSymbol.line == 24, str(functionSymbol.line)
+  raw = ""
   if i == 6:
     # myArray is passed as pointer to int to myDebug. I look up myArray up in the stack
     gdb.execute("up")
@@ -43,10 +52,13 @@ for i, expected in enumerate(outputs):
     gdb.execute("up")
     raw = gdb.parse_and_eval("myOtherArray")
   else:
-    raw = gdb.parse_and_eval("arg")
-
+    rawArg = re.sub(noSuitableRegex, "", gdb.execute("info args", to_string = True))
+    raw = rawArg.split("=", 1)[-1].strip()
   output = str(raw)
 
-  assert output == expected, output + " != " + expected
-  gdb.write(f"passed\n", gdb.STDLOG)
+  if output != expected:
+    gdb.write(f"\x1b[38;5;196m ({output}) != expected: ({expected})\x1b[0m\n", gdb.STDERR)
+    gdb.execute("quit 1")
+  else:
+    gdb.write("\x1b[38;5;34mpassed\x1b[0m\n", gdb.STDLOG)
   gdb.execute("continue")
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test_output.txt b/tests/untestable/gdb/gdb_pretty_printer_test_output.txt
deleted file mode 100644
index 73d26016f..000000000
--- a/tests/untestable/gdb/gdb_pretty_printer_test_output.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Loading Nim Runtime support.
-NimEnumPrinter: lookup global symbol 'NTI__z9cu80OJCfNgw9bUdzn5ZEzw_ failed for tyEnum_MyOtherEnum__z9cu80OJCfNgw9bUdzn5ZEzw.
-8
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test_program.nim b/tests/untestable/gdb/gdb_pretty_printer_test_program.nim
index c376ef89a..163c99860 100644
--- a/tests/untestable/gdb/gdb_pretty_printer_test_program.nim
+++ b/tests/untestable/gdb/gdb_pretty_printer_test_program.nim
@@ -14,7 +14,10 @@ type
     moTwo,
     moThree,
     moFoure,
-
+  
+  MyObj = object
+    a*: int
+    b*: string
 
 var counter = 0
 
@@ -74,7 +77,13 @@ proc testProc(): void =
   var myOtherTable = {"one": 1, "two": 2, "three": 3}.toTable
   myDebug(myOtherTable) #14
 
-  echo(counter)
+  var obj = MyObj(a: 1, b: "some string")
+  myDebug(obj) #15
+
+  var tup = ("hello", 42)
+  myDebug(tup) # 16
+
+  assert counter == 16
 
 
 testProc()
diff --git a/tests/untestable/gdb/gdb_pretty_printer_test_run.sh b/tests/untestable/gdb/gdb_pretty_printer_test_run.sh
index 525f54705..411c68435 100644..100755
--- a/tests/untestable/gdb/gdb_pretty_printer_test_run.sh
+++ b/tests/untestable/gdb/gdb_pretty_printer_test_run.sh
@@ -1,15 +1,13 @@
 #!/usr/bin/env bash
-# Exit if anything fails
 set -e
-#!/usr/bin/env bash
 # Compile the test project with fresh debug information.
-nim c --debugger:native gdb_pretty_printer_test_program.nim &> /dev/null
+nim c --debugger:native --mm:orc --out:gdbNew gdb_pretty_printer_test_program.nim
+echo "Running new runtime tests..."
 # 2>&1 redirects stderr to stdout (all output in stdout)
-# <(...) is a bash feature that makes the output of a command into a
-# file handle.
-# diff compares the two files, the expected output, and the file
-# handle that is created by the execution of gdb.
-diff ./gdb_pretty_printer_test_output.txt <(gdb -x gdb_pretty_printer_test.py --batch-silent --args gdb_pretty_printer_test_program 2>&1)
-# The exit code of diff is forwarded as the exit code of this
-# script. So when the comparison fails, the exit code of this script
-# won't be 0. So this script should be embeddable in a test suite.
+gdb -x gdb_pretty_printer_test.py --batch-silent --args gdbNew 2>&1
+
+
+# Do it all again, but with old runtime
+nim c --debugger:native --mm:refc --out:gdbOld gdb_pretty_printer_test_program.nim &> /dev/null
+echo "Running old runtime tests"
+gdb -x gdb_pretty_printer_test.py --batch-silent --args gdbOld 2>&1
diff --git a/tests/untestable/thttpclient_ssl_remotenetwork.nim b/tests/untestable/thttpclient_ssl_remotenetwork.nim
index ed6866d53..3cb759516 100644
--- a/tests/untestable/thttpclient_ssl_remotenetwork.nim
+++ b/tests/untestable/thttpclient_ssl_remotenetwork.nim
@@ -13,7 +13,7 @@
 ## for a comparison with other clients.
 
 from stdtest/testutils import enableRemoteNetworking
-when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(windows) and not defined(openbsd) and not defined(i386)):
+when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(windows) and not defined(openbsd)):
   # Not supported on Windows due to old openssl version
   import
     httpclient,
@@ -32,70 +32,75 @@ when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(win
       good, bad, dubious, good_broken, bad_broken, dubious_broken
     CertTest = tuple[url:string, category:Category, desc: string]
 
-  const certificate_tests: array[0..55, CertTest] = [
-    ("https://wrong.host.badssl.com/", bad, "wrong.host"),
-    ("https://captive-portal.badssl.com/", bad, "captive-portal"),
-    ("https://expired.badssl.com/", bad, "expired"),
-    ("https://google.com/", good, "good"),
-    ("https://self-signed.badssl.com/", bad, "self-signed"),
-    ("https://untrusted-root.badssl.com/", bad, "untrusted-root"),
-    ("https://revoked.badssl.com/", bad_broken, "revoked"),
-    ("https://pinning-test.badssl.com/", bad_broken, "pinning-test"),
-    ("https://no-common-name.badssl.com/", dubious_broken, "no-common-name"),
-    ("https://no-subject.badssl.com/", dubious_broken, "no-subject"),
-    ("https://incomplete-chain.badssl.com/", dubious_broken, "incomplete-chain"),
-    ("https://sha1-intermediate.badssl.com/", bad, "sha1-intermediate"),
-    ("https://sha256.badssl.com/", good, "sha256"),
-    ("https://sha384.badssl.com/", good, "sha384"),
-    ("https://sha512.badssl.com/", good, "sha512"),
-    ("https://1000-sans.badssl.com/", good, "1000-sans"),
-    ("https://10000-sans.badssl.com/", good_broken, "10000-sans"),
-    ("https://ecc256.badssl.com/", good, "ecc256"),
-    ("https://ecc384.badssl.com/", good, "ecc384"),
-    ("https://rsa2048.badssl.com/", good, "rsa2048"),
-    ("https://rsa8192.badssl.com/", dubious_broken, "rsa8192"),
-    ("http://http.badssl.com/", good, "regular http"),
-    ("https://http.badssl.com/", bad_broken, "http on https URL"),  # FIXME
-    ("https://cbc.badssl.com/", dubious, "cbc"),
-    ("https://rc4-md5.badssl.com/", bad, "rc4-md5"),
-    ("https://rc4.badssl.com/", bad, "rc4"),
-    ("https://3des.badssl.com/", bad, "3des"),
-    ("https://null.badssl.com/", bad, "null"),
-    ("https://mozilla-old.badssl.com/", bad_broken, "mozilla-old"),
-    ("https://mozilla-intermediate.badssl.com/", dubious_broken, "mozilla-intermediate"),
-    ("https://mozilla-modern.badssl.com/", good, "mozilla-modern"),
-    ("https://dh480.badssl.com/", bad, "dh480"),
-    ("https://dh512.badssl.com/", bad, "dh512"),
-    ("https://dh1024.badssl.com/", dubious_broken, "dh1024"),
-    ("https://dh2048.badssl.com/", good, "dh2048"),
-    ("https://dh-small-subgroup.badssl.com/", bad_broken, "dh-small-subgroup"),
-    ("https://dh-composite.badssl.com/", bad_broken, "dh-composite"),
-    ("https://static-rsa.badssl.com/", dubious, "static-rsa"),
-    ("https://tls-v1-0.badssl.com:1010/", dubious, "tls-v1-0"),
-    ("https://tls-v1-1.badssl.com:1011/", dubious, "tls-v1-1"),
-    ("https://invalid-expected-sct.badssl.com/", bad, "invalid-expected-sct"),
-    ("https://hsts.badssl.com/", good, "hsts"),
-    ("https://upgrade.badssl.com/", good, "upgrade"),
-    ("https://preloaded-hsts.badssl.com/", good, "preloaded-hsts"),
-    ("https://subdomain.preloaded-hsts.badssl.com/", bad, "subdomain.preloaded-hsts"),
-    ("https://https-everywhere.badssl.com/", good, "https-everywhere"),
-    ("https://long-extended-subdomain-name-containing-many-letters-and-dashes.badssl.com/", good,
-      "long-extended-subdomain-name-containing-many-letters-and-dashes"),
-    ("https://longextendedsubdomainnamewithoutdashesinordertotestwordwrapping.badssl.com/", good,
-      "longextendedsubdomainnamewithoutdashesinordertotestwordwrapping"),
-    ("https://superfish.badssl.com/", bad, "(Lenovo) Superfish"),
-    ("https://edellroot.badssl.com/", bad, "(Dell) eDellRoot"),
-    ("https://dsdtestprovider.badssl.com/", bad, "(Dell) DSD Test Provider"),
-    ("https://preact-cli.badssl.com/", bad, "preact-cli"),
-    ("https://webpack-dev-server.badssl.com/", bad, "webpack-dev-server"),
-    ("https://mitm-software.badssl.com/", bad, "mitm-software"),
-    ("https://sha1-2016.badssl.com/", dubious, "sha1-2016"),
-    ("https://sha1-2017.badssl.com/", bad, "sha1-2017"),
-  ]
+  # badssl certs sometimes expire, set to false when that happens
+  when true:
+    const certificate_tests: array[0..54, CertTest] = [
+      ("https://wrong.host.badssl.com/", bad, "wrong.host"),
+      ("https://captive-portal.badssl.com/", bad, "captive-portal"),
+      ("https://expired.badssl.com/", bad, "expired"),
+      ("https://google.com/", good, "good"),
+      ("https://self-signed.badssl.com/", bad, "self-signed"),
+      ("https://untrusted-root.badssl.com/", bad, "untrusted-root"),
+      ("https://revoked.badssl.com/", bad_broken, "revoked"),
+      ("https://pinning-test.badssl.com/", bad_broken, "pinning-test"),
+      ("https://no-common-name.badssl.com/", bad, "no-common-name"),
+      ("https://no-subject.badssl.com/", bad, "no-subject"),
+      ("https://sha1-intermediate.badssl.com/", bad, "sha1-intermediate"),
+      ("https://sha256.badssl.com/", good, "sha256"),
+      ("https://sha384.badssl.com/", bad, "sha384"),
+      ("https://sha512.badssl.com/", bad, "sha512"),
+      ("https://1000-sans.badssl.com/", bad, "1000-sans"),
+      ("https://10000-sans.badssl.com/", good_broken, "10000-sans"),
+      ("https://ecc256.badssl.com/", good_broken, "ecc256"),
+      ("https://ecc384.badssl.com/", good_broken, "ecc384"),
+      ("https://rsa2048.badssl.com/", good, "rsa2048"),
+      ("https://rsa8192.badssl.com/", dubious_broken, "rsa8192"),
+      ("http://http.badssl.com/", good, "regular http"),
+      ("https://http.badssl.com/", bad_broken, "http on https URL"),  # FIXME
+      ("https://cbc.badssl.com/", dubious, "cbc"),
+      ("https://rc4-md5.badssl.com/", bad, "rc4-md5"),
+      ("https://rc4.badssl.com/", bad, "rc4"),
+      ("https://3des.badssl.com/", bad, "3des"),
+      ("https://null.badssl.com/", bad, "null"),
+      ("https://mozilla-old.badssl.com/", bad_broken, "mozilla-old"),
+      ("https://mozilla-intermediate.badssl.com/", dubious_broken, "mozilla-intermediate"),
+      ("https://mozilla-modern.badssl.com/", good, "mozilla-modern"),
+      ("https://dh480.badssl.com/", bad, "dh480"),
+      ("https://dh512.badssl.com/", bad, "dh512"),
+      ("https://dh1024.badssl.com/", dubious_broken, "dh1024"),
+      ("https://dh2048.badssl.com/", good, "dh2048"),
+      ("https://dh-small-subgroup.badssl.com/", bad_broken, "dh-small-subgroup"),
+      ("https://dh-composite.badssl.com/", bad_broken, "dh-composite"),
+      ("https://static-rsa.badssl.com/", dubious, "static-rsa"),
+      ("https://tls-v1-0.badssl.com:1010/", dubious, "tls-v1-0"),
+      ("https://tls-v1-1.badssl.com:1011/", dubious, "tls-v1-1"),
+      ("https://invalid-expected-sct.badssl.com/", bad, "invalid-expected-sct"),
+      ("https://hsts.badssl.com/", good, "hsts"),
+      ("https://upgrade.badssl.com/", good, "upgrade"),
+      ("https://preloaded-hsts.badssl.com/", good, "preloaded-hsts"),
+      ("https://subdomain.preloaded-hsts.badssl.com/", bad, "subdomain.preloaded-hsts"),
+      ("https://https-everywhere.badssl.com/", good, "https-everywhere"),
+      ("https://long-extended-subdomain-name-containing-many-letters-and-dashes.badssl.com/", good,
+        "long-extended-subdomain-name-containing-many-letters-and-dashes"),
+      ("https://longextendedsubdomainnamewithoutdashesinordertotestwordwrapping.badssl.com/", good,
+        "longextendedsubdomainnamewithoutdashesinordertotestwordwrapping"),
+      ("https://superfish.badssl.com/", bad, "(Lenovo) Superfish"),
+      ("https://edellroot.badssl.com/", bad, "(Dell) eDellRoot"),
+      ("https://dsdtestprovider.badssl.com/", bad, "(Dell) DSD Test Provider"),
+      ("https://preact-cli.badssl.com/", bad, "preact-cli"),
+      ("https://webpack-dev-server.badssl.com/", bad, "webpack-dev-server"),
+      ("https://mitm-software.badssl.com/", bad, "mitm-software"),
+      ("https://sha1-2016.badssl.com/", dubious, "sha1-2016"),
+      ("https://sha1-2017.badssl.com/", bad, "sha1-2017"),
+    ]
+  else:
+    const certificate_tests: array[0..0, CertTest] = [
+      ("https://google.com/", good, "good")
+    ]
 
 
   template evaluate(exception_msg: string, category: Category, desc: string) =
-    # Evaluate test outcome. Testes flagged as _broken are evaluated and skipped
+    # Evaluate test outcome. Tests flagged as `_broken` are evaluated and skipped
     let raised = (exception_msg.len > 0)
     let should_not_raise = category in {good, dubious_broken, bad_broken}
     if should_not_raise xor raised:
@@ -115,12 +120,23 @@ when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(win
 
     else:
       # this is unexpected
+      var fatal = true
+      var msg = ""
       if raised:
-        echo "         $# ($#) raised: $#" % [desc, $category, exception_msg]
+        msg = "         $# ($#) raised: $#" % [desc, $category, exception_msg]
+        if "500 Internal Server Error" in exception_msg:
+          # refs https://github.com/nim-lang/Nim/issues/16338#issuecomment-804300278
+          # we got: `good (good) raised: 500 Internal Server Error`
+          fatal = false
+          msg.add " (http 500 => assuming this is not our problem)"
       else:
-        echo "         $# ($#) did not raise" % [desc, $category]
-      if category in {good, dubious, bad}:
+        msg = "         $# ($#) did not raise" % [desc, $category]
+
+      if category in {good, dubious, bad} and fatal:
+        echo "D20210322T121353: error: " & msg
         fail()
+      else:
+        echo "D20210322T121353: warning: " & msg
 
 
   suite "SSL certificate check - httpclient":
@@ -161,32 +177,37 @@ when enableRemoteNetworking and (defined(nimTestsEnableFlaky) or not defined(win
 
 
   suite "SSL certificate check - httpclient - threaded":
-
-    # Spawn threads before the "test" blocks
-    var outcomes = newSeq[FlowVar[TTOutcome]](certificate_tests.len)
-    for i, ct in certificate_tests:
-      let t = spawn run_t_test(ct)
-      outcomes[i] = t
-
-    # create "test" blocks and handle thread outputs
-    for t in outcomes:
-      let outcome = ^t  # wait for a thread to terminate
-
-      test outcome.desc:
-
-        evaluate(outcome.exception_msg, outcome.category, outcome.desc)
-
+    when defined(nimTestsEnableFlaky) or not defined(linux): # xxx pending bug #16338
+      # Spawn threads before the "test" blocks
+      var outcomes = newSeq[FlowVar[TTOutcome]](certificate_tests.len)
+      for i, ct in certificate_tests:
+        let t = spawn run_t_test(ct)
+        outcomes[i] = t
+
+      # create "test" blocks and handle thread outputs
+      for t in outcomes:
+        let outcome = ^t  # wait for a thread to terminate
+        test outcome.desc:
+          evaluate(outcome.exception_msg, outcome.category, outcome.desc)
+    else:
+      echo "skipped test"
 
   # net tests
 
 
   type NetSocketTest = tuple[hostname: string, port: Port, category:Category, desc: string]
-  const net_tests:array[0..3, NetSocketTest] = [
-    ("imap.gmail.com", 993.Port, good, "IMAP"),
-    ("wrong.host.badssl.com", 443.Port, bad, "wrong.host"),
-    ("captive-portal.badssl.com", 443.Port, bad, "captive-portal"),
-    ("expired.badssl.com", 443.Port, bad, "expired"),
-  ]
+  # badssl certs sometimes expire, set to false when that happens
+  when true:
+    const net_tests:array[0..3, NetSocketTest] = [
+      ("imap.gmail.com", 993.Port, good, "IMAP"),
+      ("wrong.host.badssl.com", 443.Port, bad, "wrong.host"),
+      ("captive-portal.badssl.com", 443.Port, bad, "captive-portal"),
+      ("expired.badssl.com", 443.Port, bad, "expired"),
+    ]
+  else:
+    const net_tests: array[0..0, NetSocketTest] = [
+      ("imap.gmail.com", 993.Port, good, "IMAP")
+    ]
   # TODO: ("null.badssl.com", 443.Port, bad_broken, "null"),
 
 
diff --git a/tests/untestable/tpostgres.nim b/tests/untestable/tpostgres.nim
index d3397e53a..8b1378917 100644
--- a/tests/untestable/tpostgres.nim
+++ b/tests/untestable/tpostgres.nim
@@ -1,328 +1 @@
-import db_postgres, strutils
-
-
-let db = open("localhost", "dom", "", "test")
-db.exec(sql"DROP TABLE IF EXISTS myTable")
-db.exec(sql("""CREATE TABLE myTable (
-                  id integer PRIMARY KEY,
-                  name varchar(50) not null)"""))
-let name = "Dom"
-db.exec(sql"INSERT INTO myTable (id, name) VALUES (0, ?)",
-        name)
-doAssert db.getValue(sql"SELECT name FROM myTable") == name
-# Check issue #3513
-doAssert db.getValue(sql"SELECT name FROM myTable") == name
-
-
-# issue #3560
-proc addToDb(conn: DbConn, fileId: int, fileName: string): int64 =
-  result = conn.insertId(sql("INSERT into files (id, filename) VALUES (?, ?)"), fileId, fileName)
-
-db.exec(sql"DROP TABLE IF EXISTS files")
-db.exec(sql"DROP TABLE IF EXISTS fileobjects")
-db.exec(sql("""CREATE TABLE FILEOBJECTS(
-               ID             SERIAL PRIMARY KEY,
-               FILE_SIZE      INT,
-               MD5            CHAR(32)  NOT NULL UNIQUE
-            );"""))
-
-db.exec(sql("""CREATE TABLE FILES(
-               ID                  SERIAL PRIMARY KEY,
-               OBJECT_ID           INT,
-               FILENAME            TEXT NOT NULL,
-               URI                 TEXT,
-               SCHEME              CHAR(10),
-               PUBLIC              BOOLEAN DEFAULT FALSE,
-               CONSTRAINT fk1_fileobjs FOREIGN KEY (object_id)
-               REFERENCES fileobjects (id) MATCH SIMPLE
-               ON DELETE CASCADE
-            );"""))
-
-let f1 = db.addToDb(1, "hello.tmp")
-doAssert f1 == 1
-let f2 = db.addToDb(2, "hello2.tmp")
-doAssert f2 == 2
-
-# PreparedStmt vs. normal query
-try:
-  echo db.getValue(sql("select * from files where id = $1"), 1)
-  doAssert false, "Exception expected"
-except DbError:
-  let msg = getCurrentExceptionMsg().normalize
-  doAssert "expects" in msg
-  doAssert "?" in msg
-  doAssert "parameter substitution" in msg
-
-doAssert db.getValue(sql("select filename from files where id = ?"), 1) == "hello.tmp"
-
-var first = prepare(db, "one", sql"select filename from files where id = $1", 1)
-doAssert db.getValue(first, 1) == "hello.tmp"
-
-try:
-  var second = prepare(db, "two", sql"select filename from files where id = ?", 1)
-  doAssert false, "Exception expected"
-except:
-  let msg = getCurrentExceptionMsg().normalize
-  doAssert "expects" in msg
-  doAssert "$1" in msg
-  doAssert "parameter substitution" in msg
-
-# issue #3569
-db.exec(SqlQuery("DROP TABLE IF EXISTS tags"))
-db.exec(SqlQuery("CREATE TABLE tags(id serial UNIQUE, name varchar(255))"))
-
-for i in 1..10:
-  var name = "t" & $i
-  echo(name)
-  discard db.getRow(
-    SqlQuery("INSERT INTO tags(name) VALUES(\'$1\') RETURNING id" % [name]))
-    
-# get column details
-db.exec(SqlQuery("DROP TABLE IF EXISTS dbtypes;"))
-db.exec(SqlQuery("DROP TYPE IF EXISTS custom_enum;"))
-db.exec(SqlQuery("CREATE TYPE custom_enum AS ENUM ('1', '2', '3');"))
-db.exec(SqlQuery("DROP TYPE IF EXISTS custom_composite;"))
-db.exec(SqlQuery("CREATE TYPE custom_composite AS (r double precision, i double precision);"))
-db.exec(SqlQuery("""CREATE TABLE dbtypes(
-                    id serial UNIQUE,
-                    bytea_col bytea,
-                    smallint_col smallint,
-                    integer_col integer,
-                    bigint_col bigint,
-                    decimal_col decimal,
-                    numeric_col numeric,
-                    real_col real,
-                    double_precision_col double precision,
-                    smallserial_col smallserial,
-                    serial_col serial,
-                    bigserial_col bigserial,
-                    money_col money,
-                    varchar_col varchar(10),
-                    character_col character(1),
-                    text_col text,
-                    timestamp_col timestamp,
-                    date_col date,
-                    time_col time,
-                    interval_col interval,
-                    bool_col boolean,
-                    custom_enum_col custom_enum,
-                    point_col point,
-                    line_col line,
-                    lseg_col lseg,
-                    box_col box,
-                    path_col path,
-                    polygon_col polygon,
-                    circle_col circle,
-                    cidr_col cidr,
-                    inet_col inet,
-                    macaddr_col macaddr,
-                    bit_col bit,
-                    varbit_col bit(3),
-                    tsvector_col tsvector,
-                    tsquery_col tsquery,
-                    uuid_col uuid,
-                    xml_col xml,
-                    json_col json,
-                    array_col integer[],
-                    custom_composite_col custom_composite,
-                    range_col int4range
-                    );"""))
-db.exec(SqlQuery("INSERT INTO dbtypes (id) VALUES(0);"))
-
-var dbCols : DbColumns = @[]
-for row in db.instantRows(dbCols, sql"SELECT * FROM dbtypes"):
-  doAssert len(dbCols) == 42
-
-doAssert dbCols[0].name == "id"
-doAssert dbCols[0].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[0].typ.name == "int4"
-doAssert dbCols[0].typ.size == 4
-
-doAssert dbCols[1].name == "bytea_col"
-doAssert dbCols[1].typ.kind == DbTypeKind.dbBlob
-doAssert dbCols[1].typ.name == "bytea"
-
-doAssert dbCols[2].name == "smallint_col"
-doAssert dbCols[2].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[2].typ.name == "int2"
-doAssert dbCols[2].typ.size == 2
-
-doAssert dbCols[3].name == "integer_col"
-doAssert dbCols[3].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[3].typ.name == "int4"
-doAssert dbCols[3].typ.size == 4
-
-doAssert dbCols[4].name == "bigint_col"
-doAssert dbCols[4].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[4].typ.name == "int8"
-doAssert dbCols[4].typ.size == 8
-
-doAssert dbCols[5].name == "decimal_col"
-doAssert dbCols[5].typ.kind == DbTypeKind.dbDecimal
-doAssert dbCols[5].typ.name == "numeric"
-
-doAssert dbCols[6].name == "numeric_col"
-doAssert dbCols[6].typ.kind == DbTypeKind.dbDecimal
-doAssert dbCols[6].typ.name == "numeric"
-
-doAssert dbCols[7].name == "real_col"
-doAssert dbCols[7].typ.kind == DbTypeKind.dbFloat
-doAssert dbCols[7].typ.name == "float4"
-
-doAssert dbCols[8].name == "double_precision_col"
-doAssert dbCols[8].typ.kind == DbTypeKind.dbFloat
-doAssert dbCols[8].typ.name == "float8"
-
-doAssert dbCols[9].name == "smallserial_col"
-doAssert dbCols[9].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[9].typ.name == "int2"
-
-doAssert dbCols[10].name == "serial_col"
-doAssert dbCols[10].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[10].typ.name == "int4"
-
-doAssert dbCols[11].name == "bigserial_col"
-doAssert dbCols[11].typ.kind == DbTypeKind.dbInt
-doAssert dbCols[11].typ.name == "int8"
-
-doAssert dbCols[12].name == "money_col"
-doAssert dbCols[12].typ.kind == DbTypeKind.dbDecimal
-doAssert dbCols[12].typ.name == "money"    
-    
-doAssert dbCols[13].name == "varchar_col"
-doAssert dbCols[13].typ.kind == DbTypeKind.dbVarchar
-doAssert dbCols[13].typ.name == "varchar"
-
-doAssert dbCols[14].name == "character_col"
-doAssert dbCols[14].typ.kind == DbTypeKind.dbFixedChar
-doAssert dbCols[14].typ.name == "bpchar"
-
-doAssert dbCols[15].name == "text_col"
-doAssert dbCols[15].typ.kind == DbTypeKind.dbVarchar
-doAssert dbCols[15].typ.name == "text"
-
-doAssert dbCols[16].name == "timestamp_col"
-doAssert dbCols[16].typ.kind == DbTypeKind.dbTimestamp
-doAssert dbCols[16].typ.name == "timestamp"
-
-doAssert dbCols[17].name == "date_col"
-doAssert dbCols[17].typ.kind == DbTypeKind.dbDate
-doAssert dbCols[17].typ.name == "date"
-
-doAssert dbCols[18].name == "time_col"
-doAssert dbCols[18].typ.kind == DbTypeKind.dbTime
-doAssert dbCols[18].typ.name == "time"
-
-doAssert dbCols[19].name == "interval_col"
-doAssert dbCols[19].typ.kind == DbTypeKind.dbTimeInterval
-doAssert dbCols[19].typ.name == "interval"
-
-doAssert dbCols[20].name == "bool_col"
-doAssert dbCols[20].typ.kind == DbTypeKind.dbBool
-doAssert dbCols[20].typ.name == "bool"
-
-doAssert dbCols[21].name == "custom_enum_col"
-doAssert dbCols[21].typ.kind == DbTypeKind.dbUnknown
-doAssert parseInt(dbCols[21].typ.name) > 0
-    
-doAssert dbCols[22].name == "point_col"
-doAssert dbCols[22].typ.kind == DbTypeKind.dbPoint
-doAssert dbCols[22].typ.name == "point"    
-
-doAssert dbCols[23].name == "line_col"
-doAssert dbCols[23].typ.kind == DbTypeKind.dbLine
-doAssert dbCols[23].typ.name == "line"    
-
-doAssert dbCols[24].name == "lseg_col"
-doAssert dbCols[24].typ.kind == DbTypeKind.dbLseg
-doAssert dbCols[24].typ.name == "lseg"    
-
-doAssert dbCols[25].name == "box_col"
-doAssert dbCols[25].typ.kind == DbTypeKind.dbBox
-doAssert dbCols[25].typ.name == "box"    
-
-doAssert dbCols[26].name == "path_col"
-doAssert dbCols[26].typ.kind == DbTypeKind.dbPath
-doAssert dbCols[26].typ.name == "path"    
-
-doAssert dbCols[27].name == "polygon_col"
-doAssert dbCols[27].typ.kind == DbTypeKind.dbPolygon
-doAssert dbCols[27].typ.name == "polygon"
-
-doAssert dbCols[28].name == "circle_col"
-doAssert dbCols[28].typ.kind == DbTypeKind.dbCircle
-doAssert dbCols[28].typ.name == "circle"
-
-doAssert dbCols[29].name == "cidr_col"
-doAssert dbCols[29].typ.kind == DbTypeKind.dbInet
-doAssert dbCols[29].typ.name == "cidr"
-
-doAssert dbCols[30].name == "inet_col"
-doAssert dbCols[30].typ.kind == DbTypeKind.dbInet
-doAssert dbCols[30].typ.name == "inet"
-
-doAssert dbCols[31].name == "macaddr_col"
-doAssert dbCols[31].typ.kind == DbTypeKind.dbMacAddress
-doAssert dbCols[31].typ.name == "macaddr"
-
-doAssert dbCols[32].name == "bit_col"
-doAssert dbCols[32].typ.kind == DbTypeKind.dbBit
-doAssert dbCols[32].typ.name == "bit"
-
-doAssert dbCols[33].name == "varbit_col"
-doAssert dbCols[33].typ.kind == DbTypeKind.dbBit
-doAssert dbCols[33].typ.name == "bit"
-
-doAssert dbCols[34].name == "tsvector_col"
-doAssert dbCols[34].typ.kind == DbTypeKind.dbVarchar
-doAssert dbCols[34].typ.name == "tsvector"
-
-doAssert dbCols[35].name == "tsquery_col"
-doAssert dbCols[35].typ.kind == DbTypeKind.dbVarchar
-doAssert dbCols[35].typ.name == "tsquery"
-
-doAssert dbCols[36].name == "uuid_col"
-doAssert dbCols[36].typ.kind == DbTypeKind.dbVarchar
-doAssert dbCols[36].typ.name == "uuid"
-
-doAssert dbCols[37].name == "xml_col"
-doAssert dbCols[37].typ.kind == DbTypeKind.dbXml
-doAssert dbCols[37].typ.name == "xml"
-
-doAssert dbCols[38].name == "json_col"
-doAssert dbCols[38].typ.kind == DbTypeKind.dbJson
-doAssert dbCols[38].typ.name == "json"
-
-doAssert dbCols[39].name == "array_col"
-doAssert dbCols[39].typ.kind == DbTypeKind.dbArray
-doAssert dbCols[39].typ.name == "int4[]"
-
-doAssert dbCols[40].name == "custom_composite_col"
-doAssert dbCols[40].typ.kind == DbTypeKind.dbUnknown
-doAssert parseInt(dbCols[40].typ.name) > 0
-
-doAssert dbCols[41].name == "range_col"
-doAssert dbCols[41].typ.kind == DbTypeKind.dbComposite
-doAssert dbCols[41].typ.name == "int4range"
-
-# issue 6571
-db.exec(sql"DROP TABLE IF EXISTS DICTIONARY")
-db.exec(sql("""CREATE TABLE DICTIONARY(
-               id             SERIAL PRIMARY KEY,
-               entry      VARCHAR(1000) NOT NULL,
-               definition VARCHAR(4000) NOT NULL
-            );"""))
-var entry = "あっそ"
-var definition = "(int) (See ああそうそう) oh, really (uninterested)/oh yeah?/hmmmmm"
-discard db.getRow(
-  SqlQuery("INSERT INTO DICTIONARY(entry, definition) VALUES(\'$1\', \'$2\') RETURNING id" % [entry, definition]))
-doAssert db.getValue(sql"SELECT definition FROM DICTIONARY WHERE entry = ?", entry) == definition
-entry = "Format string entry"
-definition = "Format string definition"
-db.exec(sql"INSERT INTO DICTIONARY(entry, definition) VALUES (?, ?)", entry, definition)
-doAssert db.getValue(sql"SELECT definition FROM DICTIONARY WHERE entry = ?", entry) == definition
-
-echo("All tests succeeded!")
-
-db.close()