def test_read(self): if self._driver in ["javascript"]: self.skipTest( "Transactional functions not implemented in testkit backend") script = "retry_read.script" if self._driver in ["go"]: # Until Go is updated to use PULL with n script = "retry_read_v3.script" self._server.start(os.path.join(scripts_path, script)) num_retries = 0 def retry_once(tx): nonlocal num_retries num_retries = num_retries + 1 result = tx.run("RETURN 1") record = result.next() return record.values[0] auth = AuthorizationToken(scheme="basic", principal="neo4j", credentials="pass") driver = Driver(self._backend, "bolt://%s" % self._server.address, auth) session = driver.session("r") x = session.readTransaction(retry_once) self.assertIsInstance(x, types.CypherInt) self.assertEqual(x.value, 1) self.assertEqual(num_retries, 1) session.close() driver.close() self._server.done()
class Transport(unittest.TestCase): def setUp(self): self._backend = new_backend() self._server = StubServer(9001) self._driverName = get_driver_name() auth = AuthorizationToken(scheme="basic", principal="neo4j", credentials="pass") uri = "bolt://%s" % self._server.address self._driver = Driver(self._backend, uri, auth) self._session = self._driver.session("w") def test_noop(self): # Verifies that no op messages sent on bolt chunking layer are ignored. The no op messages # are sent from server as a way to notify that the connection is still up. # Bolt 4.1 > bolt_version = "4.1" self._server.start(script=script, vars = {"$bolt_version": bolt_version}) result = self._session.run("RETURN 1 as n") record = result.next() nilrec = result.next() self._driver.close() self._server.done() # Verify the result self.assertEqual(record.values[0].value, 1) # Indirectly verifies that we got a record self.assertIsInstance(nilrec, types.NullRecord)
def test_read_twice(self): self._server.start( os.path.join(scripts_path, "retry_read_twice.script")) num_retries = 0 def retry_twice(tx): nonlocal num_retries num_retries = num_retries + 1 result = tx.run("RETURN 1") record = result.next() return record.values[0] auth = AuthorizationToken(scheme="basic", principal="neo4j", credentials="pass") driver = Driver(self._backend, "bolt://%s" % self._server.address, auth) session = driver.session("r") x = session.readTransaction(retry_twice) self.assertIsInstance(x, types.CypherInt) self.assertEqual(x.value, 1) self.assertEqual(num_retries, 2) session.close() driver.close() self._server.done()
def _run(self, n, script, end, expectedSequence, expectedError=False): uri = "bolt://%s" % self._server.address driver = Driver(self._backend, uri, AuthorizationToken(scheme="basic")) self._server.start(script=script, vars={ "#END#": end, "#VERSION#": "4" }) session = driver.session("w", fetchSize=n) result = session.run("RETURN 1 AS n") gotError = False sequence = [] while True: try: next = result.next() except Exception as e: gotError = True break if isinstance(next, types.NullRecord): break sequence.append(next.values[0].value) driver.close() self._server.done() self.assertEqual(expectedSequence, sequence) self.assertEqual(expectedError, gotError)
def test_nested(self): if get_driver_name() not in ['go', 'dotnet']: self.skipTest( "Need support for specifying session fetch size in testkit backend" ) uri = "bolt://%s" % self._server.address driver = Driver(self._backend, uri, AuthorizationToken(scheme="basic")) self._server.start(script=TxRun.script_nested_n, vars={"#VERSION#": "4"}) session = driver.session("w", fetchSize=1) tx = session.beginTransaction() res1 = tx.run("CYPHER") seq = [] seqs = [] while True: rec1 = res1.next() if isinstance(rec1, types.NullRecord): break seq.append(rec1.values[0].value) seq2 = [] res2 = tx.run("CYPHER") while True: rec2 = res2.next() if isinstance(rec2, types.NullRecord): break seq2.append(rec2.values[0].value) seqs.append(seq2) tx.commit() driver.close() self._server.done() self.assertEqual(["1_1", "1_2"], seq) self.assertEqual([["2_1", "2_2"], ["3_1"]], seqs)
def test_disconnect_on_commit(self): # Should NOT retry when connection is lost on unconfirmed commit. # The rule could be relaxed on read transactions therefore we test on writeTransaction. # An error should be raised to indicate the failure if not self._driverName in ["go"]: self.skipTest( "Backend missing support for SessionWriteTransaction") self._server.start(script=script_commit_disconnect) num_retries = 0 def once(tx): nonlocal num_retries num_retries = num_retries + 1 result = tx.run("RETURN 1") record = result.next() auth = AuthorizationToken(scheme="basic") driver = Driver(self._backend, "bolt://%s" % self._server.address, auth) session = driver.session("w") with self.assertRaises(types.DriverError) as e: # Check further... session.writeTransaction(once) self.assertEqual(num_retries, 1) session.close() driver.close() self._server.done()
class Tx(unittest.TestCase): def setUp(self): self._backend = new_backend() self._server = StubServer(9001) uri = "bolt://%s" % self._server.address self._driver = Driver(self._backend, uri, AuthorizationToken(scheme="basic")) def tearDown(self): self._backend.close() # If test raised an exception this will make sure that the stub server # is killed and it's output is dumped for analys. self._server.reset() # Tests that a committed transaction can return the last bookmark def test_last_bookmark(self): if get_driver_name() not in ["go", "dotnet"]: self.skipTest("session.lastBookmark not implemented in backend") self._server.start(script=script_commit) session = self._driver.session("w") tx = session.beginTransaction() tx.run("RETURN 1 as n") tx.commit() bookmarks = session.lastBookmarks() session.close() self._driver.close() self._server.done() self.assertEqual(bookmarks, ["bm"])
def try_connect(backend, server, scheme, host): url = "%s://%s:%d" % (scheme, host, 6666) # Doesn't really matter auth = AuthorizationToken(scheme="basic", principal="neo4j", credentials="pass") driver = Driver(backend, url, auth) session = driver.session("r") try: result = session.run("RETURN 1 as n") except: pass session.close() driver.close() return server.connected()
def test_session_run_read(self): if get_driver_name() not in ['go', 'dotnet']: self.skipTest( "Session with named database not implemented in backend") driver = Driver(self._backend, self._uri, self._auth, self._userAgent) self._routingServer.start(script=self.router_script(), vars=self.get_vars()) self._readServer.start(script=self.read_script(), vars=self.get_vars()) session = driver.session('r', database=self.get_db()) session.run("RETURN 1 as n") session.close() driver.close() self._routingServer.done() self._readServer.done()
class TestAuthenticationBasic(unittest.TestCase): def setUp(self): self._backend = new_backend() self._host, self._port = get_neo4j_host_and_port() self._scheme = "bolt://%s:%d" % (self._host, self._port) def tearDown(self): self._session.close() self._driver.close() self._backend.close() def createDriverAndSession(self, token): self._driver = Driver(self._backend, self._scheme, token) self._session = self._driver.session("r") def verifyConnectivity(self, auth_token): self.createDriverAndSession(auth_token) result = self._session.run("RETURN 2 as Number") self.assertEqual(result.next(), types.Record(values=[types.CypherInt(2)])) def testErrorOnIncorrectCredentials(self): auth_token = AuthorizationToken(scheme="basic", principal="fake", credentials="fake") with self.assertRaises( types.DriverError ) as e: # TODO: Expand this to check errorType is AuthenticationError self.verifyConnectivity(auth_token) # Tests both basic with realm specified and also custom auth token. All def testSuccessOnProvideRealmWithBasicToken(self): auth_token = AuthorizationToken( scheme="basic", realm="native", principal=os.environ.get(env_neo4j_user, "neo4j"), credentials=os.environ.get(env_neo4j_pass, "pass")) self.verifyConnectivity(auth_token) def testSuccessOnBasicToken(self): auth_token = AuthorizationToken( scheme="basic", principal=os.environ.get(env_neo4j_user, "neo4j"), credentials=os.environ.get(env_neo4j_pass, "pass")) self.verifyConnectivity(auth_token)
def test_tx_run_write(self): if get_driver_name() not in ['go', 'dotnet']: self.skipTest( "Session with named database not implemented in backend") driver = Driver(self._backend, self._uri, self._auth, self._userAgent) self._routingServer.start(script=self.router_script(), vars=self.get_vars()) self._writeServer.start(script=self.write_tx_script(), vars=self.get_vars()) session = driver.session('w', database=self.get_db()) tx = session.beginTransaction() tx.run("RETURN 1 as n") tx.commit() session.close() driver.close() self._routingServer.done() self._writeServer.done()
def test_session_run_read(self): if get_driver_name() not in ['go', 'dotnet']: self.skipTest( "Session with named database not implemented in backend") # Driver is configured to talk to "routing" stub server uri = "bolt://%s" % self._server.address self._server.start(script=self.script(), vars=self.get_vars()) driver = Driver(self._backend, uri, AuthorizationToken(scheme="basic", principal="p", credentials="c"), userAgent="007") session = driver.session('r', database="adb") session.run("RETURN 1 as n") session.close() driver.close() self._server.done()
def test_read_twice(self): # We could probably use AUTO RESET in the script but this makes the diffs more # obvious. vars = { "$extra_reset_1": "", "$extra_reset_2": "", } if self._driverName not in ["go"]: vars["$extra_reset_2"] = "C: RESET\nS: SUCCESS {}" if self._driverName in ["java", "javascript"]: vars["$extra_reset_1"] = "C: RESET\nS: SUCCESS {}" self._server.start(script=script_retry, vars=vars) num_retries = 0 def twice(tx): nonlocal num_retries num_retries = num_retries + 1 result = tx.run("RETURN 1") record = result.next() return record.values[0] auth = AuthorizationToken(scheme="basic", principal="neo4j", credentials="pass") driver = Driver(self._backend, "bolt://%s" % self._server.address, auth) session = driver.session("r") x = session.readTransaction(twice) self.assertIsInstance(x, types.CypherInt) self.assertEqual(x.value, 1) self.assertEqual(num_retries, 2) session.close() driver.close() self._server.done()
class TestDataTypes(unittest.TestCase): def setUp(self): self._backend = new_backend() self._host, self._port = get_neo4j_host_and_port() self._scheme = "bolt://%s:%d" % (self._host, self._port) self._session = None self._driver = None def tearDown(self): if self._session: self._session.close() if self._driver: self._driver.close() self._backend.close() def createDriverAndSession(self): auth_token = AuthorizationToken( scheme="basic", principal=os.environ.get(env_neo4j_user, "neo4j"), credentials=os.environ.get(env_neo4j_pass, "pass")) self._driver = Driver(self._backend, self._scheme, auth_token) self._session = self._driver.session("w") def verifyCanEcho(self, val): result = self._session.run("RETURN $x as y", params={"x": val}) record = result.next() self.assertEqual(record, types.Record(values=[val])) def testShouldEchoBack(self): if get_driver_name() in ['java']: self.skipTest("Not implemented in backend") vals = [ types.CypherBool(True), types.CypherBool(False), types.CypherNull(), types.CypherInt(1), types.CypherInt(-7), types.CypherInt(-129), types.CypherInt(129), types.CypherInt(2147483647), types.CypherInt(-2147483647), #types.CypherFloat(9223372036854775807), # TODO: Investigate #types.CypherFloat(-9223372036854775807), #types.CypherFloat(1.7976931348623157E+308), #types.CypherFloat(2.2250738585072014e-308), #types.CypherFloat(4.9E-324), #types.CypherFloat(0.0), # Js can not determine if it should be 0 or 0.0 types.CypherFloat(1.1), types.CypherString("1"), types.CypherString("-17∂ßå®"), types.CypherString("String"), types.CypherString(""), ] self.createDriverAndSession() for val in vals: self.verifyCanEcho(val) def testShouldEchoVeryLongList(self): if get_driver_name() in ['java']: self.skipTest("Not implemented in backend") vals = [ types.CypherNull(), types.CypherInt(1), types.CypherFloat(1.1), types.CypherString("hello"), types.CypherBool(True), ] self.createDriverAndSession() for val in vals: long_list = [] for i in range(1000): long_list.append(val) self.verifyCanEcho(types.CypherList(long_list)) def testShouldEchoVeryLongString(self): if get_driver_name() in ['java']: self.skipTest("Not implemented in backend") self.createDriverAndSession() long_string = "*" * 10000 self.verifyCanEcho(types.CypherString(long_string)) def testShouldEchoNestedLists(self): if get_driver_name() in ['java']: self.skipTest("Not implemented in backend") test_lists = [ types.CypherList([ types.CypherInt(1), types.CypherInt(2), types.CypherInt(3), types.CypherInt(4) ]), types.CypherList([ types.CypherString("a"), types.CypherString("b"), types.CypherString("c"), types.CypherString("˚C") ]), types.CypherList([types.CypherBool(True), types.CypherBool(False)]), types.CypherList([ types.CypherFloat(1.1), types.CypherFloat(2.2), types.CypherFloat(3.3), types.CypherFloat(4.4) ]), types.CypherList([types.CypherNull(None), types.CypherNull(None)]), types.CypherList([ types.CypherNull(None), types.CypherBool(True), types.CypherString("Hello world"), types.CypherInt(-1234567890), types.CypherFloat(123.456) ]) ] self.createDriverAndSession() self.verifyCanEcho(types.CypherList(test_lists)) def testShouldEchoNode(self): self.createDriverAndSession() result = self._session.run( "CREATE (n:TestLabel {num: 1, txt: 'abc'}) RETURN n") record = result.next() self.assertNotIsInstance(record, types.NullRecord) node = record.values[0] self.assertIsInstance(node, types.CypherNode) self.assertEqual(node.labels, types.CypherList([types.CypherString('TestLabel')])) self.assertEqual( node.props, types.CypherMap({ "num": types.CypherInt(1), "txt": types.CypherString('abc') })) # Work in progress def testShouldEchoVeryLongMap(self): if get_driver_name() not in ['dotnet', 'go']: self.skipTest("Not implemented in backend") test_list = [ types.CypherNull(None), types.CypherInt(1), types.CypherFloat(1.1), types.CypherString("Hello World"), types.CypherBool(True) ] self.createDriverAndSession() long_map = {} for cypherType in test_list: long_map.clear() for i in range(1000): long_map[str(i)] = cypherType self.verifyCanEcho(types.CypherMap(long_map)) def testShouldEchoNestedMap(self): if get_driver_name() not in ['dotnet', 'go']: self.skipTest("Not implemented in backend") test_maps = { "a": types.CypherMap({ "a": types.CypherInt(1), "b": types.CypherInt(2), "c": types.CypherInt(3), "d": types.CypherInt(4) }), "b": types.CypherMap({ "a": types.CypherBool(True), "b": types.CypherBool(False) }), "c": types.CypherMap({ "a": types.CypherFloat(1.1), "b": types.CypherFloat(2.2), "c": types.CypherFloat(3.3) }), "d": types.CypherMap({ "a": types.CypherString("a"), "b": types.CypherString("b"), "c": types.CypherString("c"), "temp": types.CypherString("˚C") }), "e": types.CypherMap({"a": types.CypherNull(None)}), "f": types.CypherMap({ "a": types.CypherInt(1), "b": types.CypherBool(True), "c": types.CypherFloat(3.3), "d": types.CypherString("Hello World"), "e": types.CypherNull(None) }), } self.createDriverAndSession() self.verifyCanEcho(types.CypherMap(test_maps))
class SessionRunDisconnected(unittest.TestCase): def setUp(self): self._backend = new_backend() self._server = StubServer(9001) self._driverName = get_driver_name() auth = AuthorizationToken(scheme="basic", principal="neo4j", credentials="pass") uri = "bolt://%s" % self._server.address self._driver = Driver(self._backend, uri, auth, userAgent=customUserAgent) self._session = self._driver.session("w") def tearDown(self): self._backend.close() # If test raised an exception this will make sure that the stub server # is killed and it's output is dumped for analys. self._server.reset() # Helper function that runs the sequence and returns the name of the step at which the # error happened. def _run(self): try: result = self._session.run("RETURN 1 as n") except types.DriverError: return "after run" try: record = result.next() except types.DriverError: return "after first next" try: nullRecord = result.next() except types.DriverError: return "after last next" return "success" def test_disconnect_on_hello(self): # Verifies how the driver handles when server disconnects right after driver sent bolt # hello message. if not self._driverName in ["go"]: self.skipTest( "No support for custom user-agent in testkit backend") self._server.start(script=script_on_hello) step = self._run() self._session.close() self._driver.close() self._server.done() expectedStep = "after first next" if self._driverName in ["go"]: # Go reports this error earlier expectedStep = "after run" self.assertEqual(step, expectedStep) def test_disconnect_on_run(self): # Verifies how the driver handles when server disconnects right after driver sent bolt # run message. self._server.start(script=script_on_run) step = self._run() self._session.close() self._driver.close() self._server.done() expectedStep = "after first next" if self._driverName in ["go"]: # Go reports this error earlier expectedStep = "after run" self.assertEqual(step, expectedStep) def test_disconnect_on_pull(self): # Verifies how the driver handles when server disconnects right after driver sent bolt # pull message. self._server.start(script=script_on_pull) step = self._run() self._session.close() self._driver.close() self._server.done() expectedStep = "after first next" if self._driverName in ["go"]: # Go reports this error earlier expectedStep = "after run" self.assertEqual(step, expectedStep)
class TestBoltTypes(unittest.TestCase): def setUp(self): self._backend = new_backend() self._host, self._port = get_neo4j_host_and_port() self._scheme = "bolt://%s:%d" % (self._host, self._port) def tearDown(self): self._session.close() self._driver.close() self._backend.close() def createDriverAndSession(self): auth_token = AuthorizationToken( scheme="basic", principal=os.environ.get(env_neo4j_user, "neo4j"), credentials=os.environ.get(env_neo4j_pass, "pass")) self._driver = Driver(self._backend, self._scheme, auth_token) self._session = self._driver.session("r") def testShouldEchoBack(self): test_map = { True: types.CypherBool, False: types.CypherBool, None: types.CypherNull, 1: types.CypherInt, -7: types.CypherInt, -129: types.CypherInt, 129: types.CypherInt, 2147483647: types.CypherInt, -2147483647: types.CypherInt, 9223372036854775807: types.CypherFloat, -9223372036854775807: types.CypherFloat, 1.7976931348623157E+308: types.CypherFloat, 2.2250738585072014e-308: types.CypherFloat, 4.9E-324: types.CypherFloat, 0.0: types.CypherFloat, 1.1: types.CypherFloat, "1": types.CypherString, "-17∂ßå®": types.CypherString, "String": types.CypherString, "": types.CypherString } self.createDriverAndSession() for key, value in test_map.items(): self.verifyCanEchoKeyValue(key, value) def testShouldEchoVeryLongList(self): test_map = { None: types.CypherNull, 1: types.CypherInt, 1.1: types.CypherFloat, "hello": types.CypherString, True: types.CypherBool } self.createDriverAndSession() long_list = [] for key, value in test_map.items(): long_list.clear() for i in range(1000): long_list.append(value(key)) self.verifyCanEcho(long_list, types.CypherList) def testShouldEchoVeryLongString(self): self.createDriverAndSession() long_string = "*" * 10000 self.verifyCanEcho(long_string, types.CypherString) # def testShouldEchoVeryLongMap(self): # todo: need to implement the cypher map type to do this test. def testShouldEchoNestedLst(self): test_lists = [ types.CypherList([ types.CypherInt(1), types.CypherInt(2), types.CypherInt(3), types.CypherInt(4) ]), types.CypherList([ types.CypherString("a"), types.CypherString("b"), types.CypherString("c"), types.CypherString("˚C") ]), types.CypherList([types.CypherBool(True), types.CypherBool(False)]), types.CypherList([ types.CypherFloat(1.1), types.CypherFloat(2.2), types.CypherFloat(3.3), types.CypherFloat(4.4) ]), types.CypherList([types.CypherNull(None), types.CypherNull(None)]), types.CypherList([ types.CypherNull(None), types.CypherBool(True), types.CypherString("Hello world"), types.CypherInt(-1234567890), types.CypherFloat(1.7976931348623157E+308) ]) ] self.createDriverAndSession() self.verifyCanEcho(test_lists, types.CypherList) # def testShouldEchoNestedMap(self): # todo: need to implement the cypher map type to do this test. def verifyCanEcho(self, key, value): result = self._session.run("RETURN $x as y", params={"x": value(key)}) self.assertEqual(result.next(), types.Record(values=[key]))
class SessionRunParameters(unittest.TestCase): def setUp(self): self._backend = new_backend() self._server = StubServer(9001) self._driverName = get_driver_name() auth = AuthorizationToken() uri = "bolt://%s" % self._server.address self._driver = Driver(self._backend, uri, AuthorizationToken(scheme="basic")) def tearDown(self): self._backend.close() # If test raised an exception this will make sure that the stub server # is killed and it's output is dumped for analys. self._server.reset() def _run(self, accessMode, params=None, bookmarks=None, txMeta=None, timeout=None): session = self._driver.session(accessMode, bookmarks=bookmarks) try: result = session.run("RETURN 1 as n", params=params, txMeta=txMeta, timeout=timeout) result.next() finally: session.close() def test_accessmode_read(self): if self._driverName not in ["go", "java", "dotnet"]: self.skipTest("Session accessmode not implemented in backend") self._server.start(script=script_accessmode_read) self._run("r") self._driver.close() self._server.done() def test_accessmode_write(self): self._server.start(script=script_accessmode_write) self._run("w") self._driver.close() self._server.done() def test_bookmarks(self): if self._driverName not in ["go", "dotnet"]: self.skipTest("Session bookmarks not implemented in backend") self._server.start(script=script_bookmarks) self._run("w", bookmarks=["b1", "b2"]) self._driver.close() self._server.done() def test_txmeta(self): if self._driverName not in ["go", "dotnet"]: self.skipTest("Session txmeta not implemented in backend") self._server.start(script=script_txmeta) self._run("w", txMeta={"akey": "aval"}) self._driver.close() self._server.done() def test_timeout(self): if self._driverName not in ["go", "dotnet"]: self.skipTest("Session timeout not implemented in backend") self._server.start(script=script_timeout) self._run("w", timeout=17) self._driver.close() self._server.done() def test_combined(self): if self._driverName not in ["go", "dotnet"]: self.skipTest("Session parameters not implemented in backend") self._server.start(script=script_combined) self._run("r", params={"p": types.CypherInt(1)}, bookmarks=["b0"], txMeta={"k": "v"}, timeout=11) self._driver.close() self._server.done()