Hazelcast allows you to create more than one member on the same JVM. Each member is called
HazelcastInstance
and each will have its own configuration, socket
and threads, so you can treat them as totally separate members. This enables us to write and
run cluster unit tests on single JVM. As you can use this feature for creating separate
members different applications running on the same JVM (imagine running multiple webapps on
the same JVM), you can also use this feature for testing Hazelcast cluster.
Let's say you want to test if two members have the same size of a map.
@Test public void testTwoMemberMapSizes() { // start the first member HazelcastInstance h1 = Hazelcast.newHazelcastInstance(null); // get the map and put 1000 entries Map map1 = h1.getMap("testmap"); for (int i = 0; i < 1000; i++) { map1.put(i, "value" + i); } // check the map size assertEquals(1000, map1.size()); // start the second member HazelcastInstance h2 = Hazelcast.newHazelcastInstance(null); // get the same map from the second member Map map2 = h2.getMap("testmap"); // check the size of map2 assertEquals(1000, map2.size()); // check the size of map1 again assertEquals(1000, map1.size()); }
In the test above, everything happened in the same thread. When developing
multi-threaded test, coordination of the thread executions has to be carefully handled.
Usage of
CountDownLatch
for thread coordination is highly recommended.
You can certainly use other things. Here is an example where we need to listen for messages
and make sure that we got these messages:
@Test public void testTopic() { // start two member cluster HazelcastInstance h1 = Hazelcast.newHazelcastInstance(null); HazelcastInstance h2 = Hazelcast.newHazelcastInstance(null); String topicName = "TestMessages"; // get a topic from the first member and add a messageListener ITopic<String> topic1 = h1.getTopic(topicName); final CountDownLatch latch1 = new CountDownLatch(1); topic1.addMessageListener(new MessageListener() { public void onMessage(Object msg) { assertEquals("Test1", msg); latch1.countDown(); } }); // get a topic from the second member and add a messageListener ITopic<String> topic2 = h2.getTopic(topicName); final CountDownLatch latch2 = new CountDownLatch(2); topic2.addMessageListener(new MessageListener() { public void onMessage(Object msg) { assertEquals("Test1", msg); latch2.countDown(); } }); // publish the first message, both should receive this topic1.publish("Test1"); // shutdown the first member h1.shutdown(); // publish the second message, second member's topic should receive this topic2.publish("Test1"); try { // assert that the first member's topic got the message assertTrue(latch1.await(5, TimeUnit.SECONDS)); // assert that the second members' topic got two messages assertTrue(latch2.await(5, TimeUnit.SECONDS)); } catch (InterruptedException ignored) { } }
You can surely start Hazelcast members with different configuration. Let's say
we want to test if Hazelcast
LiteMember
can shutdown fine.
@Test(timeout = 60000) public void shutdownLiteMember() { // first config for normal cluster member Config c1 = new XmlConfigBuilder().build(); c1.setPortAutoIncrement(false); c1.setPort(5709); // second config for LiteMember Config c2 = new XmlConfigBuilder().build(); c2.setPortAutoIncrement(false); c2.setPort(5710); // make sure to set LiteMember=true c2.setLiteMember(true); // start the normal member with c1 HazelcastInstance hNormal = Hazelcast.newHazelcastInstance(c1); // start the LiteMember with different configuration c2 HazelcastInstance hLite = Hazelcast.newHazelcastInstance(c2); hNormal.getMap("default").put("1", "first"); assert hLite.getMap("default").get("1").equals("first"); hNormal.shutdown(); hLite.shutdown(); }
Also remember to call
Hazelcast.shutdownAll()
after each test
case to make sure that there is no other running member left from the previous tests.
@After
public void cleanup() throws Exception {
Hazelcast.shutdownAll();
}
Need more info? Check out existing tests.