예제 #1
0
        public void TransactionCommitInTransactionScope()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var commitRequest          = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var scope = new TransactionScope())
                {
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                    scope.Complete();
                }
            }
        }
예제 #2
0
        public void OnTransactionDisposeCallRollback()
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var rollbackTransactionRequest = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                }
            }
        }
예제 #3
0
        public void CommitFailsOnPendingAsyncRequests()
        {
            const string queryText    = @"MATCH (n) RETURN count(n) as Total";
            const string resultColumn = @"{'columns':['Total'], 'data':[{'row':[1]}]}";

            var cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };

            using (var testHarness = new RestTestHarness(false)
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                }
            })
            {
                var client    = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient)client;
                using (var tran = client.BeginTransaction())
                {
                    rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(cypherQuery);
                    tran.Commit();
                }
            }
        }
예제 #4
0
        public void UpdateTransactionEndpointAfterFirstRequest()
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var rollbackTransactionRequest = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    Assert.AreEqual(
                        new Uri("http://foo/db/data/transaction/1"),
                        ((INeo4jTransaction)((TransactionScopeProxy)transaction).TransactionContext).Endpoint);
                }
            }
        }
        //https://github.com/Readify/Neo4jClient/issues/127
        public void ReturnsThe404_WhenVersionIsLessThan_2_2_6([Values(RestTestHarness.Neo4jVersion.Neo20, RestTestHarness.Neo4jVersion.Neo22, RestTestHarness.Neo4jVersion.Neo225)] RestTestHarness.Neo4jVersion version)
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var rollbackTransactionRequest = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateCypherErrorResponse(1, "{\"code\":\"Neo.ClientError.Schema.ConstraintViolation\",\"message\":\"Node 19572 already exists with label User and property.\"}"), "http://foo/db/data/transaction/1")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}")
                }
            })
            {
                var client = testHarness.CreateGraphClient(version);
                client.Connect();
                try
                {
                    using (var transaction = client.BeginTransaction())
                    {
                        client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults();
                    }
                }
                catch (ApplicationException ex)
                {
                    Assert.That(ex.Message.Contains("404"));
                }
            }
        }
        //https://github.com/Readify/Neo4jClient/issues/127
        public void ReturnsCorrectError_WhenTransactionIsAutomaticallyRolledBack_ViaNeo4j_2_2_6_Plus([Values(RestTestHarness.Neo4jVersion.Neo226 /*, RestTestHarness.Neo4jVersion.Neo23*/)] RestTestHarness.Neo4jVersion version)
        {
            /* In 2.2.6 ClientErrors (Constraint Violations etc) were changed to Automatically rollback. This created a 404 error when *we* tried to rollback on an error, as the transaction no longer existed. */
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var rollbackTransactionRequest = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateCypherErrorResponse(1, "{\"code\":\"Neo.ClientError.Schema.ConstraintViolation\",\"message\":\"Node 19572 already exists with label User and property.\"}"), "http://foo/db/data/transaction/1")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}")
                }
            })
            {
                var client = testHarness.CreateGraphClient(version);
                client.Connect();
                using (var transaction = client.BeginTransaction())
                {
                    client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults();
                }
            }
        }
        //https://github.com/Readify/Neo4jClient/issues/127
        public void ReturnsThe404_WhenVersionIs_2_2_6_Plus_WhenActuallyTimingOut([Values(RestTestHarness.Neo4jVersion.Neo226, RestTestHarness.Neo4jVersion.Neo23)] RestTestHarness.Neo4jVersion version)
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var rollbackTransactionRequest = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness()
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(404, "{\"results\":[],\"errors\":[{\"code\":\"Neo.ClientError.Transaction.UnknownId\",\"message\":\"Unrecognized transaction id. Transaction may have timed out and been rolled back.\"}]}")
                }
            })
            {
                var client = testHarness.CreateGraphClient(version);
                client.Connect();
                try
                {
                    using (var transaction = client.BeginTransaction())
                    {
                        client.Cypher.Match("n").Return(n => n.Count()).ExecuteWithoutResults();
                    }
                    Assert.Fail("Should not reach this code, as there is an expected exception.");
                }
                catch (ApplicationException ex)
                {
                    Assert.That(ex.Message.Contains("404"));
                }
            }
        }
예제 #8
0
        public void ExecuteAsyncRequestInTransaction()
        {
            const string queryText    = @"MATCH (n) RETURN count(n) as Total";
            const string resultColumn = @"{'columns':['Total'], 'data':[{'row':[1]}]}";

            var cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };
            var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client    = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient)client;
                using (var tran = client.BeginTransaction())
                {
                    var totalObj = rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(cypherQuery).Result.Single();
                    Assert.AreEqual(1, totalObj.Total);
                    tran.Commit();
                }
            }
        }
