diff --git a/.travis.yml b/.travis.yml index 06d0df07..71e98750 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,12 @@ -sudo: false +sudo: required cache: directories: - $HOME/.m2 language: java -install: true +services: + - docker jdk: -- openjdk7 +#- openjdk7 - oraclejdk7 - oraclejdk8 os: @@ -13,12 +14,26 @@ os: env: matrix: - NEO_VERSION=2.0.5 + WITH_DOCKER=false - NEO_VERSION=2.1.8 + WITH_DOCKER=false - NEO_VERSION=2.2.9 + WITH_DOCKER=false EXTRA_PROFILES=-Pwith-neo4j-io - NEO_VERSION=2.3.3 + WITH_DOCKER=true EXTRA_PROFILES=-Pwith-neo4j-io -script: "mvn -T4 clean test -Dneo4j.version=${NEO_VERSION} ${EXTRA_PROFILES}" +before_script: +# Workaround for Travis CI buffer overflow with OpenJDK 7 +# Details: https://github.com/travis-ci/travis-ci/issues/5227#issuecomment-165131913 + - cat /etc/hosts + - echo "$(hostname | cut -c1-63)" + - sudo hostname "$(hostname | cut -c1-63)" + - sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts | sudo tee /etc/hosts + - cat /etc/hosts +# End of workaround +script: build/run.sh +install: true after_success: - mvn clean test jacoco:report coveralls:report - "[ ${TRAVIS_PULL_REQUEST} = 'false' ] && [ ${TRAVIS_BRANCH} = 'master' ] && mvn clean deploy -DskipTests --settings ./deploy-settings.xml" diff --git a/build/run.sh b/build/run.sh new file mode 100755 index 00000000..03d7db6b --- /dev/null +++ b/build/run.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -e +if [ "$WITH_DOCKER" = true ] ; then + docker pull neo4j:${NEO_VERSION} + docker run --detach --publish=7474:7474 --volume=$HOME/neo4j/data:/data --env=NEO4J_AUTH=neo4j/j4oen neo4j +fi +mvn -T4 clean test -Dneo4j.version=${NEO_VERSION} ${EXTRA_PROFILES} \ No newline at end of file diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/EmbeddedGraphDatabaseRule.java b/liquigraph-core/src/test/java/org/liquigraph/core/EmbeddedGraphDatabaseRule.java index 1868fb38..9b150796 100644 --- a/liquigraph-core/src/test/java/org/liquigraph/core/EmbeddedGraphDatabaseRule.java +++ b/liquigraph-core/src/test/java/org/liquigraph/core/EmbeddedGraphDatabaseRule.java @@ -15,6 +15,7 @@ */ package org.liquigraph.core; +import com.google.common.base.Optional; import org.junit.rules.ExternalResource; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.test.TestGraphDatabaseFactory; @@ -25,9 +26,11 @@ import java.util.Properties; import java.util.UUID; +import static com.google.common.base.Optional.absent; import static com.google.common.base.Throwables.propagate; -public class EmbeddedGraphDatabaseRule extends ExternalResource { +public class EmbeddedGraphDatabaseRule extends ExternalResource + implements GraphDatabaseRule { private final String dbName; private final String uri; @@ -38,15 +41,27 @@ public EmbeddedGraphDatabaseRule(String name) { dbName = name + "-" + UUID.randomUUID().toString(); uri = "jdbc:neo4j:instance:" + dbName; } - - public Connection jdbcConnection() { + + @Override + public Connection connection() { return connection; } + @Override public String uri() { return uri; } + @Override + public Optional username() { + return absent(); + } + + @Override + public Optional password() { + return absent(); + } + protected void before() { try { db = new TestGraphDatabaseFactory().newImpermanentDatabase(); diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/GraphDatabaseRule.java b/liquigraph-core/src/test/java/org/liquigraph/core/GraphDatabaseRule.java new file mode 100644 index 00000000..aa82982f --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/GraphDatabaseRule.java @@ -0,0 +1,29 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core; + +import com.google.common.base.Optional; +import org.junit.rules.TestRule; + +import java.sql.Connection; + +public interface GraphDatabaseRule extends TestRule { + + Connection connection(); + String uri(); + Optional username(); + Optional password(); +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/GraphIntegrationTestSuite.java b/liquigraph-core/src/test/java/org/liquigraph/core/GraphIntegrationTestSuite.java new file mode 100644 index 00000000..24db3955 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/GraphIntegrationTestSuite.java @@ -0,0 +1,21 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core; + +public interface GraphIntegrationTestSuite { + + GraphDatabaseRule graphDatabase(); +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/RemoteGraphDatabaseRule.java b/liquigraph-core/src/test/java/org/liquigraph/core/RemoteGraphDatabaseRule.java new file mode 100644 index 00000000..35feed68 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/RemoteGraphDatabaseRule.java @@ -0,0 +1,105 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core; + +import com.google.common.base.Optional; +import org.junit.Assume; +import org.junit.rules.ExternalResource; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import static com.google.common.base.Throwables.propagate; +import static org.assertj.core.api.Assertions.assertThat; + +public class RemoteGraphDatabaseRule extends ExternalResource + implements GraphDatabaseRule { + + private final String uri; + private final String username; + private final String password; + private Connection connection; + + public RemoteGraphDatabaseRule() { + uri = "jdbc:neo4j://127.0.0.1:7474"; + username = "neo4j"; + password = "j4oen"; + } + + public static void assumeRemoteGraphDatabaseIsProvisioned() { + Assume.assumeTrue( + "Neo4j remote instance is provisioned with Docker", + "true".equals(System.getenv("WITH_DOCKER")) + ); + } + + @Override + public Statement apply(Statement base, Description description) { + assumeRemoteGraphDatabaseIsProvisioned(); + return super.apply(base, description); + } + + @Override + public Connection connection() { + return connection; + } + + @Override + public String uri() { + return uri; + } + + @Override + public Optional username() { + return Optional.of(username); + } + + @Override + public Optional password() { + return Optional.of(password); + } + + protected void before() { + try { + Class.forName("org.neo4j.jdbc.Driver"); + connection = DriverManager.getConnection(uri, username, password); + connection.setAutoCommit(false); + emptyDatabase(connection); + } catch (ClassNotFoundException | SQLException e) { + throw propagate(e); + } + } + + protected void after() { + try { + if (!connection.isClosed()) { + connection.close(); + } + } catch (SQLException e) { + throw propagate(e); + } + } + + private void emptyDatabase(Connection connection) throws SQLException { + try (java.sql.Statement statement = connection.createStatement()) { + assertThat(statement.execute("MATCH (n) OPTIONAL MATCH (n)-[r]->() DELETE n,r")).isTrue(); + } + } + +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphEmbeddedTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphEmbeddedTest.java new file mode 100644 index 00000000..f5647870 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphEmbeddedTest.java @@ -0,0 +1,31 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core.api; + +import org.junit.Rule; +import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphDatabaseRule; + +public class LiquigraphEmbeddedTest extends LiquigraphTestSuite { + + @Rule + public GraphDatabaseRule graph = new EmbeddedGraphDatabaseRule("neo"); + + @Override + public GraphDatabaseRule graphDatabase() { + return graph; + } +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphRemoteTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphRemoteTest.java new file mode 100644 index 00000000..f82c0d20 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphRemoteTest.java @@ -0,0 +1,31 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core.api; + +import org.junit.Rule; +import org.liquigraph.core.GraphDatabaseRule; +import org.liquigraph.core.RemoteGraphDatabaseRule; + +public class LiquigraphRemoteTest extends LiquigraphTestSuite { + + @Rule + public GraphDatabaseRule graph = new RemoteGraphDatabaseRule(); + + @Override + public GraphDatabaseRule graphDatabase() { + return graph; + } +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphTestSuite.java similarity index 69% rename from liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphTest.java rename to liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphTestSuite.java index 74a9bf4a..c0d0bf54 100644 --- a/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphTest.java +++ b/liquigraph-core/src/test/java/org/liquigraph/core/api/LiquigraphTestSuite.java @@ -15,11 +15,9 @@ */ package org.liquigraph.core.api; -import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphIntegrationTestSuite; import org.liquigraph.core.configuration.ConfigurationBuilder; import org.liquigraph.core.io.FixedConnectionConnector; @@ -31,16 +29,15 @@ import static org.assertj.core.api.Assertions.assertThat; -public class LiquigraphTest { +abstract class LiquigraphTestSuite implements GraphIntegrationTestSuite { - @Rule public EmbeddedGraphDatabaseRule graph = new EmbeddedGraphDatabaseRule("neo"); private Liquigraph liquigraph; @Before public void prepare() { liquigraph = new Liquigraph( - // bypasses the configured URI - new FixedConnectionConnector(graph.jdbcConnection()) + // bypasses the configured URI + new FixedConnectionConnector(graphDatabase().connection()) ); } @@ -50,14 +47,16 @@ public void runs_migrations_against_embedded_graph_with_failed_precondition_whos new ConfigurationBuilder() .withRunMode() .withMasterChangelogLocation("changelog/changelog-with-1-node.xml") - .withUri(graph.uri()) + .withUri(graphDatabase().uri()) + .withUsername(graphDatabase().username().orNull()) + .withPassword(graphDatabase().password().orNull()) .build() ); - try (Connection connection = graph.jdbcConnection()) { + try (Connection connection = graphDatabase().connection()) { try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery( - "MATCH (human:Human {name: 'fbiville'}) RETURN human" + "MATCH (human:Human {name: 'fbiville'}) RETURN human" )) { assertThat(resultSet.next()).isTrue(); @@ -66,7 +65,7 @@ public void runs_migrations_against_embedded_graph_with_failed_precondition_whos } try (PreparedStatement statement = connection.prepareStatement( - "MATCH (changeset:__LiquigraphChangeset {id: {1}}) RETURN changeset" + "MATCH (changeset:__LiquigraphChangeset {id: {1}}) RETURN changeset" )) { statement.setObject(1, "insert-fbiville"); @@ -86,14 +85,16 @@ public void runs_migrations_against_embedded_graph_with_failed_precondition_whos @Test public void runs_migrations_with_schema_changes() throws SQLException { liquigraph.runMigrations( - new ConfigurationBuilder() - .withRunMode() - .withMasterChangelogLocation("schema/schema-changelog.xml") - .withUri(graph.uri()) - .build() + new ConfigurationBuilder() + .withRunMode() + .withMasterChangelogLocation("schema/schema-changelog.xml") + .withUri(graphDatabase().uri()) + .withUsername(graphDatabase().username().orNull()) + .withPassword(graphDatabase().password().orNull()) + .build() ); - try (Connection connection = graph.jdbcConnection(); + try (Connection connection = graphDatabase().connection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("MATCH (foo:Foo {bar: 123}) RETURN foo")) { @@ -106,14 +107,14 @@ public void runs_migrations_with_schema_changes() throws SQLException { @Test public void runs_migrations_with_schema_changes_and_preconditions() throws SQLException { liquigraph.runMigrations( - new ConfigurationBuilder() - .withRunMode() - .withMasterChangelogLocation("schema/schema-preconditions-changelog.xml") - .withUri(graph.uri()) - .build() + new ConfigurationBuilder() + .withRunMode() + .withMasterChangelogLocation("schema/schema-preconditions-changelog.xml") + .withUri(graphDatabase().uri()) + .build() ); - try (Connection connection = graph.jdbcConnection(); + try (Connection connection = graphDatabase().connection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("MATCH (foo:Foo {bar: 123}) RETURN foo")) { @@ -122,5 +123,4 @@ public void runs_migrations_with_schema_changes_and_preconditions() throws SQLEx connection.commit(); } } - } \ No newline at end of file diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderEmbeddedTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderEmbeddedTest.java new file mode 100644 index 00000000..bd67e250 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderEmbeddedTest.java @@ -0,0 +1,31 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core.io; + +import org.junit.Rule; +import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphDatabaseRule; + +public class ChangelogGraphReaderEmbeddedTest extends ChangelogGraphReaderTestSuite { + + @Rule + public GraphDatabaseRule graph = new EmbeddedGraphDatabaseRule("neotestreader"); + + @Override + public GraphDatabaseRule graphDatabase() { + return graph; + } +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderRemoteTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderRemoteTest.java new file mode 100644 index 00000000..5f1a08f8 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderRemoteTest.java @@ -0,0 +1,31 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core.io; + +import org.junit.Rule; +import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphDatabaseRule; +import org.liquigraph.core.RemoteGraphDatabaseRule; + +public class ChangelogGraphReaderRemoteTest extends ChangelogGraphReaderTestSuite { + + @Rule public GraphDatabaseRule graph = new RemoteGraphDatabaseRule(); + + @Override + public GraphDatabaseRule graphDatabase() { + return graph; + } +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderTestSuite.java similarity index 91% rename from liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderTest.java rename to liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderTestSuite.java index 6df246a7..0ddfdc6f 100644 --- a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderTest.java +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphReaderTestSuite.java @@ -15,9 +15,8 @@ */ package org.liquigraph.core.io; -import org.junit.Rule; import org.junit.Test; -import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphIntegrationTestSuite; import org.liquigraph.core.model.Changeset; import java.sql.Connection; @@ -30,14 +29,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.liquigraph.core.model.Checksums.checksum; -public class ChangelogGraphReaderTest { +abstract class ChangelogGraphReaderTestSuite implements GraphIntegrationTestSuite { - @Rule public EmbeddedGraphDatabaseRule graph = new EmbeddedGraphDatabaseRule("neotest"); private ChangelogGraphReader reader = new ChangelogGraphReader(); @Test public void reads_changelog_from_graph_database() throws SQLException { - try (Connection connection = graph.jdbcConnection()) { + try (Connection connection = graphDatabase().connection()) { String query = "MATCH n RETURN n"; given_inserted_data(format( "CREATE (:__LiquigraphChangelog)<-[:EXECUTED_WITHIN_CHANGELOG {time:1}]-" + @@ -50,7 +48,7 @@ public void reads_changelog_from_graph_database() throws SQLException { connection ); - Collection changesets = reader.read(graph.jdbcConnection()); + Collection changesets = reader.read(graphDatabase().connection()); assertThat(changesets).hasSize(1); Changeset changeset = changesets.iterator().next(); @@ -64,7 +62,7 @@ public void reads_changelog_from_graph_database() throws SQLException { @Test public void reads_changeset_with_multiple_queries() throws SQLException { - try (Connection connection = graph.jdbcConnection()) { + try (Connection connection = graphDatabase().connection()) { given_inserted_data(format( "CREATE (:__LiquigraphChangelog)<-[:EXECUTED_WITHIN_CHANGELOG {time:1}]-" + " (changeset:__LiquigraphChangeset {" + @@ -82,7 +80,7 @@ public void reads_changeset_with_multiple_queries() throws SQLException { connection ); - Collection changesets = reader.read(graph.jdbcConnection()); + Collection changesets = reader.read(graphDatabase().connection()); assertThat(changesets).hasSize(1); Changeset changeset = changesets.iterator().next(); diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterEmbeddedTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterEmbeddedTest.java new file mode 100644 index 00000000..e87d50a7 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterEmbeddedTest.java @@ -0,0 +1,31 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core.io; + +import org.junit.Rule; +import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphDatabaseRule; + +public class ChangelogGraphWriterEmbeddedTest extends ChangelogGraphWriterTestSuite { + + @Rule + public GraphDatabaseRule graph = new EmbeddedGraphDatabaseRule("neotestwriter"); + + @Override + public GraphDatabaseRule graphDatabase() { + return graph; + } +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterRemoteTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterRemoteTest.java new file mode 100644 index 00000000..61084340 --- /dev/null +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterRemoteTest.java @@ -0,0 +1,32 @@ +/** + * Copyright 2014-2016 the original author or authors. + * + * 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.liquigraph.core.io; + +import org.junit.Rule; +import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphDatabaseRule; +import org.liquigraph.core.RemoteGraphDatabaseRule; + +public class ChangelogGraphWriterRemoteTest extends ChangelogGraphWriterTestSuite { + + @Rule + public GraphDatabaseRule graph = new RemoteGraphDatabaseRule(); + + @Override + public GraphDatabaseRule graphDatabase() { + return graph; + } +} diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterTestSuite.java similarity index 78% rename from liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterTest.java rename to liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterTestSuite.java index d050fa67..103e58a4 100644 --- a/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterTest.java +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/ChangelogGraphWriterTestSuite.java @@ -16,10 +16,8 @@ package org.liquigraph.core.io; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.liquigraph.core.EmbeddedGraphDatabaseRule; +import org.liquigraph.core.GraphIntegrationTestSuite; import org.liquigraph.core.exception.PreconditionNotMetException; import org.liquigraph.core.model.Changeset; import org.liquigraph.core.model.Precondition; @@ -33,29 +31,29 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.Collection; +import java.util.Map; import static com.google.common.collect.Lists.newArrayList; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.liquigraph.core.model.Checksums.checksum; -public class ChangelogGraphWriterTest { +abstract class ChangelogGraphWriterTestSuite implements GraphIntegrationTestSuite { - @Rule public EmbeddedGraphDatabaseRule graph = new EmbeddedGraphDatabaseRule("neotest"); - @Rule public ExpectedException thrown = ExpectedException.none(); private ChangelogGraphWriter writer; @Before public void prepare() throws SQLException { - writer = new ChangelogGraphWriter(graph.jdbcConnection(), new PreconditionExecutor()); + writer = new ChangelogGraphWriter(graphDatabase().connection(), new PreconditionExecutor()); } @Test public void persists_changesets_in_graph() throws SQLException { writer.write(newArrayList(changeset("identifier", "fbiville", "CREATE (n: SomeNode {text:'yeah'})"))); - assertThatQueryIsExecutedAndHistoryPersisted(graph.jdbcConnection()); + assertThatQueryIsExecutedAndHistoryPersisted(graphDatabase().connection()); } @Test @@ -65,18 +63,23 @@ public void persists_changesets_in_graph_when_preconditions_are_met() throws SQL writer.write(newArrayList(changeset)); - assertThatQueryIsExecutedAndHistoryPersisted(graph.jdbcConnection()); + assertThatQueryIsExecutedAndHistoryPersisted(graphDatabase().connection()); } @Test public void fails_when_precondition_is_not_met_and_configured_to_halt_execution() { - thrown.expect(PreconditionNotMetException.class); - thrown.expectMessage("Changeset : precondition query failed with policy . Aborting."); + try { + Precondition precondition = precondition(PreconditionErrorPolicy.FAIL, "RETURN false AS result"); + Changeset changeset = changeset("identifier", "fbiville", "CREATE (n: SomeNode {text:'yeah'})", precondition); - Precondition precondition = precondition(PreconditionErrorPolicy.FAIL, "RETURN false AS result"); - Changeset changeset = changeset("identifier", "fbiville", "CREATE (n: SomeNode {text:'yeah'})", precondition); + writer.write(newArrayList(changeset)); + failBecauseExceptionWasNotThrown(PreconditionNotMetException.class); + } + catch (PreconditionNotMetException pnme) { + assertThat(pnme) + .hasMessage("Changeset : precondition query failed with policy . Aborting."); + } - writer.write(newArrayList(changeset)); } @Test @@ -86,7 +89,7 @@ public void skips_changeset_execution_when_precondition_is_not_met_and_configure writer.write(newArrayList(changeset)); - try (Statement statement = graph.jdbcConnection().createStatement(); + try (Statement statement = graphDatabase().connection().createStatement(); ResultSet resultSet = statement.executeQuery( "MATCH (changelog:__LiquigraphChangelog)<-[execution:EXECUTED_WITHIN_CHANGELOG]-(changeset:__LiquigraphChangeset) " + "OPTIONAL MATCH (node :SomeNode) " + @@ -104,7 +107,7 @@ public void persists_changeset_but_does_execute_it_when_precondition_is_not_met_ writer.write(singletonList(changeset)); - try (Statement statement = graph.jdbcConnection().createStatement(); + try (Statement statement = graphDatabase().connection().createStatement(); ResultSet resultSet = statement.executeQuery( "OPTIONAL MATCH (node: SomeNode) " + "WITH node " + @@ -132,7 +135,7 @@ public void executes_changeset_with_multiple_queries() throws SQLException { writer.write(singletonList(changeset)); - try (Statement transaction = graph.jdbcConnection().createStatement(); + try (Statement transaction = graphDatabase().connection().createStatement(); ResultSet resultSet = transaction.executeQuery("MATCH (n:Human) RETURN n.age AS age")) { assertThat(resultSet.next()).isTrue(); @@ -140,7 +143,7 @@ public void executes_changeset_with_multiple_queries() throws SQLException { assertThat(resultSet.next()).as("No more result in result set").isFalse(); } - try (Statement transaction = graph.jdbcConnection().createStatement(); + try (Statement transaction = graphDatabase().connection().createStatement(); ResultSet resultSet = transaction.executeQuery("MATCH (queries:__LiquigraphQuery) RETURN COLLECT(queries.query) AS query")) { assertThat(resultSet.next()).isTrue(); @@ -163,14 +166,16 @@ public void persists_run_always_changesets_in_graph_only_once() throws SQLExcept writer.write(newArrayList(changeset)); } - try (Statement transaction = graph.jdbcConnection().createStatement(); + try (Statement transaction = graphDatabase().connection().createStatement(); ResultSet changesetSet = transaction.executeQuery("MATCH (changeset:__LiquigraphChangeset) RETURN changeset"); ResultSet propSet = transaction.executeQuery("MATCH (n:SomeNode) RETURN n.prop AS prop")) { + assertThat(changesetSet.next()).isTrue(); - Node changesetNode = (Node) changesetSet.getObject("changeset"); - assertThat(changesetNode.getProperty("id")).isEqualTo("identifier"); - assertThat(changesetNode.getProperty("author")).isEqualTo("fbiville"); - assertThat(changesetNode.getProperty("checksum")) + + Object changesetNode = changesetSet.getObject("changeset"); + assertThat(property(changesetNode, "id")).isEqualTo("identifier"); + assertThat(property(changesetNode, "author")).isEqualTo("fbiville"); + assertThat(property(changesetNode, "checksum")) .isEqualTo(checksum(singletonList( "MERGE (n:SomeNode) " + "ON CREATE SET n.prop = 1 " + @@ -185,10 +190,11 @@ public void persists_run_always_changesets_in_graph_only_once() throws SQLExcept @Test public void persists_run_on_change_changesets_in_graph_only_once() throws SQLException { - Changeset changeset = changeset("identifier", "fbiville", - "CREATE (n:SomeNode {prop: 1})"); + Changeset changeset = changeset("identifier", "fbiville", "CREATE (n:SomeNode {prop: 1})"); changeset.setRunOnChange(true); + writer.write(newArrayList(changeset)); + changeset = changeset(changeset.getId(), changeset.getAuthor(), "MERGE (n:SomeNode) " + "ON CREATE SET n.prop = 1 " + @@ -197,14 +203,16 @@ public void persists_run_on_change_changesets_in_graph_only_once() throws SQLExc writer.write(newArrayList(changeset)); - try (Statement transaction = graph.jdbcConnection().createStatement(); + try (Statement transaction = graphDatabase().connection().createStatement(); ResultSet changesetSet = transaction.executeQuery("MATCH (changeset:__LiquigraphChangeset) RETURN changeset"); ResultSet propSet = transaction.executeQuery("MATCH (n:SomeNode) RETURN n.prop AS prop")) { + assertThat(changesetSet.next()).isTrue(); - Node changesetNode = (Node) changesetSet.getObject("changeset"); - assertThat(changesetNode.getProperty("id")).isEqualTo("identifier"); - assertThat(changesetNode.getProperty("author")).isEqualTo("fbiville"); - assertThat(changesetNode.getProperty("checksum")) + + Object changesetNode = changesetSet.getObject("changeset"); + assertThat(property(changesetNode, "id")).isEqualTo("identifier"); + assertThat(property(changesetNode, "author")).isEqualTo("fbiville"); + assertThat(property(changesetNode, "checksum")) .isEqualTo(checksum(singletonList( "MERGE (n:SomeNode) " + "ON CREATE SET n.prop = 1 " + @@ -267,19 +275,26 @@ private static void assertThatChangesetIsStored(ResultSet resultSet) throws SQLE assertThat((Collection) resultSet.getObject("queries")) .containsExactly("CREATE (n: SomeNode {text:'yeah'})"); - Node changeset = (Node) resultSet.getObject("changeset"); - assertThat(changeset.getProperty("id")).isEqualTo("identifier"); - assertThat(changeset.getProperty("author")).isEqualTo("fbiville"); - assertThat(changeset.getProperty("checksum")).isEqualTo(checksum(singletonList("CREATE (n: SomeNode {text:'yeah'})"))); + Object changeset = resultSet.getObject("changeset"); + assertThat(property(changeset, "id")).isEqualTo("identifier"); + assertThat(property(changeset, "author")).isEqualTo("fbiville"); + assertThat(property(changeset, "checksum")).isEqualTo(checksum(singletonList("CREATE (n: SomeNode {text:'yeah'})"))); } private static void assertThatQueryIsExecuted(ResultSet resultSet) throws SQLException { - Node node = (Node) resultSet.getObject("node"); - assertThat(node.getLabels()).containsExactly(DynamicLabel.label("SomeNode")); - assertThat(node.getProperty("text")).isEqualTo("yeah"); + Object node = resultSet.getObject("node"); + assertThat(property(node, "text")).isEqualTo("yeah"); } private static void assertThatQueryIsNotExecuted(ResultSet resultSet) throws SQLException { assertThat(resultSet.getObject("node")).isNull(); } + + private static Object property(Object changeset, String name) { + if (changeset instanceof Map) { + return ((Map) changeset).get(name); + } + assertThat(changeset).isInstanceOf(Node.class); + return ((Node)changeset).getProperty(name); + } } diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/GraphJdbcConnectorTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/GraphJdbcConnectorTest.java index 87db11f7..f953904e 100644 --- a/liquigraph-core/src/test/java/org/liquigraph/core/io/GraphJdbcConnectorTest.java +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/GraphJdbcConnectorTest.java @@ -15,7 +15,6 @@ */ package org.liquigraph.core.io; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -28,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.data.MapEntry.entry; +import static org.liquigraph.core.RemoteGraphDatabaseRule.assumeRemoteGraphDatabaseIsProvisioned; public class GraphJdbcConnectorTest { @@ -50,21 +50,18 @@ public void instantiates_a_local_graph_database() throws SQLException { } @Test - @Ignore("requires starting local Neo4j instance") public void instantiates_a_remote_graph_database() throws SQLException { + assumeRemoteGraphDatabaseIsProvisioned(); + try (Connection connection = connector.connect(new ConfigurationBuilder() .withRunMode() - .withMasterChangelogLocation("changelog.xml") - .withUri("jdbc:neo4j://localhost:7474") + .withMasterChangelogLocation("changelog/changelog.xml") + .withUri("jdbc:neo4j://127.0.0.1:7474") .withUsername("neo4j") - .withPassword("toto") + .withPassword("j4oen") .build() )) { - - assertThat(((Neo4jConnection) connection).getProperties()).contains( - entry("user", "neo4j"), - entry("password", "toto") - ); + assertThat(connection).isInstanceOf(LockableConnection.class); } } diff --git a/liquigraph-core/src/test/java/org/liquigraph/core/io/PreconditionExecutorTest.java b/liquigraph-core/src/test/java/org/liquigraph/core/io/PreconditionExecutorTest.java index 7e9bcf5a..2f9a179b 100644 --- a/liquigraph-core/src/test/java/org/liquigraph/core/io/PreconditionExecutorTest.java +++ b/liquigraph-core/src/test/java/org/liquigraph/core/io/PreconditionExecutorTest.java @@ -48,7 +48,7 @@ public class PreconditionExecutorTest { @Test public void executes_simple_precondition() throws SQLException { - Connection connection = graphDatabaseRule.jdbcConnection(); + Connection connection = graphDatabaseRule.connection(); try (Statement ignored = connection.createStatement()) { PreconditionResult result = executor.executePrecondition( connection, @@ -62,7 +62,7 @@ public void executes_simple_precondition() throws SQLException { @Test public void executes_nested_and_precondition_queries() throws SQLException { - Connection connection = graphDatabaseRule.jdbcConnection(); + Connection connection = graphDatabaseRule.connection(); try (Statement ignored = connection.createStatement()) { PreconditionResult result = executor.executePrecondition( connection, @@ -76,7 +76,7 @@ public void executes_nested_and_precondition_queries() throws SQLException { @Test public void executes_nested_or_precondition_queries() throws SQLException { - Connection connection = graphDatabaseRule.jdbcConnection(); + Connection connection = graphDatabaseRule.connection(); try (Statement ignored = connection.createStatement()) { PreconditionResult result = executor.executePrecondition( connection, @@ -98,7 +98,7 @@ public void executes_nested_mixed_precondition_queries_like_a_charm() throws SQL )); precondition.setQuery(andQuery); - Connection connection = graphDatabaseRule.jdbcConnection(); + Connection connection = graphDatabaseRule.connection(); try (Statement ignored = connection.createStatement()) { PreconditionResult result = executor.executePrecondition( connection, @@ -119,7 +119,7 @@ public void fails_with_invalid_cypher_query() throws SQLException { "\tActual cause: Error executing query toto\n" + " with params {}"); - Connection connection = graphDatabaseRule.jdbcConnection(); + Connection connection = graphDatabaseRule.connection(); try (Statement ignored = connection.createStatement()) { executor.executePrecondition( connection, @@ -133,7 +133,7 @@ public void fails_with_badly_named_precondition_result_column() throws SQLExcept thrown.expect(PreconditionExecutionException.class); thrown.expectMessage("Make sure your query yields exactly one column named or aliased 'result'."); - Connection connection = graphDatabaseRule.jdbcConnection(); + Connection connection = graphDatabaseRule.connection(); try (Statement ignored = connection.createStatement()) { executor.executePrecondition( connection, @@ -149,7 +149,7 @@ public void fails_with_unknown_query_type() { Precondition precondition = new Precondition(); precondition.setQuery(new PreconditionQuery() {}); - executor.executePrecondition(graphDatabaseRule.jdbcConnection(), precondition); + executor.executePrecondition(graphDatabaseRule.connection(), precondition); } private Precondition simplePrecondition(PreconditionErrorPolicy fail, String query) {