Skip to content

Commit

Permalink
Add tests for null, 0, and -1 tx timeout (#356)
Browse files Browse the repository at this point in the history
Changes the protocol:
 * tx timeout in protocol is now an optional field
  • Loading branch information
robsdedude authored Jan 19, 2022
1 parent fb07a87 commit dc4c783
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 18 deletions.
16 changes: 8 additions & 8 deletions nutkit/frontend/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ def close(self, hooks=None):
if not isinstance(res, protocol.Session):
raise Exception("Should be session but was: %s" % res)

def run(self, cypher, params=None, tx_meta=None, timeout=None, hooks=None):
def run(self, cypher, params=None, tx_meta=None, hooks=None, **kwargs):
req = protocol.SessionRun(self._session.id, cypher, params,
txMeta=tx_meta, timeout=timeout)
txMeta=tx_meta, **kwargs)
self._backend.send(req, hooks=hooks)
while True:
res = self._backend.receive(hooks=hooks)
Expand Down Expand Up @@ -91,23 +91,23 @@ def process_transaction(self, req, fn, config=None, hooks=None):
elif isinstance(res, protocol.RetryableDone):
return x

def read_transaction(self, fn, tx_meta=None, timeout=None, hooks=None):
def read_transaction(self, fn, tx_meta=None, hooks=None, **kwargs):
# Send request to enter transactional read function
req = protocol.SessionReadTransaction(
self._session.id, txMeta=tx_meta, timeout=timeout
self._session.id, txMeta=tx_meta, **kwargs
)
return self.process_transaction(req, fn, hooks=hooks)

def write_transaction(self, fn, tx_meta=None, timeout=None, hooks=None):
def write_transaction(self, fn, tx_meta=None, hooks=None, **kwargs):
# Send request to enter transactional read function
req = protocol.SessionWriteTransaction(
self._session.id, txMeta=tx_meta, timeout=timeout
self._session.id, txMeta=tx_meta, **kwargs
)
return self.process_transaction(req, fn, hooks=hooks)

def begin_transaction(self, tx_meta=None, timeout=None, hooks=None):
def begin_transaction(self, tx_meta=None, hooks=None, **kwargs):
req = protocol.SessionBeginTransaction(
self._session.id, txMeta=tx_meta, timeout=timeout
self._session.id, txMeta=tx_meta, **kwargs
)
res = self._backend.send_and_receive(req, hooks=hooks)
if not isinstance(res, protocol.Transaction):
Expand Down
20 changes: 12 additions & 8 deletions nutkit/protocol/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,13 @@ class SessionRun:
Backend should respond with a Result response or an Error response.
"""

def __init__(self, sessionId, cypher, params, txMeta=None, timeout=None):
def __init__(self, sessionId, cypher, params, txMeta=None, **kwargs):
self.sessionId = sessionId
self.cypher = cypher
self.params = params
self.txMeta = txMeta
self.timeout = timeout
if "timeout" in kwargs:
self.timeout = kwargs["timeout"]


class SessionReadTransaction:
Expand All @@ -253,10 +254,11 @@ class SessionReadTransaction:
Backend should respond with a RetryableTry response or an Error response.
"""

def __init__(self, sessionId, txMeta=None, timeout=None):
def __init__(self, sessionId, txMeta=None, **kwargs):
self.sessionId = sessionId
self.txMeta = txMeta
self.timeout = timeout
if "timeout" in kwargs:
self.timeout = kwargs["timeout"]


class SessionWriteTransaction:
Expand All @@ -266,10 +268,11 @@ class SessionWriteTransaction:
Backend should respond with a RetryableTry response or an Error response.
"""

def __init__(self, sessionId, txMeta=None, timeout=None):
def __init__(self, sessionId, txMeta=None, **kwargs):
self.sessionId = sessionId
self.txMeta = txMeta
self.timeout = timeout
if "timeout" in kwargs:
self.timeout = kwargs["timeout"]


class SessionBeginTransaction:
Expand All @@ -279,10 +282,11 @@ class SessionBeginTransaction:
Backend should respond with a Transaction response or an Error response.
"""

def __init__(self, sessionId, txMeta=None, timeout=None):
def __init__(self, sessionId, txMeta=None, **kwargs):
self.sessionId = sessionId
self.txMeta = txMeta
self.timeout = timeout
if "timeout" in kwargs:
self.timeout = kwargs["timeout"]


class SessionLastBookmarks:
Expand Down
14 changes: 14 additions & 0 deletions tests/stub/session_run_parameters/scripts/timeout_-1.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 4.4

