Skip to content

Commit 9348516

Browse files
committed
fix the tck so it always runs
* split the simple map datastore into it's own library * split the tck up into domains / base spec / tests * ensure the tck only runs on the simple, hibernate5, and mongo implementations
1 parent 20a3f14 commit 9348516

File tree

167 files changed

+1981
-1706
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+1981
-1706
lines changed

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ def publishedProjects = [
6060
'grails-datastore-gorm',
6161
'grails-datastore-gorm-async',
6262
//'grails-datastore-gorm-rx',
63+
'grails-datastore-gorm-simple',
6364
'grails-datastore-gorm-support',
6465
'grails-datastore-gorm-tck',
65-
'grails-datastore-gorm-test',
66+
'grails-datastore-gorm-tck-base',
67+
'grails-datastore-gorm-tck-domains',
6668
'grails-datastore-gorm-validation',
6769
'grails-datastore-web',
6870
'grails-gorm-testing-support',

docs/guide-developer/src/main/docs/stepByStep.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies {
3232
project(':grails-datastore-web'),
3333
project(':grails-datastore-gorm-support')
3434
35-
testImplementation project(':grails-datastore-gorm-tck')
35+
testImplementation project(':grails-datastore-gorm-tck').testFixtures
3636
testRuntime "javax.servlet:javax.servlet-api:$servletApiVersion"
3737
3838
}

docs/guide-developer/src/main/docs/testing.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ The `grails-datastore-gorm-tck` project provides several hundred tests to guaran
22

33
[source,groovy]
44
----
5-
testCompile project(':grails-datastore-gorm-tck')
5+
testCompile project(':grails-datastore-gorm-tck').testFixtures
66
----
77

88
Then create a `Setup.groovy` file that sets up your custom datastore in your implementation.

gradle/publish-config.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ extensions.configure(GrailsPublishExtension) {
2020
'jamesfredley': 'James Fredley'
2121
]
2222
it.artifactId = findProperty('pomArtifactId') ?: name
23+
it.publishTestSources = findProperty('pomPublishTestSources') ?: false
2324
}

gradle/tck-config.gradle

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,33 @@
11
dependencies {
2+
if(!project.hasProperty('includeBaseTckClass') || project.findProperty('includeBaseTckClass')) {
3+
testImplementation project(':grails-datastore-gorm-tck-base')
4+
}
5+
// testImplementation project(path: ':grails-datastore-gorm-tck', configuration: 'testArtifacts')
26
testImplementation project(':grails-datastore-gorm-tck')
7+
testImplementation project(':grails-datastore-gorm-tck-domains')
38
}
49

