rewrite matrix plugin readme

This commit is contained in:
Strong Liu 2011-11-27 22:53:41 +08:00
parent 1f11f78074
commit dd5074b9b2
2 changed files with 179 additions and 68 deletions

179
buildSrc/Readme.md Normal file
View File

@ -0,0 +1,179 @@
##Hibernate Matrix Testing
#### Goal
Run hibernate-core _functional_ tests on other DBs besides default H2 easily.
Well, although [Functional Testing](http://en.wikipedia.org/wiki/Functional_testing) and [Unit Testing](http://en.wikipedia.org/wiki/Unit_testing) are already well known in the developer world, but we ( hibernate team ) use a little different definition:
###### Unit Test
Test doesn't need DB involved or only the default DB (currently is [H2](http://www.h2database.com/)) is fine, then we call it is a _unit test_.
###### Functional Test
Test which is used to verify a hibernate function and needs to make sure this function works fine on all DBs.
Just to be clear, in hibernate codebase, most tests we have are _functional tests_ by this definition.
And all hibernate _functional tests_ are also _unit tests_, since they are also supposed to pass on the default DB (H2).
#### MatrixTestingPlugin
Since Hibernate Core has moved to [Gradle](http://www.gradle.org/) from [Maven](http://maven.apache.org/), so we created a gradle plugin, called _MatrixTestingPlugin_, to run hibernate functional tests on the DB matrix (this is why it is called _MatrixTestingPlugin_ :).
The source of this plugin is [here](https://github.com/hibernate/hibernate-core/tree/master/buildSrc), this is used by Hibernate Core only right now, so this post is specific to hibernate core project only, hope one day we could denote it to the gradle community.
#### How to use this plugin
1. apply this plugin in your gradle build script (of course!)
In [hibernate-core/hibernate-core.gradle](https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/hibernate-core.gradle) we have this line:
`apply plugin: org.hibernate.gradle.testing.matrix.MatrixTestingPlugin`
2. SourceSet separation
Although it is possible to define a logical separation in Gradle (see [this](http://gradle.org/current/docs/javadoc/org/gradle/api/tasks/SourceSet.html)), I would like physical separation of unit tests and functional tests, so, we have this project structure:
localhost:hibernate-core stliu$ tree -L 3
├── hibernate-core.gradle
├── src
   ├── main
   │   ├── antlr
   │   ├── java
   │   ├── javadoc
   │   ├── resources
   │   └── xjb
   ├── matrix
   │   └── java
   └── test
   ├── java
   └── resources
* matrix/java
all functional tests go into this directory
* test/java
all unit tests go into this directory
* test/resources
all resources for ***functional tests and unit tests***, yes, resource files in this directory are shared for both, so you don't need to copy one file to both place, for example, log4j.properties.
To make _idea plugin_ (and _eclipse plugin_) works, we also have this defined in hibernate-core.gradle:
sourceSets {
matrix {
java {
srcDir 'src/matrix/java'
}
resources {
srcDir 'src/matrix/resources'
}
}
}
ideaModule {
sourceDirs += file( '$buildDir/generated-src/antlr/main' )
testSourceDirs += file( 'src/matrix/java')
testSourceDirs += file( 'src/matrix/resources')
}
3. DB profile
A DB profile defines the JDBC driver and DB connection info ( and hibernate properties for this DB ) that hibernate should use to run _functional tests_ on this DB.
A DB profile looks like this:
├── mysql50
│   ├── jdbc
│   │   └── mysql-connector-java-5.1.9.jar
│   ├── matrix.gradle
│   └── resources
│   └── hibernate.properties
There are two ways to define JDBC driver, as showed above, put the driver jar file into `jdbc` directory, or use `matrix.gradle` file, below is something you should put into your `matrix.gradle` file:
jdbcDependency "mysql:mysql-connector-java:5.1.17"
As you can see, just add the driver's GAV into `jdbcDependency` configuration, then MatrixTestingPlugin will look it up from maven repository defined in the `build.gradle` and add it to the `testCompile` scope.
For DB connection info, you should add it into `resources/hibernate.properties` (if you have Redhat VPN access, you can use the DB maintained by JBoss QA and get the DB connection automatically through DB Allocator, see below).
NOTE: this `hibernate.properties` will overrides the one in `hibernate-core/test/resources/hibernate.properties` if same property name defined in both place.
And, the DB profile name is the directory name, in this example, it is _mysql50_.
The default DB profile location is in `hibernate-core/databases` directory, but you can also reallocate it to another place by using system property `hibernate-matrix-databases`, see below for more details.
#### Matrix Tasks
Once you have DB profiles defined, you could run `gradle tasks --all`, this will list all tasks you can use.
For example, there will be a `matrix` task, which depends on all of other `matrix_${profile_name}` tasks, each DB profile has a `matrix_${profile_name}` task, so if you want to run hibernate functional tests on all DB profiles, then just call `gradle matrix` or if you want to run them on mysql only, then `gradle mysql50`.
In this case ( run `gradle matrix` or its sub-task `gradle matrix_${profile_name}` ), only tests in `src/matrix/java` will be ran, and `hibernate.properties` come from your `db profile/resources/hibernate.properties` (and `test/resources/hibernate.properties`).
Matrix test results are in `target/matrix/${profile_name}/test-results`.
But, there is also a `test` task, this task runs ***all*** tests, both `src/matrix/java` and `src/test/java`, with `src/test/resources` on default DB (as above said, all _functional tests_ are also _unit tests_).
Unit test results are in `target/test-results`, so if you run `test` task, all test results are in here, instead of `target/matrix/${profile_name}/test-results`, just as normal.
#### Configuration Properties
There are two way to pass a system property to gradle build:
1. The original java way, -Dxxx=yyy
2. Add it to ${user.home}/.gradle/gradle.properties with a 'systemProp' prefix, like 'systemProp.xxx=yyy'
* hibernate-matrix-databases
This property is used to define the location of DB profile container.
Accept value: absolute path of DB profile container directory.
* hibernate-matrix-ignore
This property is used to ignore some DB profiles (or all of them), so if you run `matrix`, the ignored profile matrix task won't be run.
Accept value : _all_ or _${profile name1},${profile name2},${profile name3}_
#### DB Allocator (JBoss internally, VPN required)
For users who has access to JBoss QA lab (need Redhat VPN), here is a better way to run matrix tests, you don't need to have a DB instance on your side, but you can use DB instance in JBoss QA Lab.
And the connection info can be queried from DB Allocator automatically.
This feature is disabled by default, to enable it, you need this system property
* hibernate-matrix-dballcoation
Accept value: _all_ or _${profile name1},${profile name2},${profile name3}_
For example, if you want to run matrix test on postgresql84, you can use this command
./gradlew clean test matrix_postgresql84 -Dhibernate-matrix-dballocation=postgresql84
what does this command do actually?
1. test
run 'src/test/java' on default H2, test results in 'target/test-results'
run 'src/matrix/java' on default H2, test results in 'target/test-results'
2. query postgresql 84 db instance connection info
3. run 'src/matrix/java' on postgresql 84 with 'databases/postgresql84/matrix.gradle' defined jdbc driver and 'databases/postgresql84/resources/hibernate.properties' and postgresql84 db instance connection info (this info will override those defined in hibernate.properties), test results in 'target/matrix/postgresql84/results'
Some DBs need we tweak url with some configurations after get it from DB allocator, so, we can use this system property:
* hibernate-matrix-dballocation-url-postfix-${dbname}
for example:
`-Dhibernate-matrix-dballocation-url-postfix-sybase155="?SQLINITSTRING=set quoted_identifier on&DYNAMIC_PREPARE=true"`
* hibernate-matrix-dballocation-requestee
This property is used to define the DB Allocator requester name, default is _hibernate_

View File

@ -1,68 +0,0 @@
org.hibernate.gradle.testing.matrix.MatrixTestingPlugin
Goal:
Run hibernate-core functional test on other DBs besides default H2 easily.
Usage:
1. Databases configuration
In the root hibernate-core project, we have a 'databases' directory, this is the default DB profiles location, take it as an example and you can create your db profile easily.
Take a look of the sub-directories of 'databases' to see how each DB profile is defined.
Each default DB profile has a matrix.gradle, we use this to get jdbc driver from a maven repo.
but we also accept a 'jbdc' directory which contains jdbc driver directly to replace this matrix.gradle, this is useful for non-opensource jdbc drivers.
And each DB profile also needs a "resources/hibernate.properties", which, as you expected, defines DB connection info and others hibernate properties.
For now, we have 5 default DB profiles, mysql50, mysql51, postgresql82, postgresql83 and postgresql84.
You can create your DB profile under 'hibernate-core/databases', but if you do that, GIT will ask you check in or remove it everytime when you run git command.
so, you should create a 'databases/${your db profile}' in other place and use system property 'hibernate-matrix-databases' with the full path of your 'databases'.
Btw, to add a system properties, you can either use '-Dhibernate-matrix-databases' or add it to ${user.home}/.gradle/gradle.properties with a 'systemProp' perfix, like 'systemProp.hibernate-matrix-databases=${your databases directory path}'
and if this property is given, MatrixTestingPlugin will take profiles defined in there as well as default 'hibernate-core/databases'
MatrixTestingPlugin also has a system property "hibernate-matrix-ignore" which can be use to ignore some DB profiles or all of them, it accepts values like:
'all' -- ignore all DB profiles, so matrix testing will be ignored.
'${profile name1},${profile name2},${profile name3}'
2. Gradle Tasks
run './gradlew tasks --all', you will see there is a 'matrix' task and also 'matrix_${profile_name}' tasks against your DB profiles (not ignored).
3. Source Set separation
All functional tests[1] should go into src/matrix/java
All unit tests[2] should go into src/test/java
if you run gradle task 'test', tests in src/test/java and src/matrix/java will be ran, and resources of src/test/resource will be used.
so, "functional tests" defined in 'src/matrix/java' here are also 'unit test' which run on default H2.
all test results (test and matrix) are in target/test-results.
if you run gradle task 'matrix' (or its sub-task 'matrix_${profile name}), only tests in 'src/matrix/java' will be ran, and hibernate.properties come from your db profile/resources/hibernate.properties.
3. DBAllocation
For users who has access to JBoss QA lab (need redhat vpn), here is an better way to run matrix tests, you don't need to have a DB instance on your side, but you can use DB instance in JBoss QA Lab.
And the connection info can be queried by DBAllocation automatically.
This feature is disabled by default, to enable it, you need system property 'hibernate-matrix-dballcoation', it accepts value like: 'all', '${profile name1},${profile name2},${profile name3}'
for example, if you want to run matrix test on postgresql84, default DB profile, you can
'./gradlew clean test matrix_postgresql84 -Dhibernate-matrix-dballocation=postgresql84'
some DBs need we tweak url with some configurations after get it from DB allocator, so, we can use this system property:
"hibernate-matrix-dballocation-url-postfix-${dbname} = configurations"
for example:
-Dhibernate-matrix-dballocation-url-postfix-sybase155="?SQLINITSTRING=set quoted_identifier on&DYNAMIC_PREPARE=true"
what does this command do actually?
1. test
run 'src/test/java' on default H2, test results in 'target/test-results'
run 'src/matrix/java' on default H2, test results in 'target/test-results'
2. query postgresql 84 db instance connection info
3. run 'src/matrix/java' on postgresql 84 with 'databases/postgresql84/matrix.gradle' defined jdbc driver and 'databases/postgresql84/resources/hibernate.properties' and postgresql84 db instance connection info (this info will override those defined in hibernate.properties), test results in 'target/matrix/postgresql84/results'
[1] Functional Test in this document means test need to run on DB matrix
[2] Unit Test in this document means test does not care the underlying DB (H2) or does not need a DB involved.
* others may have different "functional test"/"unit test" definition :)
* use 'hibernate-matrix-dballocation-requestee' to define requestee, default is 'hibernate'