예제 #9
0
        public void PromoteDurableInAmbientTransaction()
        {
            // when two durables are registered they get promoted

            // this request will be made by the ForceKeepAlive() call when PSPE registration fails for the second client
            var afterPspeFailRequest = MockRequest.PostJson("/transaction", @"{'statements': []}");
            // this request will be mode in Promote() after second durable enlistment
            var promoteRequest         = MockRequest.PostJson("/transaction/1", @"{'statements': []}");
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");

            var secondClientRequest = MockRequest.PostJson("/transaction/2", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");

            // there are no delete requests because those will be made in another app domain

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    secondClientRequest,
                    MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    afterPspeFailRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(2), "http://foo/db/data/transaction/2")
                },
                {
                    promoteRequest,
                    MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                using (var scope = new TransactionScope())
                {
                    var client = testHarness.CreateAndConnectTransactionalGraphClient();

                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    var client2 = testHarness.CreateAndConnectTransactionalGraphClient();

                    client2.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                }

                // we sleep so that the app domain for the resource manager gets cleaned up
                Thread.Sleep(500);
            }
        }
예제 #10
0
        public void NestedTransactionMixedBetweenTransactionScopeAndBeginTransaction()
        {
            const string queryText      = @"MATCH (n) RETURN count(n)";
            const string resultColumn   = @"{'columns':['count(n)'], 'data':[{'row':[1]}]}";
            var          cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var          cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };
            var deleteRequest = MockRequest.Delete("/transaction/1");
            var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(commitRequest))
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var parentTx = client.BeginTransaction())
                {
                    using (var msTransaction = new TransactionScope())
                    {
                        Assert.IsTrue(client.InTransaction);

                        using (var tx = client.BeginTransaction())
                        {
                            long total = client.Cypher
                                         .Match("(n)")
                                         .Return(n => n.Count())
                                         .Results
                                         .SingleOrDefault();

                            Assert.AreEqual(1, total);

                            // should not be called
                            tx.Commit();
                        }

                        msTransaction.Complete();
                    }
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
예제 #11
0
        public void SuppressTransactionScopeShouldNotEmitTransactionalQuery()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");

            var nonTransactionalRequest = MockRequest.PostJson("/cypher", @"{'query': 'MATCH n\r\nRETURN count(n)', 'params': {}}");

            var commitTransactionRequest = MockRequest.PostJson("/transaction/1/commit", @"{
                'statements': []}");
            var deleteRequest            = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitTransactionRequest,
                    MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    nonTransactionalRequest,
                    MockResponse.Json(200, @"{'columns':['count(n)'], 'data':[[0]] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(deleteRequest))
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var tran = new TransactionScope())
                {
                    using (var tran2 = new TransactionScope(TransactionScopeOption.Suppress))
                    {
                        client.Cypher
                        .Match("n")
                        .Return(n => n.Count())
                        .ExecuteWithoutResults();

                        // no rollback should be generated
                    }

                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    tran.Complete();
                }
            }
        }
예제 #12
0
        public void TestTransactionScopeWithComplexDeserialization_WithCulture()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("nb-NO");

            const string queryText      = @"MATCH (dt:DummyTotal) RETURN dt";
            const string resultColumn   = @"{'columns':['dt'],'data':[{'row':[{'date':'2015-07-27T22:30:35Z'}]}]}";
            var          cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var          cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };
            var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                client.JsonContractResolver = new CamelCasePropertyNamesContractResolver();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.IsTrue(client.InTransaction);

                    var query = client.Cypher.Match("(dt:DummyTotal)")
                                .Return(dt => dt.As <DateHolder>());

                    var eResults = query.Results;
                    var results  = eResults.ToList();

                    Assert.AreEqual(1, results.Count);
                    var date = results.First().Date;

                    Assert.AreEqual(date.Kind, DateTimeKind.Utc);
                    Assert.AreEqual(new DateTime(2015, 7, 27, 22, 30, 35), results.First().Date);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
예제 #13
0
        public void NestedJoinedTransactionScope()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var secondRequest          = MockRequest.PostJson("/transaction/1", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var deleteRequest          = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    secondRequest,
                    MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    deleteRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var scope = new TransactionScope())
                {
                    using (var scope2 = new TransactionScope())
                    {
                        client.Cypher
                        .Match("n")
                        .Return(n => n.Count())
                        .ExecuteWithoutResults();

                        // this will not commit
                        scope2.Complete();
                    }

                    // this should generate a request to the known transaction ID
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();
                }
            }
        }