5-
// We need to test against the TCK. Gradle cannot find/run tests from jars
6-
// without a lot of plumbing, so here we copy the class files from the TCK
7-
// project into this project's test classes dir so Gradle can find the test
8-
// classes and run them. See grails.gorm.tests.GormDatastoreSpec for on the TCK.
10+
// TODO: gradle will happily put the jar file on the classpath, but junit won't find the tests. Dynamic test discovery also won't find them.
11+
tasks.register("extractTckJar", Copy) {
12+
dependsOn(configurations.testRuntimeClasspath)
13+
14+
Provider<Directory> extractTarget = layout.buildDirectory.dir("extracted-tck-classes")
915

10-
// helper, used below.
11-
def toBaseClassRelativePathWithoutExtension = { String base, String classFile ->
12-
if (classFile.startsWith(base)) {
13-
def sansClass = classFile[0 .. classFile.size() - '.class'.size() - 1]
14-
def dollarIndex = sansClass.indexOf('$')
15-
def baseClass = dollarIndex > 0 ? sansClass[0..dollarIndex - 1] : sansClass
16-
def relative = baseClass - base - '/'
17-
relative
16+
doFirst {
17+
extractTarget.get().asFile.deleteDir()
1818
}
19-
else {
20-
null
19+
20+
outputs.dir(extractTarget)
21+
File tckJar = configurations.testRuntimeClasspath.resolve().find { it.name.startsWith("grails-datastore-gorm-tck-${projectVersion}") }
22+
if (tckJar) {
23+
from(zipTree(tckJar))
24+
into(extractTarget)
2125
}
2226
}
2327

24-
tasks.named('test') {
28+
tasks.withType(Test).configureEach {
29+
dependsOn("extractTckJar")
2530
doFirst {
26-
File tckClassesDir = findProject(':grails-datastore-gorm-tck').sourceSets.main.output.classesDirs.files.first()
27-
// surely there is a less hardcoded way to do this
28-
copy {
29-
from tckClassesDir
30-
into sourceSets.test.output.classesDirs.files.first()
31-
include '**/*.class'
32-
exclude { details ->
33-
// Do not copy across any TCK class (or nested classes of that class)
34-
// If there is a corresponding source file in the particular modules
35-
// test source tree. Allows a module to override a test/helper.
36-
if (!details.file.isFile()) {
37-
return false
38-
}
39-
def candidatePath = details.file.absolutePath
40-
def relativePath = toBaseClassRelativePathWithoutExtension(tckClassesDir.absolutePath, candidatePath)
41-
if (relativePath == null) {
42-
throw new IllegalStateException("$candidatePath does not appear to be in the TCK")
43-
}
44-
file("src/test/groovy/${relativePath}.groovy").exists()
45-
}
46-
}
31+
testClassesDirs += files(layout.buildDirectory.dir("extracted-tck-classes"))
4732
}
48-
}
49-
50-
// Only enable to force snapshot dependency updates due to spring dependency management plugin snapshot caching behavior
51-
// configurations.all {
52-
// resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
53-
// }
33+
}

grails-data-hibernate5/gorm/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ dependencies {
4343
}
4444

4545
testImplementation "com.h2database:h2"
46-
testImplementation 'junit:junit' // JUnit 4
46+
testImplementation 'org.junit.platform:junit-platform-suite', {
47+
// api: SelectClasses, Suite
48+
}
4749
testImplementation "org.apache.groovy:groovy-test-junit5"
4850
testImplementation "org.apache.groovy:groovy-sql"
4951
testImplementation "org.apache.groovy:groovy-json"
@@ -69,6 +71,6 @@ dependencies {
6971
apply {
7072
from rootProject.layout.projectDirectory.file('gradle/java-config.gradle')
7173
from rootProject.layout.projectDirectory.file('gradle/hibernate5-test-config.gradle')
72-
from rootProject.layout.projectDirectory.file('gradle/tck-config.gradle')
7374
from rootProject.layout.projectDirectory.file('gradle/publish-config.gradle')
75+
from rootProject.layout.projectDirectory.file('gradle/tck-config.gradle')
7476
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package grails.gorm.tests
2+
3+
import grails.gorm.tck.Book
4+
import grails.gorm.tck.ChildEntity
5+
import grails.gorm.tck.City
6+
import grails.gorm.tck.ClassWithListArgBeforeValidate
7+
import grails.gorm.tck.ClassWithNoArgBeforeValidate
8+
import grails.gorm.tck.ClassWithOverloadedBeforeValidate
9+
import grails.gorm.tck.CommonTypes
10+
import grails.gorm.tck.Country
11+
import grails.gorm.tck.EnumThing
12+
import grails.gorm.tck.Face
13+
import grails.gorm.tck.Highway
14+
import grails.gorm.tck.Location
15+
import grails.gorm.tck.ModifyPerson
16+
import grails.gorm.tck.Nose
17+
import grails.gorm.tck.OptLockNotVersioned
18+
import grails.gorm.tck.OptLockVersioned
19+
import grails.gorm.tck.Person
20+
import grails.gorm.tck.PersonEvent
21+
import grails.gorm.tck.Pet
22+
import grails.gorm.tck.PetType
23+
import grails.gorm.tck.Plant
24+
import grails.gorm.tck.PlantCategory
25+
import grails.gorm.tck.Publication
26+
import grails.gorm.tck.Task
27+
import grails.gorm.tck.TestEntity
28+
import org.grails.datastore.mapping.core.DatastoreUtils
29+
import org.grails.datastore.mapping.core.Session
30+
import spock.lang.Shared
31+
import spock.lang.Specification
32+
33+
/**
34+
* A Spec base class that manages a Session for each feature as well as
35+
* meta class cleanup on the Entity classes in the TCK.
36+
*
37+
* Users of this class need to provide a "setup" class at runtime that
38+
* provides the session instance. It *must* have the following name:
39+
*
40+
* - org.grails.datastore.gorm.Setup
41+
*
42+
* This class must contain a static no-arg method called "setup()"
43+
* that returns a Session instance.
44+
*/
45+
abstract class GormDatastoreSpec extends Specification {
46+
47+
static final CURRENT_TEST_NAME = "current.gorm.test"
48+
static final SETUP_CLASS_NAME = 'org.grails.datastore.gorm.Setup'
49+
static final TEST_CLASSES = [
50+
Book, ChildEntity, City, ClassWithListArgBeforeValidate, ClassWithNoArgBeforeValidate,
51+
ClassWithOverloadedBeforeValidate, CommonTypes, Country, EnumThing, Face, Highway,
52+
Location, ModifyPerson, Nose, OptLockNotVersioned, OptLockVersioned, Person, PersonEvent,
53+
Pet, PetType, Plant, PlantCategory, Publication, Task, TestEntity]
54+
55+
@Shared Class setupClass
56+
57+
Session session
58+
59+
def setupSpec() {
60+
setupClass = loadSetupClass()
61+
}
62+
63+
def setup() {
64+
System.out.println("Using hibernate5 datastore class")
65+
cleanRegistry()
66+
System.setProperty(CURRENT_TEST_NAME, this.getClass().simpleName - 'Spec')
67+
session = createSession()
68+
DatastoreUtils.bindSession session
69+
}
70+
71+
Session createSession() {
72+
setupClass.setup(((TEST_CLASSES + getDomainClasses()) as Set) as List)
73+
}
74+
75+
List getDomainClasses() {
76+
[]
77+
}
78+
79+
def cleanup() {
80+
if (session) {
81+
session.disconnect()
82+
DatastoreUtils.unbindSession session
83+
}
84+
try {
85+
setupClass.destroy()
86+
} catch(e) {
87+
println "ERROR: Exception during test cleanup: ${e.message}"
88+
}
89+
90+
cleanRegistry()
91+
}
92+
93+
private cleanRegistry() {
94+
for (clazz in (TEST_CLASSES + getDomainClasses() )) {
95+
GroovySystem.metaClassRegistry.removeMetaClass(clazz)
96+
}
97+
}
98+
99+
static Class loadSetupClass() {
100+
try {
101+
getClassLoader().loadClass(SETUP_CLASS_NAME)
102+
} catch (Throwable e) {
103+
throw new RuntimeException("Datastore setup class ($SETUP_CLASS_NAME) was not found",e)
104+
}
105+
}
106+
}

grails-data-hibernate5/gorm/src/test/groovy/grails/gorm/tests/GroovyProxySpec.groovy

Lines changed: 0 additions & 37 deletions
This file was deleted.

grails-data-hibernate5/gorm/src/test/groovy/grails/gorm/tests/OptimisticLockingSpec.groovy renamed to grails-data-hibernate5/gorm/src/test/groovy/grails/gorm/tests/HibernateOptimisticLockingSpec.groovy

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,13 @@
11
package grails.gorm.tests
22

3+
import grails.gorm.tck.OptLockNotVersioned
4+
import grails.gorm.tck.OptLockVersioned
35
import org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException
46

5-
67
/**
78
* @author Burt Beckwith
89
*/
9-
class OptimisticLockingSpec extends GormDatastoreSpec {
10-
11-
void "Test versioning"() {
12-
13-
given:
14-
def o = new OptLockVersioned(name: 'locked')
15-
16-
when:
17-
o.save flush: true
18-
19-
then:
20-
o.version == 0
21-
22-
when:
23-
session.clear()
24-
o = OptLockVersioned.get(o.id)
25-
o.name = 'Fred'
26-
o.save flush: true
27-
28-
then:
29-
o.version == 1
30-
31-
when:
32-
session.clear()
33-
o = OptLockVersioned.get(o.id)
34-
35-
then:
36-
o.name == 'Fred'
37-
o.version == 1
38-
}
10+
class HibernateOptimisticLockingSpec extends GormDatastoreSpec {
3911

4012
void "Test optimistic locking"() {
4113

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package grails.gorm.tests
22

3-
import org.junit.runner.RunWith
4-
import org.junit.runners.Suite
3+
import grails.gorm.tck.FirstAndLastMethodSpec
4+
import grails.gorm.tck.NotInListSpec
5+
import org.junit.platform.suite.api.SelectClasses
6+
import org.junit.platform.suite.api.Suite
57

68
/**
79
* Created by graemerocher on 06/07/2016.
810
*/
9-
@RunWith(Suite)
10-
11-
@Suite.SuiteClasses([
12-
NullValueEqualSpec
13-
])
11+
@Suite
12+
@SelectClasses([FirstAndLastMethodSpec])
1413
class HibernateSuite {
1514
}

0 commit comments

Comments
 (0)