Description
Distributed JUnit support has been added starting GridGain 1.6.0 release.
You can distribute your JUnit4 test suites in 2 different ways. One way is to use GridJunit4Suite directly instead of the usual JUnit4 Suite class. This is perhaps the easiest and most straight forward way to grid-enable your JUnit4 test suites.
Another way is with AOP by attaching @GridifyTest to the same class you attach @RunWith(Suite.class) annotation. The advantage of this approach is that you can provide test configuration parameters, such as timeout or custom test router right as annotation parameter in code, without having to pass extra VM arguments.
Package
org.gridgain.grid.test.junit4 Javadoc![]()
GridJunit4Suite
GridJunit4Suite ![]()
Below is an example of distributed JUnit4 test suite:
@RunWith(GridJunit4Suite.class)
@SuiteClasses({
TestA.class, // TestA will run in parallel on the grid.
TestB.class, // TestB will run in parallel on the grid.
TestC.class, // TestC will run in parallel on the grid.
TestD.class // TestD will run in parallel on the grid.
})
public class GridJunit4ExampleSuite {
// No-op.
}
If you have four tests A, B, C, and D, and if you need to run A and B sequentially, then you should create a nested test suite with test A and B as follows:
@RunWith(GridJunit4Suite.class)
@SuiteClasses({
GridJunit4ExampleNestedSuite.class, // Nested suite that will execute tests A and B added to it sequentially.
TestC.class, // TestC will run in parallel on the grid.
TestD.class // TestD will run in parallel on the grid.
})
public class GridJunit4ExampleSuite {
// No-op.
}
@RunWith(Suite.class)
@SuiteClasses({
TestA.class,
TestB.class
})
public class GridJunit4ExampleNestedSuite {
// No-op.
}
Note that you can also grid-enable existing JUnit4 tests using @GridifyTest annotation which you can attach to the same class you attach @RunWith annotation to.
GridJunit4LocalSuite
Some tests can only be executed locally mostly due to some environment issues. However they still can benefit from parallel execution with other tests. GridGain supports it via GridJunit4LocalSuite ![]()
![]()
To use local test suite within distributed test suite, simply add it to distributed test suite as follows:
@RunWith(GridJunit4Suite.class)
@SuiteClasses({
TestA.class,
TestB.class,
GridJunit4ExampleNestedLocalSuite.class, // Local suite that will execute its test C locally.
})
public class GridJunit4ExampleSuite {
// No-op.
}
@RunWith(GridJunit4LocalSuite.class) // Specify local suite to run tests. @SuiteClasses({ TestC.class, TestD.class }) public class GridJunit4ExampleNestedLocalSuite { // No-op. }
Logging
When running distributed JUnit, all the logging that is done to System.out or System.err is preserved. GridGain will accumulate all logging that is done on remote nodes, send them back to originating node and associate all log statements with their corresponding tests. This way, for example, if you are running tests from and IDEA or Eclipse (or any other IDE) you would still see the logs as if it was a local run. However, since remote nodes keep all log statements done within a single individual test case in memory, you must make sure that enough memory is allocated on every node and that individual test cases do not spit out GigaBytes of log statements. Also note, that logs will be sent back to originating node upon completion of every test, so don't be alarmed if you don't see any log statements for a while and then all of them appear at once.
GridGain achieves such log transparency via reassigning System.out or System.err to internal PrintStream implementation. However, when using Log4J (or any other logging framework) within your tests you must make sure that it is configured with ConsoleAppender and that ConsoleAppender.setFollow(boolean) attribute is set to true. Logging to files is not supported yet and is planned for future releases.
Test Nesting
GridJunit4Suite ![]()
GridifyTest Annotation
To enable JUnit4 tests using GridifyTest annotation, you need to attach this annotation to the same class that has Suite annotation (only Suite runners can be grid-enabled in JUnit4).
@RunWith(Suite.class)
@SuiteClasses({
GridJunit4ExampleNestedSuite.class, // Nested suite that will execute tests A and B added to it sequentially.
TestC.class, // Test C will run in parallel with other tests.
TestD.class // TestD will run in parallel with other tests.
})
@GridifyTest // Run this suite on the grid.
public class GridifyJunit4ExampleSuite {
// No-op.
}
@RunWith(Suite.class)
@SuiteClasses({
TestA.class,
TestB.class
})
public class GridJunit4ExampleNestedSuite {
// No-op.
}
For information on how to start GridGain with AOP support refer to AOP Configuration documentation. Note that only AspectJ and JBoss AOP are supported. Spring AOP is not supported as it is proxy-based and only works with interfaces.
Configuration
To run distributed JUnit tests you need to start other instances of GridGain. You can do so by running GRIDGAIN_HOME/bin/gridgain-junit.{sh|bat} script, which will start default configuration. If configuration other than default is required, then use regular GRIDGAIN_HOME/bin/gridgain.{sh|bat} script and pass your own Spring configuration file as a parameter to the script.
You can use the following configuration parameters to configure distributed test suite locally. These parameters are set via @GridifyTest ![]()
![]()
| Configuration Method | Default Value | Description |
|---|---|---|
| @GridifyTest.disabled() |
false | If true then GridGain will be turned off and suite will run locally. This value can be overridden by setting GridTestVmParameters.GRID_DISABLED |
| @GridifyTest.configPath() |
config/junit/junit-spring.xml | Optional path to GridGain Spring configuration file for running JUnit tests. This property can be overridden by setting GridTestVmParameters.GRID_CONFIG |
| @GridifyTest.routerClass() |
GridTestRouterAdapter |
Optional router class that implements GridTestRouter |
| GRID_ROUTER_PREFER_REMOTE |
false | This value can only be set as VM parameter. Set it to true, e.g. -DGRID_ROUTER_PREFER_REMOTE=true, if you would like test router to not route tests to local node if there are remote nodes present. Note that this property works only with default test router. |
| @GridifyTest.timeout() |
0 which means that tests will never timeout. | Maximum timeout value in milliseconds after which test suite will return without waiting for the remaining tests to complete. This value can be overridden by setting GridTestVmParameters.GRID_TEST_TIMEOUT |
Test Scheduling
With GridGain you can configure how many tests you can run in parallel by specifying parallelJobsNumber configuration parameter on GridCollisionSpi ![]()
<property name="collisionSpi"> <bean class="org.gridgain.grid.spi.collision.fifoqueue.GridFifoQueueCollisionSpi"> <property name="parallelJobsNumber" value="1"/> </bean> </property>
The XML configuration above will guarantee that only 1 test can run at a time on local or remote nodes. You can ensure this way that although your tests run in parallel on different nodes, within a single node only one test can be running and all other ones are waiting.
Starting Grid Node
To start a remote node for JUnit tests, open the terminal window on Linux/Mac OS X or Command Prompt on Windows, change directory to ${GRIDGAIN_HOME}/bin and run the gridgain.{sh|bat} script. However, distributed JUnits have to use GridTestExecutorService ![]()
gridgain.bat config/junit/junit-spring.xml
or starting from GridGain 1.6.1, simply execute gridgain-junit.{sh|bat} script.
gridgain-junit.bat
It takes 2-3 seconds for grid node to start and if everything worked fine you should see starting log ending with successful start acknowledgment.
Examples
GridGain comes with several examples for distributed JUnit4. Please refer to JUnit4 - Distributed JUnit Example for example of how to use GridJunit4Suite ![]()
![]()