예제 #14
0
        public void ExecuteMultipleStatementInOneRequest()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}, {'statement': 'MATCH t\r\nRETURN count(t)', 'resultDataContents':[], 'parameters': {}}]}");
            var commitRequest          = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    var rawClient = client as IRawGraphClient;
                    if (rawClient == null)
                    {
                        Assert.Fail("ITransactionalGraphClient is not IRawGraphClient");
                    }

                    var queries = new List <CypherQuery>()
                    {
                        client.Cypher
                        .Match("n")
                        .Return(n => n.Count())
                        .Query,
                        client.Cypher
                        .Match("t")
                        .Return(t => t.Count())
                        .Query
                    };

                    rawClient.ExecuteMultipleCypherQueriesInTransaction(queries);
                    transaction.Commit();
                }
            }
        }
예제 #15
0
        public void DeserializeResultsFromTransaction()
        {
            var initTransactionRequest     = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var deserializationRequest     = MockRequest.PostJson("/transaction/1", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var rollbackTransactionRequest = MockRequest.Delete("/transaction/1");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    deserializationRequest,
                    MockResponse.Json(200, @"{'results':[{'columns': ['count(n)'], 'data': [{'row': [0]}]}]}")
                },
                {
                    rollbackTransactionRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    // this query will hit the deserializer
                    var count = client.Cypher
                                .Match("n")
                                .Return(n => n.Count())
                                .Results;

                    Assert.AreEqual(count.First(), 0);
                }
            }
        }
예제 #16
0
        public void TestTransactionScopeWithComplexDeserialization()
        {
            const string queryText      = @"MATCH (dt:DummyTotal) RETURN dt";
            const string resultColumn   = @"{'columns':['dt'],'data':[{'row':[{'total':1234}]}]}";
            var          cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var          cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };
            var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                client.JsonContractResolver = new CamelCasePropertyNamesContractResolver();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.IsTrue(client.InTransaction);

                    var results = client.Cypher.Match("(dt:DummyTotal)")
                                  .Return(dt => dt.As <DummyTotal>())
                                  .Results
                                  .ToList();

                    Assert.AreEqual(1, results.Count());
                    Assert.AreEqual(1234, results.First().Total);

                    msTransaction.Complete();
                }

                Assert.IsFalse(client.InTransaction);
            }
        }
예제 #17
0
        public void TestTransactionScopeWithSimpleDeserialization()
        {
            const string queryText      = @"MATCH (n) RETURN count(n)";
            const string resultColumn   = @"{'columns':['count(n)'], 'data':[{'row':[1]}]}";
            var          cypherQuery    = new CypherQuery(queryText, new Dictionary <string, object>(), CypherResultMode.Projection);
            var          cypherApiQuery = new CypherStatementList {
                new CypherTransactionStatement(cypherQuery, false)
            };
            var commitRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    MockRequest.PostObjectAsJson("/transaction", cypherApiQuery),
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, resultColumn), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var msTransaction = new TransactionScope())
                {
                    Assert.True(client.InTransaction);

                    long total = client.Cypher
                                 .Match("(n)")
                                 .Return(n => n.Count())
                                 .Results
                                 .SingleOrDefault();

                    Assert.Equal(1, total);

                    msTransaction.Complete();
                }

                Assert.False(client.InTransaction);
            }
        }
예제 #18
0
        public void SecondRequestDoesntReturnCreateHttpStatus()
        {
            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}]}");
            var secondRequest          = MockRequest.PostJson("/transaction/1", @"{
                'statements': [{'statement': 'MATCH t\r\nRETURN count(t)', 'resultDataContents':[], 'parameters': {}}]}");
            var commitRequest          = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                },
                {
                    secondRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy queries to generate request
                    client.Cypher
                    .Match("n")
                    .Return(n => n.Count())
                    .ExecuteWithoutResults();

                    client.Cypher
                    .Match("t")
                    .Return(t => t.Count())
                    .ExecuteWithoutResults();

                    transaction.Commit();
                }
            }
        }
예제 #19
0
        public void CommitWithoutRequestsShouldNotGenerateMessage()
        {
            var initTransactionRequest   = MockRequest.PostJson("/transaction", @"{'statements': []}");
            var commitTransactionRequest = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest, MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitTransactionRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            }.ShouldNotBeCalled(initTransactionRequest, commitTransactionRequest))
            {
                var client = testHarness.CreateAndConnectTransactionalGraphClient();
                using (var transaction = client.BeginTransaction())
                {
                    // no requests
                    transaction.Commit();
                }
            }
        }
