diff --git a/plugins/nf-sqldb/build.gradle b/plugins/nf-sqldb/build.gradle index c88f6fa..ecf109e 100644 --- a/plugins/nf-sqldb/build.gradle +++ b/plugins/nf-sqldb/build.gradle @@ -84,6 +84,10 @@ dependencies { testImplementation(testFixtures("io.nextflow:nextflow:$nextflowVersion")) testImplementation(testFixtures("io.nextflow:nf-commons:$nextflowVersion")) + + testImplementation("org.testcontainers:testcontainers") + testImplementation("org.testcontainers:mysql:1.17.4") + testImplementation("org.testcontainers:postgresql:1.17.4") } test { diff --git a/plugins/nf-sqldb/src/test/nextflow/sql/H2SqlDslTest.groovy b/plugins/nf-sqldb/src/test/nextflow/sql/H2SqlDslTest.groovy new file mode 100644 index 0000000..9dc2c12 --- /dev/null +++ b/plugins/nf-sqldb/src/test/nextflow/sql/H2SqlDslTest.groovy @@ -0,0 +1,53 @@ +/* + * Copyright 2020-2022, Seqera Labs + * + * 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 nextflow.sql + +import groovy.sql.Sql +import nextflow.Channel +import nextflow.plugin.Plugins +import nextflow.plugin.TestPluginDescriptorFinder +import nextflow.plugin.TestPluginManager +import nextflow.plugin.extension.PluginExtensionProvider +import org.pf4j.PluginDescriptorFinder +import spock.lang.Shared +import spock.lang.Timeout +import test.Dsl2Spec +import test.MockScriptRunner + +import java.nio.file.Path + +/** + * + * @author Paolo Di Tommaso + */ +@Timeout(10) +class H2SqlDslTest extends SqlDslTest { + + String getJdbcURL(){ + 'jdbc:h2:mem:test_' + Random.newInstance().nextInt(1_000_000) + } + + String getUsername(){ + 'sa' + } + + String getPasword(){ + null + } + +} diff --git a/plugins/nf-sqldb/src/test/nextflow/sql/MySqlDslTest.groovy b/plugins/nf-sqldb/src/test/nextflow/sql/MySqlDslTest.groovy new file mode 100644 index 0000000..303aca2 --- /dev/null +++ b/plugins/nf-sqldb/src/test/nextflow/sql/MySqlDslTest.groovy @@ -0,0 +1,67 @@ +/* + * Copyright 2020-2022, Seqera Labs + * + * 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 nextflow.sql + +import groovy.sql.Sql +import nextflow.Channel +import nextflow.plugin.Plugins +import nextflow.plugin.TestPluginDescriptorFinder +import nextflow.plugin.TestPluginManager +import nextflow.plugin.extension.PluginExtensionProvider +import org.pf4j.PluginDescriptorFinder +import org.testcontainers.containers.MySQLContainer +import spock.lang.Shared +import spock.lang.Timeout +import test.Dsl2Spec +import test.MockScriptRunner + +import java.nio.file.Path + +/** + * + * @author Paolo Di Tommaso + */ +@Timeout(10) +class MySqlDslTest extends SqlDslTest { + + @Shared MySQLContainer db = new MySQLContainer(MySQLContainer.DEFAULT_IMAGE_NAME.withTag("latest")) + .withDatabaseName("test") + .withUsername("user1") + .withPassword("password1") + + def setupSpec(){ + db.start() + } + + def cleanSpec(){ + db.stop() + } + + String getJdbcURL(){ + db.jdbcUrl + } + + String getUsername(){ + db.username + } + + String getPasword(){ + db.password + } + +} diff --git a/plugins/nf-sqldb/src/test/nextflow/sql/PostgresSqlDslTest.groovy b/plugins/nf-sqldb/src/test/nextflow/sql/PostgresSqlDslTest.groovy new file mode 100644 index 0000000..008e0d5 --- /dev/null +++ b/plugins/nf-sqldb/src/test/nextflow/sql/PostgresSqlDslTest.groovy @@ -0,0 +1,58 @@ +/* + * Copyright 2020-2022, Seqera Labs + * + * 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 nextflow.sql + + +import org.testcontainers.containers.MySQLContainer +import org.testcontainers.containers.PostgreSQLContainer +import spock.lang.Shared +import spock.lang.Timeout + +/** + * + * @author Paolo Di Tommaso + */ +@Timeout(10) +class PostgresSqlDslTest extends SqlDslTest { + + @Shared PostgreSQLContainer db = new PostgreSQLContainer(PostgreSQLContainer.DEFAULT_IMAGE_NAME) + .withDatabaseName("test") + .withUsername("user1") + .withPassword("password1") + + def setupSpec(){ + db.start() + } + + def cleanSpec(){ + db.stop() + } + + String getJdbcURL(){ + db.jdbcUrl + } + + String getUsername(){ + db.username + } + + String getPasword(){ + db.password + } + +} diff --git a/plugins/nf-sqldb/src/test/nextflow/sql/SqlDslTest.groovy b/plugins/nf-sqldb/src/test/nextflow/sql/SqlDslTest.groovy index f67f814..fc41b0c 100644 --- a/plugins/nf-sqldb/src/test/nextflow/sql/SqlDslTest.groovy +++ b/plugins/nf-sqldb/src/test/nextflow/sql/SqlDslTest.groovy @@ -35,11 +35,20 @@ import java.nio.file.Path * * @author Paolo Di Tommaso */ -@Timeout(10) -class SqlDslTest extends Dsl2Spec { +abstract class SqlDslTest extends Dsl2Spec { @Shared String pluginsMode + abstract String getJdbcURL() + + abstract String getUsername() + + abstract String getPasword() + + Map getConfiguration(String jdbc){ + [sql: [db: [ds1: [url: jdbc, user: username, password: pasword]]]] + } + def setup() { // reset previous instances PluginExtensionProvider.reset() @@ -69,41 +78,45 @@ class SqlDslTest extends Dsl2Spec { } def 'should perform a query and create a channel' () { given: - def JDBC_URL = 'jdbc:h2:mem:test_' + Random.newInstance().nextInt(1_000_000) - def sql = Sql.newInstance(JDBC_URL, 'sa', null) + def JDBC_URL = getJdbcURL() + def sql = Sql.newInstance(JDBC_URL, getUsername(), getPasword()) and: sql.execute('create table FOO(id int primary key, alpha varchar(255), omega int);') sql.execute("insert into FOO (id, alpha, omega) values (1, 'hola', 10) ") sql.execute("insert into FOO (id, alpha, omega) values (2, 'ciao', 20) ") sql.execute("insert into FOO (id, alpha, omega) values (3, 'hello', 30) ") and: - def config = [sql: [db: [test: [url: JDBC_URL]]]] + def config = getConfiguration(JDBC_URL) when: def SCRIPT = ''' include { fromQuery; sqlInsert } from 'plugin/nf-sqldb' def table = 'FOO' def sql = "select * from $table" - channel.fromQuery(sql, db: "test") + channel.fromQuery(sql, db: "ds1") ''' and: def result = new MockScriptRunner(config).setScript(SCRIPT).execute() + then: result.val == [1, 'hola', 10] result.val == [2, 'ciao', 20] result.val == [3, 'hello', 30] result.val == Channel.STOP + + cleanup: + sql.execute("drop table FOO") } def 'should insert channel data into a db table' () { given: - def JDBC_URL = 'jdbc:h2:mem:test_' + Random.newInstance().nextInt(1_000_000) - def sql = Sql.newInstance(JDBC_URL, 'sa', null) + def JDBC_URL = getJdbcURL() + def sql = Sql.newInstance(JDBC_URL, getUsername(), getPasword()) and: sql.execute('create table FOO(id int primary key, alpha varchar(255), omega int);') and: - def config = [sql: [db: [ds1: [url: JDBC_URL]]]] + def config= getConfiguration(JDBC_URL) when: def SCRIPT = ''' @@ -125,16 +138,18 @@ class SqlDslTest extends Dsl2Spec { rows.size() == 3 rows.id == [100, 200, 300] + cleanup: + sql.execute("drop table FOO") } def 'should insert channel data into a db table in batches' () { given: - def JDBC_URL = 'jdbc:h2:mem:test_' + Random.newInstance().nextInt(1_000_000) - def sql = Sql.newInstance(JDBC_URL, 'sa', null) + def JDBC_URL = getJdbcURL() + def sql = Sql.newInstance(JDBC_URL, getUsername(), getPasword()) and: sql.execute('create table FOO(id int primary key, alpha varchar(255), omega int);') and: - def config = [sql: [db: [ds1: [url: JDBC_URL]]]] + def config = getConfiguration(JDBC_URL) when: def SCRIPT = ''' @@ -158,34 +173,40 @@ class SqlDslTest extends Dsl2Spec { rows.size() == 5 rows.id == [100, 200, 300, 400, 500] + cleanup: + sql.execute("drop table FOO") } def 'should perform a query with headers and create a channel' () { given: - def JDBC_URL = 'jdbc:h2:mem:test_' + Random.newInstance().nextInt(1_000_000) - def sql = Sql.newInstance(JDBC_URL, 'sa', null) + def JDBC_URL = getJdbcURL() + def sql = Sql.newInstance(JDBC_URL, getUsername(), getPasword()) and: sql.execute('create table FOO(id int primary key, alpha varchar(255), omega int);') sql.execute("insert into FOO (id, alpha, omega) values (1, 'hola', 10) ") sql.execute("insert into FOO (id, alpha, omega) values (2, 'ciao', 20) ") sql.execute("insert into FOO (id, alpha, omega) values (3, 'hello', 30) ") and: - def config = [sql: [db: [test: [url: JDBC_URL]]]] + def config = getConfiguration(JDBC_URL) when: def SCRIPT = ''' include { fromQuery; sqlInsert } from 'plugin/nf-sqldb' def table = 'FOO' def sql = "select * from $table" - channel.fromQuery(sql, db: "test", emitColumns:true) + channel.fromQuery(sql, db: "ds1", emitColumns:true) ''' and: def result = new MockScriptRunner(config).setScript(SCRIPT).execute() + then: - result.val == ['ID', 'ALPHA', 'OMEGA'] + result.val*.toUpperCase() == ['ID', 'ALPHA', 'OMEGA'] result.val == [1, 'hola', 10] result.val == [2, 'ciao', 20] result.val == [3, 'hello', 30] result.val == Channel.STOP + + cleanup: + sql.execute("drop table FOO") } }