Test for sql_time_limit_ms + sqlite_functions mechanism

Added a unit test for the sql_time_limit_ms option.

To test this, I needed to add a custom SQLite sleep() function. I've added a
simple mechanism to the Datasette class for registering custom functions.

I also had to modify the sqlite_timelimit() function. It makes use of a magic
value, N, which is the number of SQLite virtual machine instructions that
should execute in between calls to my termination decision function.

The value of N was not finely grained enough for my test to work - so I've
added logic that says that if the time limit is less than 50ms, N is set to 1.
This got the tests working.

Refs #95
This commit is contained in:
Simon Willison 2017-11-14 18:41:03 -08:00
commit 0b8c1b0a6d
3 changed files with 37 additions and 5 deletions

View file

@ -85,13 +85,21 @@ class CustomJSONEncoder(json.JSONEncoder):
@contextmanager
def sqlite_timelimit(conn, ms):
deadline = time.time() + (ms / 1000)
# n is the number of SQLite virtual machine instructions that will be
# executed between each check. It's hard to know what to pick here.
# After some experimentation, I've decided to go with 1000 by default and
# 1 for time limits that are less than 50ms
n = 1000
if ms < 50:
n = 1
def handler():
if time.time() >= deadline:
return 1
conn.set_progress_handler(handler, 10000)
conn.set_progress_handler(handler, n)
yield
conn.set_progress_handler(None, 10000)
conn.set_progress_handler(None, n)
class InvalidSql(Exception):