예제 #20
0
        public void AsyncRequestsInTransactionShouldBeExecutedInOrder()
        {
            const string queryTextBase    = @"MATCH (n) RETURN {0} as Total";
            const string resultColumnBase = @"{{'columns':['Total'], 'data':[{{'row':[{0}]}}]}}";
            const int    asyncRequests    = 15;

            var queries     = new CypherQuery[asyncRequests];
            var apiQueries  = new CypherStatementList[asyncRequests];
            var responses   = new MockResponse[asyncRequests];
            var testHarness = new RestHarnessWithCounter();

            for (int i = 0; i < asyncRequests; i++)
            {
                queries[i] = new CypherQuery(string.Format(queryTextBase, i), new Dictionary <string, object>(),
                                             CypherResultMode.Projection);
                apiQueries[i] = new CypherStatementList {
                    new CypherTransactionStatement(queries[i], false)
                };
                responses[i] = MockResponse.Json(200,
                                                 @"{'results':[" + string.Format(resultColumnBase, i) + @"], 'errors':[] }");
                if (i > 0)
                {
                    testHarness.Add(MockRequest.PostObjectAsJson("/transaction/1", apiQueries[i]), responses[i]);
                }
            }

            testHarness.Add(
                MockRequest.PostObjectAsJson("/transaction", apiQueries[0]),
                MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1, string.Format(resultColumnBase, 0)),
                                  "http://foo/db/data/transaction/1")
                );
            testHarness.Add(
                MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}"),
                MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                );
            try
            {
                var client    = testHarness.CreateAndConnectTransactionalGraphClient();
                var rawClient = (IRawGraphClient)client;
                var tasks     = new Task[asyncRequests];
                using (var tran = client.BeginTransaction())
                {
                    for (int i = 0; i < asyncRequests; i++)
                    {
                        int tmpResult = i;
                        tasks[i] = rawClient.ExecuteGetCypherResultsAsync <DummyTotal>(queries[i]).ContinueWith(task =>
                        {
                            Assert.AreEqual(tmpResult, task.Result.Single().Total);
                        });
                    }

                    Task.WaitAll(tasks);
                    tran.Commit();
                }
            }
            finally
            {
                testHarness.Dispose();
            }

            // check that we have a total order
            Assert.AreEqual(asyncRequests, testHarness.Queue.Count);
            int lastElement = -1;

            for (int i = 0; i < asyncRequests; i++)
            {
                int headItem;
                Assert.IsTrue(testHarness.Queue.TryDequeue(out headItem));
                Assert.Greater(headItem, lastElement);
                lastElement = headItem;
            }
        }
예제 #21
0
        public void ExecuteMultipleStatementInOneRequestHttpRequest()
        {
            const string headerName    = "MyTestHeader";
            const string headerValue   = "myTestHeaderValue";
            var          customHeaders = new NameValueCollection {
                { headerName, headerValue }
            };


            var initTransactionRequest = MockRequest.PostJson("/transaction", @"{
                'statements': [{'statement': 'MATCH n\r\nRETURN count(n)', 'resultDataContents':[], 'parameters': {}}, {'statement': 'MATCH t\r\nRETURN count(t)', 'resultDataContents':[], 'parameters': {}}]}");
            var commitRequest          = MockRequest.PostJson("/transaction/1/commit", @"{'statements': []}");

            using (var testHarness = new RestTestHarness
            {
                {
                    initTransactionRequest,
                    MockResponse.Json(201, TransactionRestResponseHelper.GenerateInitTransactionResponse(1), "http://foo/db/data/transaction/1")
                },
                {
                    commitRequest, MockResponse.Json(200, @"{'results':[], 'errors':[] }")
                }
            })
            {
                var response = MockResponse.NeoRoot20();
                testHarness.Add(MockRequest.Get(""), response);
                var httpClient = testHarness.GenerateHttpClient("http://foo/db/data");
                testHarness.CreateAndConnectTransactionalGraphClient();
                ITransactionalGraphClient client = new GraphClient(new Uri("http://foo/db/data"), httpClient);
                client.Connect();
                using (var transaction = client.BeginTransaction())
                {
                    // dummy query to generate request
                    var rawClient = client as IRawGraphClient;
                    if (rawClient == null)
                    {
                        Assert.Fail("ITransactionalGraphClient is not IRawGraphClient");
                    }

                    var queries = new List <CypherQuery>()
                    {
                        client.Cypher
                        .Match("n")
                        .Return(n => n.Count())
                        .Query,
                        client.Cypher
                        .Match("t")
                        .Return(t => t.Count())
                        .Query
                    };
                    httpClient.ClearReceivedCalls();
                    rawClient.ExecuteMultipleCypherQueriesInTransaction(queries, customHeaders);
                    transaction.Commit();

                    var calls = httpClient.ReceivedCalls().ToList();
                    Assert.IsNotEmpty(calls);

                    HttpRequestMessage requestMessage = null;

                    foreach (var call in calls)
                    {
                        if (call.GetArguments().Single().GetType() == typeof(HttpRequestMessage))
                        {
                            requestMessage = (HttpRequestMessage)call.GetArguments().Single();
                        }
                    }

                    Assert.IsNotNull(requestMessage);

                    var customHeader = requestMessage.Headers.Single(h => h.Key == headerName);
                    Assert.IsNotNull(customHeader);
                    Assert.AreEqual(headerValue, customHeader.Value.Single());
                }
            }
        }