|
21 | 21 |
|
22 | 22 | from neo4j.v1 import GraphDatabase, READ_ACCESS, WRITE_ACCESS, SessionExpired, \ |
23 | 23 | RoutingDriver, RoutingConnectionPool, LeastConnectedLoadBalancingStrategy, LOAD_BALANCING_STRATEGY_ROUND_ROBIN, \ |
24 | | - RoundRobinLoadBalancingStrategy |
| 24 | + RoundRobinLoadBalancingStrategy, TransientError, ClientError |
25 | 25 | from neo4j.bolt import ProtocolError, ServiceUnavailable |
26 | 26 |
|
27 | 27 | from test.stub.tools import StubTestCase, StubCluster |
@@ -236,8 +236,79 @@ def test_can_select_round_robin_load_balancing_strategy(self): |
236 | 236 | self.assertIsInstance(driver._pool.load_balancing_strategy, RoundRobinLoadBalancingStrategy) |
237 | 237 |
|
238 | 238 | def test_no_other_load_balancing_strategies_are_available(self): |
239 | | - with StubCluster({9001: "router.script"}): |
| 239 | + uri = "bolt+routing://127.0.0.1:9001" |
| 240 | + with self.assertRaises(ValueError): |
| 241 | + with GraphDatabase.driver(uri, auth=self.auth_token, encrypted=False, load_balancing_strategy=-1): |
| 242 | + pass |
| 243 | + |
| 244 | + def test_forgets_address_on_not_a_leader_error(self): |
| 245 | + with StubCluster({9001: "router.script", 9006: "not_a_leader.script"}): |
240 | 246 | uri = "bolt+routing://127.0.0.1:9001" |
241 | | - with self.assertRaises(ValueError): |
242 | | - with GraphDatabase.driver(uri, auth=self.auth_token, encrypted=False, load_balancing_strategy=-1): |
243 | | - pass |
| 247 | + with GraphDatabase.driver(uri, auth=self.auth_token, encrypted=False) as driver: |
| 248 | + with driver.session(WRITE_ACCESS) as session: |
| 249 | + with self.assertRaises(ClientError): |
| 250 | + _ = session.run("CREATE (n {name:'Bob'})") |
| 251 | + |
| 252 | + pool = driver._pool |
| 253 | + table = pool.routing_table |
| 254 | + |
| 255 | + # address might still have connections in the pool, failed instance just can't serve writes |
| 256 | + assert ('127.0.0.1', 9006) in pool.connections |
| 257 | + assert table.routers == {('127.0.0.1', 9001), ('127.0.0.1', 9002), ('127.0.0.1', 9003)} |
| 258 | + assert table.readers == {('127.0.0.1', 9004), ('127.0.0.1', 9005)} |
| 259 | + # writer 127.0.0.1:9006 should've been forgotten because of an error |
| 260 | + assert len(table.writers) == 0 |
| 261 | + |
| 262 | + def test_forgets_address_on_forbidden_on_read_only_database_error(self): |
| 263 | + with StubCluster({9001: "router.script", 9006: "forbidden_on_read_only_database.script"}): |
| 264 | + uri = "bolt+routing://127.0.0.1:9001" |
| 265 | + with GraphDatabase.driver(uri, auth=self.auth_token, encrypted=False) as driver: |
| 266 | + with driver.session(WRITE_ACCESS) as session: |
| 267 | + with self.assertRaises(ClientError): |
| 268 | + _ = session.run("CREATE (n {name:'Bob'})") |
| 269 | + |
| 270 | + pool = driver._pool |
| 271 | + table = pool.routing_table |
| 272 | + |
| 273 | + # address might still have connections in the pool, failed instance just can't serve writes |
| 274 | + assert ('127.0.0.1', 9006) in pool.connections |
| 275 | + assert table.routers == {('127.0.0.1', 9001), ('127.0.0.1', 9002), ('127.0.0.1', 9003)} |
| 276 | + assert table.readers == {('127.0.0.1', 9004), ('127.0.0.1', 9005)} |
| 277 | + # writer 127.0.0.1:9006 should've been forgotten because of an error |
| 278 | + assert len(table.writers) == 0 |
| 279 | + |
| 280 | + def test_forgets_address_on_service_unavailable_error(self): |
| 281 | + with StubCluster({9001: "router.script", 9004: "rude_reader.script"}): |
| 282 | + uri = "bolt+routing://127.0.0.1:9001" |
| 283 | + with GraphDatabase.driver(uri, auth=self.auth_token, encrypted=False) as driver: |
| 284 | + with driver.session(READ_ACCESS) as session: |
| 285 | + with self.assertRaises(SessionExpired): |
| 286 | + _ = session.run("RETURN 1") |
| 287 | + |
| 288 | + pool = driver._pool |
| 289 | + table = pool.routing_table |
| 290 | + |
| 291 | + # address should not have connections in the pool, it has failed |
| 292 | + assert ('127.0.0.1', 9004) not in pool.connections |
| 293 | + assert table.routers == {('127.0.0.1', 9001), ('127.0.0.1', 9002), ('127.0.0.1', 9003)} |
| 294 | + # reader 127.0.0.1:9004 should've been forgotten because of an error |
| 295 | + assert table.readers == {('127.0.0.1', 9005)} |
| 296 | + assert table.writers == {('127.0.0.1', 9006)} |
| 297 | + |
| 298 | + def test_forgets_address_on_database_unavailable_error(self): |
| 299 | + with StubCluster({9001: "router.script", 9004: "database_unavailable.script"}): |
| 300 | + uri = "bolt+routing://127.0.0.1:9001" |
| 301 | + with GraphDatabase.driver(uri, auth=self.auth_token, encrypted=False) as driver: |
| 302 | + with driver.session(READ_ACCESS) as session: |
| 303 | + with self.assertRaises(TransientError): |
| 304 | + _ = session.run("RETURN 1") |
| 305 | + |
| 306 | + pool = driver._pool |
| 307 | + table = pool.routing_table |
| 308 | + |
| 309 | + # address should not have connections in the pool, it has failed |
| 310 | + assert ('127.0.0.1', 9004) not in pool.connections |
| 311 | + assert table.routers == {('127.0.0.1', 9001), ('127.0.0.1', 9002), ('127.0.0.1', 9003)} |
| 312 | + # reader 127.0.0.1:9004 should've been forgotten because of an error |
| 313 | + assert table.readers == {('127.0.0.1', 9005)} |
| 314 | + assert table.writers == {('127.0.0.1', 9006)} |
0 commit comments