summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--testament/specs.nim8
-rw-r--r--testament/testament.nim5
-rw-r--r--testament/tests/shouldfail/ttimeout.nim7
-rw-r--r--tests/testament/tshouldfail.nim2
-rw-r--r--tests/vm/tslow_tables.nim31
5 files changed, 52 insertions, 1 deletions
diff --git a/testament/specs.nim b/testament/specs.nim
index cf3455027..7943e63cc 100644
--- a/testament/specs.nim
+++ b/testament/specs.nim
@@ -34,6 +34,7 @@ type
     reLinesDiffer,      # expected and given line numbers differ
     reOutputsDiffer,
     reExitcodesDiffer,
+    reTimeout,
     reInvalidPeg,
     reCodegenFailure,
     reCodeNotFound,
@@ -70,6 +71,8 @@ type
     nimout*: string
     parseErrors*: string # when the spec definition is invalid, this is not empty.
     unjoinable*: bool
+    timeout*: float # in seconds, fractions possible,
+                    # but don't rely on much precision
 
 proc getCmd*(s: TSpec): string =
   if s.cmd.len == 0:
@@ -225,6 +228,11 @@ proc parseSpec*(filename: string): TSpec =
         result.ccodeCheck = e.value
       of "maxcodesize":
         discard parseInt(e.value, result.maxCodeSize)
+      of "timeout":
+        try:
+          result.timeout = parseFloat(e.value)
+        except ValueError:
+          result.parseErrors.addLine "cannot interpret as a float: ", e.value
       of "target", "targets":
         for v in e.value.normalize.splitWhitespace:
           case v
diff --git a/testament/testament.nim b/testament/testament.nim
index c7ff3adc5..cf76cd971 100644
--- a/testament/testament.nim
+++ b/testament/testament.nim
@@ -244,13 +244,16 @@ proc `$`(x: TResults): string =
             [$x.passed, $x.skipped, $x.total]
 
 proc addResult(r: var TResults, test: TTest, target: TTarget,
-               expected, given: string, success: TResultEnum) =
+               expected, given: string, successOrig: TResultEnum) =
   # test.name is easier to find than test.name.extractFilename
   # A bit hacky but simple and works with tests/testament/tshouldfail.nim
   var name = test.name.replace(DirSep, '/')
   name.add " " & $target & test.options
 
   let duration = epochTime() - test.startTime
+  let success = if test.spec.timeout > 0.0 and duration > test.spec.timeout: reTimeout
+                else: successOrig
+
   let durationStr = duration.formatFloat(ffDecimal, precision = 8).align(11)
   if backendLogging:
     backend.writeTestResult(name = name,
diff --git a/testament/tests/shouldfail/ttimeout.nim b/testament/tests/shouldfail/ttimeout.nim
new file mode 100644
index 000000000..fd3e1a598
--- /dev/null
+++ b/testament/tests/shouldfail/ttimeout.nim
@@ -0,0 +1,7 @@
+discard """
+  timeout: "0.1"
+"""
+
+import os
+
+os.sleep(1000)
diff --git a/tests/testament/tshouldfail.nim b/tests/testament/tshouldfail.nim
index 64f4b3838..aca73c308 100644
--- a/tests/testament/tshouldfail.nim
+++ b/tests/testament/tshouldfail.nim
@@ -27,5 +27,7 @@ FAIL: tests/shouldfail/toutputsub.nim C
 Failure: reOutputsDiffer
 FAIL: tests/shouldfail/tsortoutput.nim C
 Failure: reOutputsDiffer
+FAIL: tests/shouldfail/ttimeout.nim C
+Failure: reTimeout
 '''
 """
diff --git a/tests/vm/tslow_tables.nim b/tests/vm/tslow_tables.nim
new file mode 100644
index 000000000..7ee523a87
--- /dev/null
+++ b/tests/vm/tslow_tables.nim
@@ -0,0 +1,31 @@
+discard """
+  timeout: "4"
+  action: "compile"
+  nimout: '''create
+search
+done'''
+"""
+
+# bug #12195
+
+import tables
+
+type Flop = object
+  a: int
+  #array[128, int]  # <-- compile time is proportional to array size
+
+proc hop(): bool =
+  var v: Table[int, Flop]
+
+  echo "create"
+  for i in 1..1000:
+    v.add i, Flop()
+
+  echo "search"
+  for i in 1..1000:
+    discard contains(v, i)
+
+  echo "done"
+
+const r = hop()
+