From 5c8632f2d179715ab16ec25ddf21308ebb7162d8 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Wed, 15 May 2013 15:47:49 +0200 Subject: [PATCH 01/14] Upgraded to grails 2.2.2 and release 2.2.1 --- application.properties | 6 +++--- grails-app/conf/BuildConfig.groovy | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/application.properties b/application.properties index 1dea0ec1..31409967 100644 --- a/application.properties +++ b/application.properties @@ -1,5 +1,5 @@ #Grails Metadata file -#Thu Feb 28 15:57:41 CET 2013 -app.grails.version=2.2.1 +#Wed May 15 15:47:34 CEST 2013 +app.grails.version=2.2.2 app.name=transmart-core -plugins.hibernate=2.2.1 +plugins.hibernate=2.2.2 diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index 7be9ec55..4bec652d 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -45,7 +45,7 @@ grails.project.dependency.resolution = { compile(':db-reverse-engineer:0.5') { exported: false } build(":tomcat:$grailsVersion", - ":release:2.2.0", + ":release:2.2.1", ":rest-client-builder:1.0.3", ) { exported: false From 9cac948974a3ba5ef03b4c13a05945bfca351b07 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Wed, 5 Jun 2013 16:39:53 +0200 Subject: [PATCH 02/14] DeChromosomalRegion: include new cytoband property --- .../org/transmartproject/db/highdim/DeChromosomalRegion.groovy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grails-app/domain/org/transmartproject/db/highdim/DeChromosomalRegion.groovy b/grails-app/domain/org/transmartproject/db/highdim/DeChromosomalRegion.groovy index 968866f8..82038035 100644 --- a/grails-app/domain/org/transmartproject/db/highdim/DeChromosomalRegion.groovy +++ b/grails-app/domain/org/transmartproject/db/highdim/DeChromosomalRegion.groovy @@ -9,6 +9,7 @@ class DeChromosomalRegion implements Region { Long end Integer numberOfProbes String name + String cytoband /* unused */ String geneSymbol @@ -41,6 +42,7 @@ class DeChromosomalRegion implements Region { end nullable: true numberOfProbes nullable: true name nullable: true, maxSize: 100 + cytoband nullable: true, maxSize: 100 geneSymbol nullable: true, maxSize: 100 geneId nullable: true organism nullable: true, maxSize: 200 From 3355e6ee07d31a228c2471a2163a0bf9f1f654ab Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Wed, 5 Jun 2013 16:49:22 +0200 Subject: [PATCH 03/14] Update maven repos id --- grails-app/conf/BuildConfig.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index 4bec652d..1df55e75 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -2,7 +2,7 @@ grails.project.class.dir = "target/classes" grails.project.test.class.dir = "target/test-classes" grails.project.test.reports.dir = "target/test-reports" -grails.project.repos.default = 'repo.hyve.nl-snapshots' +grails.project.repos.default = 'repo.thehyve.nl-snapshots' grails.project.repos."${grails.project.repos.default}".url = 'http://repo.thehyve.nl/content/repositories/snapshots/' grails.project.dependency.resolution = { @@ -18,7 +18,7 @@ grails.project.dependency.resolution = { mavenLocal() mavenCentral() mavenRepo([ - name: 'repo.hyve.nl-snapshots', + name: 'repo.thehyve.nl-snapshots', root: 'http://repo.thehyve.nl/content/repositories/snapshots/', ]) } From 49c5f4f416a85a16ad9d079ca5c0603a08b13c49 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Wed, 5 Jun 2013 17:03:18 +0200 Subject: [PATCH 04/14] Rename out-of-tree data source config Renamed to DataSource-coredb.groovy so it doesn't conflict with transmartApp's. --- grails-app/conf/Config.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grails-app/conf/Config.groovy b/grails-app/conf/Config.groovy index ee1e9cf9..5a74d018 100644 --- a/grails-app/conf/Config.groovy +++ b/grails-app/conf/Config.groovy @@ -1,7 +1,7 @@ // configuration for plugin testing - will not be included in the plugin zip def dataSourceConfig = new File("${userHome}/" + - ".grails/transmartConfig/DataSource.groovy") + ".grails/transmartConfig/DataSource-coredb.groovy") if (!dataSourceConfig.exists()) throw new RuntimeException("Coult not find ${dataSourceConfig}") From ba5cf6d2a3c4c6f5c4575f979d178ae17d590dd6 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Wed, 5 Jun 2013 17:39:25 +0200 Subject: [PATCH 05/14] [FT-193] Reduce waiting time for retrieving clinical + regions data, for aCGH analyses --- .../dataquery/DataQueryResourceService.groovy | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy index 6454989e..ba3778e4 100644 --- a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy +++ b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy @@ -67,15 +67,16 @@ class DataQueryResourceService implements DataQueryResource { * query before just to get the regions. This would minimize the * amount of data that the postgres server has to send us. */ - def mainHQL = 'select acgh, acgh.region\n' + - 'from DeSubjectAcghData as acgh\n' + - 'inner join acgh.assay assay\n' - //'inner join acgh.region\n' - mainHQL <<= 'where ' + whereClauses.join("\nand ") + "\n" - mainHQL <<= 'order by acgh.region.id, assay\n' - - new RegionResultImpl(assays, - createQuery(session, mainHQL, params).scroll(FORWARD_ONLY)) + def mainHQL = ''' + select acgh, acgh.region + from DeSubjectAcghData as acgh + inner join acgh.assay assay + where assay in (:assays) + order by acgh.region.id, assay''' + + def mainQuery = createQuery(session, mainHQL, ['assays' : assays]).scroll(FORWARD_ONLY) + + new RegionResultImpl(assays, mainQuery) } private void validateQuery(ACGHRegionQuery q) { From f0fb0ded3aaa2e528f5328f536459419b214bff4 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Thu, 13 Jun 2013 14:30:34 +0200 Subject: [PATCH 06/14] [FT-193] Reduce waiting time for retrieving clinical + regions data, for aCGH analyses Implemented "no gorm" version of retrieving regions data --- .../DataQueryResourceNoGormService.groovy | 137 ++++++++++++++++++ .../dataquery/DataQueryResourceService.groovy | 53 ++++--- .../db/dataquery/RegionResultImpl.groovy | 24 +-- .../db/dataquery/RegionRowImpl.groovy | 18 ++- 4 files changed, 192 insertions(+), 40 deletions(-) create mode 100644 grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceNoGormService.groovy diff --git a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceNoGormService.groovy b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceNoGormService.groovy new file mode 100644 index 00000000..ff172e1f --- /dev/null +++ b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceNoGormService.groovy @@ -0,0 +1,137 @@ +package org.transmartproject.db.dataquery + +import groovy.transform.CompileStatic +import org.hibernate.Query +import org.hibernate.ScrollableResults +import org.hibernate.Session +import org.hibernate.StatelessSession +import org.hibernate.impl.AbstractSessionImpl +import org.transmartproject.core.dataquery.DataQueryResource +import org.transmartproject.core.dataquery.acgh.RegionResult +import org.transmartproject.core.dataquery.assay.Assay +import org.transmartproject.core.dataquery.constraints.ACGHRegionQuery +import org.transmartproject.core.dataquery.acgh.Region +import org.transmartproject.core.dataquery.acgh.ACGHValues +import org.transmartproject.core.dataquery.acgh.CopyNumberState +import org.transmartproject.core.dataquery.Platform +import org.transmartproject.core.dataquery.acgh.RegionRow + +import static org.hibernate.ScrollMode.FORWARD_ONLY + +class DataQueryResourceNoGormService extends DataQueryResourceService { + + @Override + protected RegionResult getRegionResultForAssays(final List assays, AbstractSessionImpl session) { + def mainHQL = ''' + select + acgh.assay.id, + acgh.chipCopyNumberValue, + acgh.segmentCopyNumberValue, + acgh.flag, + acgh.probabilityOfLoss, + acgh.probabilityOfNormal, + acgh.probabilityOfGain, + acgh.probabilityOfAmplification, + + region.id, + region.cytoband, + region.chromosome, + region.start, + region.end, + region.numberOfProbes + from DeSubjectAcghData as acgh + inner join acgh.region region + where acgh.assay.id in (:assayIds) + order by region.id, acgh.assay.id'''.stripIndent() + + def mainQuery = createQuery(session, mainHQL, ['assayIds': assays.collect {Assay assay -> assay.id}]).scroll(FORWARD_ONLY) + + new RegionResultListImpl(assays, mainQuery) + } + + @CompileStatic + class ACGHValuesImpl implements ACGHValues { + final List rowList + + ACGHValuesImpl(final List rowList) { + this.rowList = rowList + } + + Long getAssayId() { rowList[0] as Long } + + Double getChipCopyNumberValue() { rowList[1] as Double } + + Double getSegmentCopyNumberValue() { rowList[2] as Double } + + CopyNumberState getCopyNumberState() { CopyNumberState.forInteger((rowList[3] as Short).intValue()) } + + Double getProbabilityOfLoss() { rowList[4] as Double } + + Double getProbabilityOfNormal() { rowList[5] as Double } + + Double getProbabilityOfGain() { rowList[6] as Double } + + Double getProbabilityOfAmplification() { rowList[7] as Double } + + } + + @CompileStatic + class RegionImpl implements Region { + + final List rowList + + RegionImpl(final List rowList) { + this.rowList = rowList + } + + Long getId() { rowList[8] as Long } + + String getCytoband() { rowList[9] as String } + + Platform getPlatform() { + throw new UnsupportedOperationException('Getter for get platform is not implemented') + } + + String getChromosome() { rowList[10] as String } + + Long getStart() { rowList[11] as Long } + + Long getEnd() { rowList[12] as Long } + + Integer getNumberOfProbes() { rowList[13] as Integer } + + } + + @CompileStatic + class RegionResultListImpl extends org.transmartproject.db.dataquery.RegionResultImpl { + RegionResultListImpl(List indicesList, ScrollableResults results) { + super(indicesList, results) + } + + @Override + protected RegionRow getNextRegionRow() { + List rowList = results.get() as List + if (rowList == null) { + return null + } + + RegionImpl region = new RegionImpl(rowList) + ACGHValuesImpl acghValue = new ACGHValuesImpl(rowList) + + Map values = new HashMap(indicesList.size(), 1) + while (new RegionImpl(rowList).id == region.id) { + values[acghValue.assayId] = acghValue + + if (!results.next()) { + break + } + rowList = results.get() as List + acghValue = new ACGHValuesImpl(rowList) + } + + new RegionRowImpl(region, indicesList, values) + } + } +} + + diff --git a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy index ba3778e4..48b56458 100644 --- a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy +++ b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy @@ -1,14 +1,13 @@ package org.transmartproject.db.dataquery -import org.apache.commons.beanutils.PropertyUtils import org.hibernate.Query import org.hibernate.Session import org.hibernate.StatelessSession +import org.hibernate.impl.AbstractSessionImpl import org.transmartproject.core.dataquery.DataQueryResource import org.transmartproject.core.dataquery.acgh.RegionResult import org.transmartproject.core.dataquery.assay.Assay import org.transmartproject.core.dataquery.constraints.ACGHRegionQuery -import org.transmartproject.db.highdim.DeSubjectAcghData import static org.hibernate.ScrollMode.FORWARD_ONLY @@ -19,35 +18,42 @@ class DataQueryResourceService implements DataQueryResource { @Override RegionResult runACGHRegionQuery(ACGHRegionQuery spec, session) { if (!(session == null || session instanceof Session || session - instanceof StatelessSession)) + instanceof StatelessSession)) { throw new IllegalArgumentException('Expected session to be null ' + 'or an instance of type org.hibernate.Session or ' + 'org.hibernate.StatelessSession') + } validateQuery(spec) session = session ?: sessionFactory.currentSession + List assays = getAssaysForACGHRegionQuery(spec, session) + if (log.isDebugEnabled()) { + log.debug("Found ${assays.size()} assays: " + + assays.collect { + "{id: $it.id, subjectId: $it.subjectId}" + }.join(", ")) + } + + getRegionResultForAssays(assays, session) + } - def whereClauses, - params + protected List getAssaysForACGHRegionQuery(ACGHRegionQuery spec, AbstractSessionImpl session) { + def whereClauses, params /* first obtain list of assays */ whereClauses = [] params = [:] - populateWhereClauses(spec,whereClauses, params) + populateWhereClauses(spec, whereClauses, params) def assayHQL = 'from DeSubjectSampleMapping assay\n' assayHQL <<= 'where ' + whereClauses.join("\nand ") + "\n" assayHQL <<= 'order by assay\n' - List assays = createQuery(session, assayHQL, params).list() - if (log.isDebugEnabled()) { - log.debug("Found ${assays.size()} assays: " + - assays.collect { - "{id: $it.id, subjectId: $id.subjectId}" - }.join(", ")) - } + createQuery(session, assayHQL, params).list() + } + protected RegionResult getRegionResultForAssays(final List assays, AbstractSessionImpl session) { /* Then obtain the meat. * * Doing 'select acgh from ... inner join fetch acgh.region' should @@ -67,22 +73,23 @@ class DataQueryResourceService implements DataQueryResource { * query before just to get the regions. This would minimize the * amount of data that the postgres server has to send us. */ - def mainHQL = ''' - select acgh, acgh.region - from DeSubjectAcghData as acgh - inner join acgh.assay assay - where assay in (:assays) - order by acgh.region.id, assay''' + def mainHQL = ''' + select acgh, acgh.region + from DeSubjectAcghData as acgh + inner join acgh.assay assay + where assay in (:assays) + order by acgh.region.id, assay''' - def mainQuery = createQuery(session, mainHQL, ['assays' : assays]).scroll(FORWARD_ONLY) + def mainQuery = createQuery(session, mainHQL, ['assays': assays]).scroll(FORWARD_ONLY) new RegionResultImpl(assays, mainQuery) } private void validateQuery(ACGHRegionQuery q) { - def checkEmptiness = { it, name -> - if (!it) + def checkEmptiness = {it, name -> + if (!it) { throw new IllegalArgumentException("$name not specified/empty") + } } checkEmptiness(q.common, "query.common") checkEmptiness(q.common.studies, "query.common.studies") @@ -98,7 +105,7 @@ class DataQueryResourceService implements DataQueryResource { assayQuery.readOnly = true assayQuery.cacheable = false - params.each { key, val -> + params.each {key, val -> if (val instanceof Collection) { assayQuery.setParameterList(key, val) } else { diff --git a/src/groovy/org/transmartproject/db/dataquery/RegionResultImpl.groovy b/src/groovy/org/transmartproject/db/dataquery/RegionResultImpl.groovy index 0712fefe..d347b04a 100644 --- a/src/groovy/org/transmartproject/db/dataquery/RegionResultImpl.groovy +++ b/src/groovy/org/transmartproject/db/dataquery/RegionResultImpl.groovy @@ -1,5 +1,6 @@ package org.transmartproject.db.dataquery +import groovy.transform.CompileStatic import org.hibernate.ScrollableResults import org.transmartproject.core.dataquery.acgh.RegionResult import org.transmartproject.core.dataquery.acgh.RegionRow @@ -7,7 +8,8 @@ import org.transmartproject.core.dataquery.assay.Assay import org.transmartproject.db.highdim.DeChromosomalRegion import org.transmartproject.db.highdim.DeSubjectAcghData -final class RegionResultImpl implements RegionResult, Closeable { +@CompileStatic +class RegionResultImpl implements RegionResult, Closeable { final List indicesList @@ -20,13 +22,14 @@ final class RegionResultImpl implements RegionResult, Closeable { this.results = results } - private RegionRow getNextRegionRow() { + protected RegionRow getNextRegionRow() { def entry = results.get() - if (entry == null) + if (entry == null) { return null + } - DeSubjectAcghData v = entry[0] - DeChromosomalRegion commonRegion = entry[1] + DeSubjectAcghData v = entry[0] as DeSubjectAcghData + DeChromosomalRegion commonRegion = entry[1] as DeChromosomalRegion Map values = new HashMap(indicesList.size()) /* Use .@ to access the field and bypass the getter. The problem is @@ -38,9 +41,10 @@ final class RegionResultImpl implements RegionResult, Closeable { while (v.@region.id == commonRegion.id) { values[v.@assay.id] = v - if (!results.next()) + if (!results.next()) { break - v = results.get()[0] + } + v = results.get()[0] as DeSubjectAcghData } new RegionRowImpl(commonRegion, indicesList, values) @@ -51,9 +55,9 @@ final class RegionResultImpl implements RegionResult, Closeable { def row = getNextRegionRow() [ - hasNext: { row != null }, - next: { def r = row; row = getNextRegionRow(); r }, - remove: { throw new UnsupportedOperationException() } + hasNext: { row != null }, + next: { def r = row; row = getNextRegionRow(); r }, + remove: { throw new UnsupportedOperationException() } ] as Iterator } diff --git a/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy b/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy index 078318f3..e1fbf198 100644 --- a/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy +++ b/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy @@ -1,10 +1,12 @@ package org.transmartproject.db.dataquery +import groovy.transform.CompileStatic import org.transmartproject.core.dataquery.acgh.ACGHValues import org.transmartproject.core.dataquery.acgh.Region import org.transmartproject.core.dataquery.acgh.RegionRow import org.transmartproject.core.dataquery.assay.Assay +@CompileStatic class RegionRowImpl implements RegionRow { final Region region @@ -37,11 +39,13 @@ class RegionRowImpl implements RegionRow { @Override ACGHValues getRegionDataForAssay(Assay assay) throws ArrayIndexOutOfBoundsException { - values[assay.id] ?: { - throw new ArrayIndexOutOfBoundsException("Assay with id $assay.id" + - " is not a valid index for this row; valid indexes are " + - "${values.keySet()}, which should match " + - assayList.collect { it.id }) - }() + ACGHValues result = values[assay.id] + if(!result) { + def ids = assayList.collect { Assay assayp -> assayp.id } + throw new ArrayIndexOutOfBoundsException("""Assay with id $assay.id + is not a valid index for this row; valid indexes are + ${values.keySet()}, which should match $ids""") + } + result } -} +} \ No newline at end of file From e08bfc953a5a54badf4e58132bcdb72e3d0c93f2 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Thu, 13 Jun 2013 14:52:14 +0200 Subject: [PATCH 07/14] ws --- .../transmartproject/db/dataquery/RegionRowImpl.groovy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy b/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy index e1fbf198..a467187a 100644 --- a/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy +++ b/src/groovy/org/transmartproject/db/dataquery/RegionRowImpl.groovy @@ -39,13 +39,13 @@ class RegionRowImpl implements RegionRow { @Override ACGHValues getRegionDataForAssay(Assay assay) throws ArrayIndexOutOfBoundsException { - ACGHValues result = values[assay.id] + ACGHValues result = values[assay.id] if(!result) { - def ids = assayList.collect { Assay assayp -> assayp.id } + def ids = assayList.collect { Assay assayp -> assayp.id } throw new ArrayIndexOutOfBoundsException("""Assay with id $assay.id is not a valid index for this row; valid indexes are ${values.keySet()}, which should match $ids""") } - result + result } -} \ No newline at end of file +} From 81901a9800e2fef6361660ffa158cda62e3d2aed Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Thu, 13 Jun 2013 14:58:40 +0200 Subject: [PATCH 08/14] ws --- .../db/dataquery/DataQueryResourceService.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy index 48b56458..fb689e71 100644 --- a/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy +++ b/grails-app/services/org/transmartproject/db/dataquery/DataQueryResourceService.groovy @@ -18,7 +18,7 @@ class DataQueryResourceService implements DataQueryResource { @Override RegionResult runACGHRegionQuery(ACGHRegionQuery spec, session) { if (!(session == null || session instanceof Session || session - instanceof StatelessSession)) { + instanceof StatelessSession)) { throw new IllegalArgumentException('Expected session to be null ' + 'or an instance of type org.hibernate.Session or ' + 'org.hibernate.StatelessSession') @@ -86,7 +86,7 @@ class DataQueryResourceService implements DataQueryResource { } private void validateQuery(ACGHRegionQuery q) { - def checkEmptiness = {it, name -> + def checkEmptiness = { it, name -> if (!it) { throw new IllegalArgumentException("$name not specified/empty") } @@ -105,7 +105,7 @@ class DataQueryResourceService implements DataQueryResource { assayQuery.readOnly = true assayQuery.cacheable = false - params.each {key, val -> + params.each { key, val -> if (val instanceof Collection) { assayQuery.setParameterList(key, val) } else { From bc8ede34801574b9596ee92f1ee8ddf3fdc99ab1 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Thu, 13 Jun 2013 15:15:04 +0200 Subject: [PATCH 09/14] [FT-193] Reduce waiting time for retrieving clinical + regions data, for aCGH analyses Implemented "no gorm" version of retrieving regions data --- .../db/dataquery/DataQueryResourceServiceTests.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy b/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy index 28709061..c468df59 100644 --- a/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy +++ b/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy @@ -91,6 +91,7 @@ class DataQueryResourceServiceTests { equalTo(testACGHData[0]) assertThat regionRows[1].getRegionDataForAssay(testRegionAssays[1]), equalTo(testACGHData[1]) + fail() } @Test From 84c18554ae0e7c0e481de1700f43e42cf6f636cb Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Fri, 14 Jun 2013 16:33:43 +0200 Subject: [PATCH 10/14] Integration tests for "no GORM" DataQueryResource service --- .../DataQueryResourceServiceTests.groovy | 50 ++++++------- .../CompareInterfacePropertiesMatcher.groovy | 71 +++++++++++++++++++ 2 files changed, 94 insertions(+), 27 deletions(-) create mode 100644 test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy diff --git a/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy b/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy index c468df59..4c0594eb 100644 --- a/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy +++ b/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy @@ -3,11 +3,7 @@ package org.transmartproject.db.dataquery import com.google.common.collect.Iterables import com.google.common.collect.Lists import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.rules.ExpectedException -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner import org.transmartproject.core.dataquery.Patient import org.transmartproject.core.dataquery.Platform import org.transmartproject.core.dataquery.acgh.ACGHValues @@ -21,10 +17,10 @@ import org.transmartproject.db.highdim.DeSubjectSampleMapping import org.transmartproject.db.highdim.HighDimTestData import org.transmartproject.db.querytool.QtQueryResultInstance import org.transmartproject.db.querytool.QueryResultData - import static org.hamcrest.MatcherAssert.assertThat import static org.junit.Assert.fail import static org.hamcrest.Matchers.* +import static org.transmartproject.test.Matchers.hasSameInterfaceProperties @Mixin(HighDimTestData) @Mixin(QueryResultData) @@ -32,12 +28,14 @@ class DataQueryResourceServiceTests { def sessionFactory def dataQueryResourceService + def dataQueryResourceNoGormService def resultInstance + def testedService @Before void setUp() { def queryMaster - + testedService = dataQueryResourceNoGormService assertThat testRegionPlatform.save(), isA(Platform) assertThat testRegions*.save(), everyItem(isA(Region)) assertThat testRegionPatients*.save(), everyItem(isA(Patient)) @@ -62,14 +60,14 @@ class DataQueryResourceServiceTests { patientQueryResult: resultInstance ), ) - def result = dataQueryResourceService.runACGHRegionQuery(q, null) + def result = testedService.runACGHRegionQuery(q, null) assertThat result, allOf( is(notNullValue()), hasProperty('indicesList', contains( /* they're ordered by assay id */ - equalTo(testRegionAssays[1]), - equalTo(testRegionAssays[0]), + hasSameInterfaceProperties(Assay, testRegionAssays[1], ['platform']), + hasSameInterfaceProperties(Assay, testRegionAssays[0], ['platform']), )) ) @@ -79,19 +77,18 @@ class DataQueryResourceServiceTests { assertThat regionRows, hasSize(2) /* results are ordered (asc) by region id */ assertThat regionRows[0], - hasProperty('region', equalTo(testRegions[1])) + hasProperty('region', hasSameInterfaceProperties(Region, testRegions[1], ['platform'])) assertThat regionRows[1], - hasProperty('region', equalTo(testRegions[0])) + hasProperty('region', hasSameInterfaceProperties(Region, testRegions[0], ['platform'])) assertThat regionRows[0].getRegionDataForAssay(testRegionAssays[0]), - equalTo(testACGHData[2]) + hasSameInterfaceProperties(ACGHValues, testACGHData[2]) assertThat regionRows[0].getRegionDataForAssay(testRegionAssays[1]), - equalTo(testACGHData[3]) + hasSameInterfaceProperties(ACGHValues, testACGHData[3]) assertThat regionRows[1].getRegionDataForAssay(testRegionAssays[0]), - equalTo(testACGHData[0]) + hasSameInterfaceProperties(ACGHValues, testACGHData[0]) assertThat regionRows[1].getRegionDataForAssay(testRegionAssays[1]), - equalTo(testACGHData[1]) - fail() + hasSameInterfaceProperties(ACGHValues, testACGHData[1]) } @Test @@ -115,35 +112,35 @@ class DataQueryResourceServiceTests { assays << a a = new DeSubjectSampleMapping([ - *:base, + *: base, trialName: 'TRIAL_NOT_MATCHING' ]) a.id = -4002 assays << a a = new DeSubjectSampleMapping([ - *:base, + *: base, timepointCd: 'non_match' ]) a.id = -4003 assays << a a = new DeSubjectSampleMapping([ - *:base, + *: base, sampleTypeCd: 'non_match' ]) a.id = -4004 assays << a a = new DeSubjectSampleMapping([ - *:base, + *: base, tissueTypeCd: 'non_match' ]) a.id = -4005 assays << a a = new DeSubjectSampleMapping([ - *:base, + *: base, platform: extraPlatform ]) a.id = -4006 @@ -152,7 +149,7 @@ class DataQueryResourceServiceTests { assertThat extraPlatform.save(), isA(Platform) assertThat assays*.save(), everyItem(isA(Assay)) - assertThat assays.collect { assay -> + assertThat assays.collect {assay -> createACGHData(testRegions[0], assay, -1) }*.save(), everyItem(isA(ACGHValues)) @@ -167,7 +164,7 @@ class DataQueryResourceServiceTests { ), ) - def result = dataQueryResourceService.runACGHRegionQuery(q, null) + def result = testedService.runACGHRegionQuery(q, null) assertThat result, hasProperty('indicesList', contains( hasProperty('id', equalTo(-4001L)) @@ -186,7 +183,7 @@ class DataQueryResourceServiceTests { QtQueryResultInstance, resultInstance.id) ), ) - def result = dataQueryResourceService.runACGHRegionQuery(q, session) + def result = testedService.runACGHRegionQuery(q, session) assertThat result, hasProperty('indicesList', hasSize(2)) def regionRows = Lists.newArrayList(result.rows) @@ -202,7 +199,7 @@ class DataQueryResourceServiceTests { ) try { - dataQueryResourceService.runACGHRegionQuery(q, null) + testedService.runACGHRegionQuery(q, null) fail("Expected exception") } catch (e) { assertThat(e, allOf( @@ -223,7 +220,7 @@ class DataQueryResourceServiceTests { ) try { - dataQueryResourceService.runACGHRegionQuery(q, null) + testedService.runACGHRegionQuery(q, null) fail("Expected exception") } catch (e) { assertThat(e, allOf( @@ -234,5 +231,4 @@ class DataQueryResourceServiceTests { )) } } - } diff --git a/test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy b/test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy new file mode 100644 index 00000000..d0950449 --- /dev/null +++ b/test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy @@ -0,0 +1,71 @@ +package org.transmartproject.test + +import org.codehaus.groovy.grails.commons.DomainClassArtefactHandler +import org.hamcrest.BaseMatcher +import org.hamcrest.Description; + +class Matchers { + //TODO Print failDetails in fail description + static class CompareInterfacePropertiesMatcher extends BaseMatcher { + + private Object value + private Class interf + private List excludes + private def failDetails = [] + + @Override + boolean matches(Object item) { + def interfacePropertyNames = interf.metaClass.properties*.name + def propertyMap = { + def ret = it.properties.findAll {k, v -> + interfacePropertyNames.contains(k) && + !excludes.contains(k) + } + //TODO Implement better way + if (DomainClassArtefactHandler.isDomainClass(it.getClass()) && + it.id != null) { + ret.id = it.id + } + ret + } + + if(interf.isAssignableFrom(item.class)) { + def itemPropertyMap = propertyMap(item) + def valuePropertyMap = propertyMap(value) + failDetails << value.properties + def diff1 = itemPropertyMap - valuePropertyMap + if(diff1) { + failDetails << "$item has different values than $value:\n$diff1" + } + + def diff2 = valuePropertyMap - itemPropertyMap + if(diff2) { + failDetails << "$value has different values than $item:\n$diff2" + } + + !(diff1 || diff2) + } else { + failDetails << "$interf is not assignable from ${item.class}" + false + } + } + + @Override + void describeTo(Description description) { + description.appendText("hasSameInterfaceProperties(") + .appendValue(interf.name).appendText(", ") + .appendValue(value.toString()).appendText(", ") + .appendValue(excludes.toString()).appendText(")") + } + } + + private static BaseMatcher hasSameInterfaceProperties(Class interf, + Object value, + List excludes = []) { + new CompareInterfacePropertiesMatcher( + value: value, + excludes: excludes, + interf: interf, + ) + } +} From a5d13998e9d7413f5269590bc380d981043be4e7 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Fri, 14 Jun 2013 17:32:07 +0200 Subject: [PATCH 11/14] Test helper class rename --- ...eInterfacePropertiesMatcher.groovy => Matchers.groovy} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename test/integration/org/transmartproject/test/{CompareInterfacePropertiesMatcher.groovy => Matchers.groovy} (94%) diff --git a/test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy b/test/integration/org/transmartproject/test/Matchers.groovy similarity index 94% rename from test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy rename to test/integration/org/transmartproject/test/Matchers.groovy index d0950449..d5f3a061 100644 --- a/test/integration/org/transmartproject/test/CompareInterfacePropertiesMatcher.groovy +++ b/test/integration/org/transmartproject/test/Matchers.groovy @@ -24,22 +24,22 @@ class Matchers { //TODO Implement better way if (DomainClassArtefactHandler.isDomainClass(it.getClass()) && it.id != null) { - ret.id = it.id + ret.id = it.id } ret } - if(interf.isAssignableFrom(item.class)) { + if (interf.isAssignableFrom(item.class)) { def itemPropertyMap = propertyMap(item) def valuePropertyMap = propertyMap(value) failDetails << value.properties def diff1 = itemPropertyMap - valuePropertyMap - if(diff1) { + if (diff1) { failDetails << "$item has different values than $value:\n$diff1" } def diff2 = valuePropertyMap - itemPropertyMap - if(diff2) { + if (diff2) { failDetails << "$value has different values than $item:\n$diff2" } From 91aa5b92fa7206a1d6b02c6e9650b1247f2fda95 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Fri, 14 Jun 2013 17:46:45 +0200 Subject: [PATCH 12/14] Test both gorm & no gorm versions of DataResourceService --- .../dataquery/DataQueryResourceServiceTests.groovy | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy b/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy index 4c0594eb..3a4ed57e 100644 --- a/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy +++ b/test/integration/org/transmartproject/db/dataquery/DataQueryResourceServiceTests.groovy @@ -14,28 +14,22 @@ import org.transmartproject.core.dataquery.constraints.ACGHRegionQuery import org.transmartproject.core.dataquery.constraints.CommonHighDimensionalQueryConstraints import org.transmartproject.db.highdim.DeGplInfo import org.transmartproject.db.highdim.DeSubjectSampleMapping -import org.transmartproject.db.highdim.HighDimTestData import org.transmartproject.db.querytool.QtQueryResultInstance -import org.transmartproject.db.querytool.QueryResultData + import static org.hamcrest.MatcherAssert.assertThat -import static org.junit.Assert.fail import static org.hamcrest.Matchers.* +import static org.junit.Assert.fail import static org.transmartproject.test.Matchers.hasSameInterfaceProperties -@Mixin(HighDimTestData) -@Mixin(QueryResultData) -class DataQueryResourceServiceTests { +abstract class DataQueryResourceServiceTests { def sessionFactory - def dataQueryResourceService - def dataQueryResourceNoGormService def resultInstance def testedService @Before void setUp() { def queryMaster - testedService = dataQueryResourceNoGormService assertThat testRegionPlatform.save(), isA(Platform) assertThat testRegions*.save(), everyItem(isA(Region)) assertThat testRegionPatients*.save(), everyItem(isA(Patient)) From 393bfbf7c770ddb2d90c9477147d208e52c80083 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Fri, 14 Jun 2013 18:36:57 +0200 Subject: [PATCH 13/14] Add files missed in last commit ALso remove redundant import. --- .../GormDataQueryResourceServiceTests.groovy | 17 +++++++++++++++++ .../NoGormDataQueryResourceServiceTests.groovy | 17 +++++++++++++++++ .../db/highdim/HighDimTestData.groovy | 1 - 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/integration/org/transmartproject/db/dataquery/GormDataQueryResourceServiceTests.groovy create mode 100644 test/integration/org/transmartproject/db/dataquery/NoGormDataQueryResourceServiceTests.groovy diff --git a/test/integration/org/transmartproject/db/dataquery/GormDataQueryResourceServiceTests.groovy b/test/integration/org/transmartproject/db/dataquery/GormDataQueryResourceServiceTests.groovy new file mode 100644 index 00000000..3fb71053 --- /dev/null +++ b/test/integration/org/transmartproject/db/dataquery/GormDataQueryResourceServiceTests.groovy @@ -0,0 +1,17 @@ +package org.transmartproject.db.dataquery + +import org.transmartproject.db.highdim.HighDimTestData +import org.transmartproject.db.querytool.QueryResultData + +@Mixin(HighDimTestData) +@Mixin(QueryResultData) +class GormDataQueryResourceServiceTests extends DataQueryResourceServiceTests { + + def dataQueryResourceService + + @Override + void setUp() { + testedService = dataQueryResourceService + super.setUp() + } +} diff --git a/test/integration/org/transmartproject/db/dataquery/NoGormDataQueryResourceServiceTests.groovy b/test/integration/org/transmartproject/db/dataquery/NoGormDataQueryResourceServiceTests.groovy new file mode 100644 index 00000000..375bc1d1 --- /dev/null +++ b/test/integration/org/transmartproject/db/dataquery/NoGormDataQueryResourceServiceTests.groovy @@ -0,0 +1,17 @@ +package org.transmartproject.db.dataquery + +import org.transmartproject.db.highdim.HighDimTestData +import org.transmartproject.db.querytool.QueryResultData; + +@Mixin(HighDimTestData) +@Mixin(QueryResultData) +class NoGormDataQueryResourceServiceTests extends DataQueryResourceServiceTests { + + def dataQueryResourceNoGormService + + @Override + void setUp() { + testedService = dataQueryResourceNoGormService + super.setUp() + } +} diff --git a/test/integration/org/transmartproject/db/highdim/HighDimTestData.groovy b/test/integration/org/transmartproject/db/highdim/HighDimTestData.groovy index 849d2563..3a7553eb 100644 --- a/test/integration/org/transmartproject/db/highdim/HighDimTestData.groovy +++ b/test/integration/org/transmartproject/db/highdim/HighDimTestData.groovy @@ -3,7 +3,6 @@ package org.transmartproject.db.highdim import org.transmartproject.core.dataquery.acgh.Region import org.transmartproject.core.dataquery.assay.Assay import org.transmartproject.db.i2b2data.PatientDimension -import org.transmartproject.db.querytool.QtQueryResultInstance class HighDimTestData { From a69f412b9eafbdd7548d069afbc4fe2e5bd3501d Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Tue, 18 Jun 2013 09:51:27 +0200 Subject: [PATCH 14/14] Add code coverage plugin --- grails-app/conf/BuildConfig.groovy | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index 1df55e75..66f50283 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -50,6 +50,8 @@ grails.project.dependency.resolution = { ) { exported: false } + + test ":code-coverage:1.2.6" } // see http://jira.grails.org/browse/GPRELEASE-42