Skip to content

Update tests for 5.0 handshake #384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 7, 2022
13 changes: 11 additions & 2 deletions boltstub/bolt_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ def get_bolt_protocol(version):
if version is None:
raise BoltMissingVersionError()
for sub in recursive_subclasses(BoltProtocol):
if (version == sub.protocol_version
or version in sub.version_aliases):
if version == sub.protocol_version or version in sub.version_aliases:
return sub
raise BoltUnknownVersionError(
"unsupported bolt version {}".format(version)
Expand Down Expand Up @@ -371,3 +370,13 @@ class Bolt4x4Protocol(Bolt4x3Protocol):
equivalent_versions = set()

server_agent = "Neo4j/4.4.0"


class Bolt5x0Protocol(Bolt4x4Protocol):

protocol_version = (5, 0)
version_aliases = set()
# allow the server to negotiate other bolt versions
equivalent_versions = set()

server_agent = "Neo4j/5.0.0"
4 changes: 2 additions & 2 deletions nutkit/protocol/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ class Feature(Enum):
AUTH_KERBEROS = "Feature:Auth:Kerberos"
# The driver supports Bolt protocol version 3
BOLT_3_0 = "Feature:Bolt:3.0"
# The driver supports Bolt protocol version 4.0
BOLT_4_0 = "Feature:Bolt:4.0"
# The driver supports Bolt protocol version 4.1
BOLT_4_1 = "Feature:Bolt:4.1"
# The driver supports Bolt protocol version 4.2
Expand All @@ -57,6 +55,8 @@ class Feature(Enum):
BOLT_4_3 = "Feature:Bolt:4.3"
# The driver supports Bolt protocol version 4.4
BOLT_4_4 = "Feature:Bolt:4.4"
# The driver supports Bolt protocol version 5.0
BOLT_5_0 = "Feature:Bolt:5.0"
# The driver supports impersonation
IMPERSONATION = "Feature:Impersonation"
# The driver supports TLS 1.1 connections.
Expand Down
10 changes: 2 additions & 8 deletions tests/neo4j/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def get_valid_test_case(*args, **kwargs):
return args[0]

@wraps(func)
@requires_min_bolt_version(protocol.Feature.BOLT_4_0)
@requires_min_bolt_version("4.0")
def wrapper(*args, **kwargs):
test_case = get_valid_test_case(*args, **kwargs)
if not get_server_info().supports_multi_db:
Expand All @@ -149,13 +149,7 @@ def wrapper(*args, **kwargs):
return wrapper


def requires_min_bolt_version(feature):
if not isinstance(feature, protocol.Feature):
raise TypeError("The arguments must be instances of Feature")
if not feature.name.startswith("BOLT_"):
raise ValueError("Bolt version feature expected")

min_version = feature.value.split(":")[-1]
def requires_min_bolt_version(min_version):
server_max_version = get_server_info().max_protocol_version
all_viable_versions = [
f for f in protocol.Feature
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"mode": "r", "db": "adb"}
S: FAILURE #ERROR#
S: <EXIT>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
C: BEGIN {"mode": "r", "db": "adb"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: RECORD [1]
SUCCESS {"type": "r"}
C: COMMIT
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
C: BEGIN {"mode": "r", "db": "adb"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
{{
C: PULL {"n": 1000}
S: RECORD [1]
SUCCESS {"type": "r"}
----
C: DISCARD {"n": -1}
S: SUCCESS {}
}}
C: COMMIT
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
C: BEGIN {"mode": "r", "db": "adb"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
C: BEGIN {"mode": "r", "db": "adb"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: SUCCESS {"fields": ["n"]}
{{
C: PULL {"n": 1000}
S: RECORD [1]
SUCCESS {"type": "r"}
----
C: DISCARD {"n": -1}
S: SUCCESS {}
}}
C: ROLLBACK
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: BEGIN {"mode": "r", "db": "adb"}
S: SUCCESS {}
C: RUN "RETURN 1 as n" {} {}
S: FAILURE #ERROR#
<EXIT>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
*: RESET
C: RUN "RETURN 1 as n" {} {"mode": "r", "db": "adb"}
S: SUCCESS {"fields": ["n"]}
C: PULL {"n": 1000}
S: FAILURE #ERROR#
<EXIT>
7 changes: 7 additions & 0 deletions tests/stub/authorization/scripts/v5x0/router.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
!: BOLT #VERSION#

A: HELLO {"{}": "*"}
C: ROUTE #ROUTINGCTX# [] {"{}": {"db": "adb"}}
S: SUCCESS { "rt": { "ttl": 1000, "servers": [{"addresses": ["#HOST#:9000"], "role":"ROUTE"}, {"addresses": ["#HOST#:9010", "#HOST#:9011"], "role":"READ"}, {"addresses": ["#HOST#:9020"], "role":"WRITE"}]}}
?: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_basic.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass", "[routing]": null, "[realm]": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_basic_minimal.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass"}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass", "realm": "foobar", "[routing]": null}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "basic", "principal": "neo4j", "credentials": "pass", "realm": "foobar"}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_bearer.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "bearer", "credentials": "QmFuYW5hIQ==", "[principal]": "", "[routing]": null, "[realm]": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_bearer_minimal.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "bearer", "credentials": "QmFuYW5hIQ=="}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_custom.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "wild-scheme", "principal": "I See Something", "credentials": "You Don't See!", "realm": "And it's blue.", "parameters": {"sky?": "no", "my eyes": 0.1, "da be dee da be daa?": true}, "[routing]": null}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_custom_empty.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "minimal-scheme", "principal": "", "[credentials]": "", "[realm]": "", "[parameters]": {}, "[routing]": null}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 5.0

# Server versions pre 4.4 require empty principal field. So for backwards compatibility, we expect the driver to send it.
A: HELLO {"user_agent": "*", "scheme": "minimal-scheme", "principal": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
13 changes: 13 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_custom_minimal.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
!: BOLT 5.0

A: HELLO {"user_agent": "*", "scheme": "wild-scheme", "principal": "I See Something", "credentials": "You Don't See!", "realm": "And it's blue.", "parameters": {"sky?": "no", "my eyes": 0.1, "da be dee da be daa?": true}}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
14 changes: 14 additions & 0 deletions tests/stub/authorization/scripts/v5x0/scheme_kerberos.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 5.0

# Server versions pre 4.4 require empty principal field. So for backwards compatibility, we expect the driver to send it.
A: HELLO {"user_agent": "*", "scheme": "kerberos", "principal": "", "credentials": "QmFuYW5hIQ==", "[routing]": null, "[realm]": ""}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
!: BOLT 5.0

# Server versions pre 4.4 require empty principal field. So for backwards compatibility, we expect the driver to send it.
A: HELLO {"user_agent": "*", "scheme": "kerberos", "principal": "", "credentials": "QmFuYW5hIQ=="}
*: RESET

C: RUN "RETURN 1 AS n" "*" "*"
S: SUCCESS {"fields": ["n"]}
C: PULL "*"
S: RECORD [1]
SUCCESS {"type": "r"}

*: RESET
?: GOODBYE
Loading