/* * Copyright (c) 2002-2017 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.neo4j.driver.v1.integration; import org.junit.Rule; import org.junit.Test; import java.util.List; import java.util.concurrent.TimeUnit; import org.neo4j.driver.v1.StatementResult; import org.neo4j.driver.v1.Value; import org.neo4j.driver.v1.Values; import org.neo4j.driver.v1.summary.Notification; import org.neo4j.driver.v1.summary.Plan; import org.neo4j.driver.v1.summary.ProfiledPlan; import org.neo4j.driver.v1.summary.ResultSummary; import org.neo4j.driver.v1.summary.StatementType; import org.neo4j.driver.v1.util.TestNeo4jSession; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.neo4j.driver.internal.util.ServerVersion.v3_1_0; import static org.neo4j.driver.internal.util.ServerVersion.version; public class SummaryIT { @Rule public TestNeo4jSession session = new TestNeo4jSession(); @Test public void shouldContainBasicMetadata() throws Throwable { // Given Value statementParameters = Values.parameters( "limit", 10 ); String statementText = "UNWIND [1, 2, 3, 4] AS n RETURN n AS number LIMIT {limit}"; // When StatementResult result = session.run( statementText, statementParameters ); // Then assertTrue( result.hasNext() ); // When ResultSummary summary = result.consume(); // Then assertFalse( result.hasNext() ); assertThat( summary.statementType(), equalTo( StatementType.READ_ONLY ) ); assertThat( summary.statement().text(), equalTo( statementText ) ); assertThat( summary.statement().parameters(), equalTo( statementParameters ) ); assertFalse( summary.hasPlan() ); assertFalse( summary.hasProfile() ); assertThat( summary, equalTo( result.consume() ) ); } @Test public void shouldContainTimeInformation() { // Given ResultSummary summary = session.run( "UNWIND range(1,1000) AS n RETURN n AS number" ).consume(); // Then if ( version( summary.server().version() ).greaterThanOrEqual( v3_1_0 ) ) { assertThat( summary.resultAvailableAfter( TimeUnit.MILLISECONDS ), greaterThan( 0L ) ); assertThat( summary.resultConsumedAfter( TimeUnit.MILLISECONDS ), greaterThan( 0L ) ); } else { //Not passed through by older versions of the server assertThat( summary.resultAvailableAfter( TimeUnit.MILLISECONDS ), equalTo( -1L ) ); assertThat( summary.resultConsumedAfter( TimeUnit.MILLISECONDS ), equalTo( -1L ) ); } } @Test public void shouldContainCorrectStatistics() throws Throwable { assertThat( session.run( "CREATE (n)" ).consume().counters().nodesCreated(), equalTo( 1 ) ); assertThat( session.run( "MATCH (n) DELETE (n)" ).consume().counters().nodesDeleted(), equalTo( 1 ) ); assertThat( session.run( "CREATE ()-[:KNOWS]->()" ).consume().counters().relationshipsCreated(), equalTo( 1 ) ); assertThat( session.run( "MATCH ()-[r:KNOWS]->() DELETE r" ).consume().counters().relationshipsDeleted(), equalTo( 1 ) ); assertThat( session.run( "CREATE (n:ALabel)" ).consume().counters().labelsAdded(), equalTo( 1 ) ); assertThat( session.run( "CREATE (n {magic: 42})" ).consume().counters().propertiesSet(), equalTo( 1 ) ); assertTrue( session.run( "CREATE (n {magic: 42})" ).consume().counters().containsUpdates() ); assertThat( session.run( "MATCH (n:ALabel) REMOVE n:ALabel " ).consume().counters().labelsRemoved(), equalTo( 1 ) ); assertThat( session.run( "CREATE INDEX ON :ALabel(prop)" ).consume().counters().indexesAdded(), equalTo( 1 ) ); assertThat( session.run( "DROP INDEX ON :ALabel(prop)" ).consume().counters().indexesRemoved(), equalTo( 1 ) ); assertThat( session.run( "CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE" ) .consume().counters().constraintsAdded(), equalTo( 1 ) ); assertThat( session.run( "DROP CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE" ) .consume().counters().constraintsRemoved(), equalTo( 1 ) ); } @Test public void shouldContainCorrectStatementType() throws Throwable { assertThat( session.run("MATCH (n) RETURN 1").consume().statementType(), equalTo( StatementType.READ_ONLY )); assertThat( session.run("CREATE (n)").consume().statementType(), equalTo( StatementType.WRITE_ONLY )); assertThat( session.run("CREATE (n) RETURN (n)").consume().statementType(), equalTo( StatementType.READ_WRITE )); assertThat( session.run("CREATE INDEX ON :User(p)").consume().statementType(), equalTo( StatementType.SCHEMA_WRITE )); } @Test public void shouldContainCorrectPlan() throws Throwable { // When Plan plan = session.run( "EXPLAIN MATCH (n) RETURN 1" ).consume().plan(); // Then assertThat( plan.operatorType(), notNullValue() ); assertThat( plan.arguments().size(), greaterThan( 0 ) ); assertThat( plan.children().size(), greaterThan( 0 ) ); } @Test public void shouldContainProfile() throws Throwable { // When ResultSummary summary = session.run( "PROFILE RETURN 1" ).consume(); // Then assertEquals( true, summary.hasProfile() ); assertEquals( true, summary.hasPlan() ); // Profile is a superset of plan, so plan should be available as well if profile is available assertEquals( summary.plan(), summary.profile() ); ProfiledPlan profile = summary.profile(); assertEquals( 0, profile.dbHits() ); assertEquals( 1, profile.records() ); } @Test public void shouldContainNotifications() throws Throwable { // When ResultSummary summary = session.run( "EXPLAIN MATCH (n), (m) RETURN n, m" ).consume(); // Then assertEquals( true, summary.hasPlan() ); List<Notification> notifications = summary.notifications(); assertNotNull( notifications ); assertThat( notifications.size(), equalTo( 1 ) ); assertThat( notifications.get( 0 ).toString(), containsString("CartesianProduct") ); } }