A: HELLO {"{}": "*"}
*: RESET
# We expect the driver to not even try this. So should it do so nonetheless,
# we will let is pass to not cause any error. The error should be generated
# inside the driver.
C: BEGIN {"[tx_timeout]": "*"}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: RECORD [1]
SUCCESS {"type": "w"}
*: RESET
?: GOODBYE
11 changes: 11 additions & 0 deletions tests/stub/session_run_parameters/scripts/timeout_0.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
!: BOLT 4.4

A: HELLO {"{}": "*"}
*: RESET
C: RUN "RETURN 1 as n" {} {"tx_timeout": 0}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: RECORD [1]
SUCCESS {"type": "w"}
*: RESET
?: GOODBYE
11 changes: 11 additions & 0 deletions tests/stub/session_run_parameters/scripts/timeout_null.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
!: BOLT 4.4

A: HELLO {"{}": "*"}
*: RESET
C: RUN "RETURN 1 as n" {} {"[tx_timeout]": null}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: RECORD [1]
SUCCESS {"type": "w"}
*: RESET
?: GOODBYE
22 changes: 21 additions & 1 deletion tests/stub/session_run_parameters/test_session_run_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,29 @@ def test_tx_meta(self):
def test_timeout(self):
for routing in (True, False):
with self.subTest("routing" if routing else "direct"):
self._run("timeout", routing,
self._run("timeout_17", routing,
session_args=("w",), run_kwargs={"timeout": 17})

@driver_feature(types.Feature.BOLT_4_4)
def test_0_timeout(self):
self._run("timeout_0", routing=False,
session_args=("w",), run_kwargs={"timeout": 0})

@driver_feature(types.Feature.BOLT_4_4)
def test_null_timeout(self):
self._run("timeout_null", routing=False,
session_args=("w",), run_kwargs={"timeout": None})

@driver_feature(types.Feature.BOLT_4_4)
def test_default_timeout(self):
self._run("timeout_null", routing=False, session_args=("w",))

@driver_feature(types.Feature.BOLT_4_4)
def test_negative_timeout(self):
with self.assertRaises(types.DriverError):
self._run("timeout_-1", routing=False,
session_args=("w",), run_kwargs={"timeout": -1})

@driver_feature(types.Feature.IMPERSONATION,
types.Feature.BOLT_4_4)
def test_database(self):
Expand Down
17 changes: 17 additions & 0 deletions tests/stub/tx_begin_parameters/scripts/timeout_-1.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
!: BOLT 4.4

A: HELLO {"{}": "*"}
*: RESET
# We expect the driver to not even try this. So should it do so nonetheless,
# we will let is pass to not cause any error. The error should be generated
# inside the driver.
C: BEGIN {"[tx_timeout]": "*"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: SUCCESS {"type": "r"}
C: COMMIT
S: SUCCESS {}
*: RESET
?: GOODBYE
14 changes: 14 additions & 0 deletions tests/stub/tx_begin_parameters/scripts/timeout_0.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 4.4

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"tx_timeout": 0}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: SUCCESS {"type": "r"}
C: COMMIT
S: SUCCESS {}
*: RESET
?: GOODBYE
14 changes: 14 additions & 0 deletions tests/stub/tx_begin_parameters/scripts/timeout_null.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 4.4

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"[tx_timeout]": null}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: SUCCESS {"type": "r"}
C: COMMIT
S: SUCCESS {}
*: RESET
?: GOODBYE
23 changes: 22 additions & 1 deletion tests/stub/tx_begin_parameters/test_tx_begin_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,30 @@ def test_tx_meta(self):
def test_timeout(self):
for routing in (True, False):
with self.subTest("routing" if routing else "direct"):
self._run("timeout", routing,
self._run("timeout_17", routing,
session_args=("w",), tx_kwargs={"timeout": 17})

@driver_feature(types.Feature.BOLT_4_4)
def test_0_timeout(self):
self._run("timeout_0", routing=False,
session_args=("w",), tx_kwargs={"timeout": 0})

@driver_feature(types.Feature.BOLT_4_4)
def test_null_timeout(self):
self._run("timeout_null", routing=False,
session_args=("w",), tx_kwargs={"timeout": None})

@driver_feature(types.Feature.BOLT_4_4)
def test_negative_timeout(self):
with self.assertRaises(types.DriverError):
self._run("timeout_-1", routing=False,
session_args=("w",), tx_kwargs={"timeout": -1})

@driver_feature(types.Feature.BOLT_4_4)
def test_default_timeout(self):
self._run("timeout_null", routing=False,
session_args=("w",))

@driver_feature(types.Feature.BOLT_4_4)
def test_database(self):
for routing in (True, False)[1:]:
Expand Down

0 comments on commit dc4c783

Please sign in to comment.