package
com.oracle.coherence.test;
import
static
org.hamcrest.CoreMatchers.is;
import
static
org.junit.Assert.assertThat;
import
java.lang.management.ManagementFactory;
import
java.util.HashMap;
import
java.util.Map;
import
java.util.Random;
import
java.util.Set;
import
java.util.concurrent.TimeUnit;
import
javax.management.MBeanServerConnection;
import
javax.management.ObjectName;
import
org.junit.After;
import
org.junit.Before;
import
org.junit.Test;
import
org.littlegrid.ClusterMemberGroup;
import
org.littlegrid.ClusterMemberGroupUtils;
import
com.tangosol.net.CacheFactory;
import
com.tangosol.net.Member;
import
com.tangosol.net.NamedCache;
import
com.tangosol.net.PartitionedService;
/**
* Coherence simple assignment strategy tests.
*
* @author Dave Felcey
*/
public
class
TestCase {
private
ClusterMemberGroup memberGroup;
private
NamedCache cache =
null
;
private
int
[][] racks =
null
;
@Before
public
void
setUp() {
memberGroup = ClusterMemberGroupUtils.newBuilder()
.buildAndConfigureForNoClient();
final
int
numberOfRacks =
3
;
final
int
numberOfMachines =
2
;
final
int
numberOfStorageEnabledMembersPerMachine =
2
;
final
int
expectedClusterSize = (numberOfRacks
* numberOfMachines * numberOfStorageEnabledMembersPerMachine);
racks =
new
int
[numberOfRacks][numberOfMachines
* numberOfStorageEnabledMembersPerMachine];
for
(
int
rack =
0
; rack < numberOfRacks; rack++) {
for
(
int
machine =
0
; machine < numberOfMachines; machine++) {
memberGroup.merge(ClusterMemberGroupUtils
.newBuilder()
.setFastStartJoinTimeoutMilliseconds(
100
)
.setSiteName(
"site1"
)
.setMachineName(
"r-"
+ rack +
"-m-"
+ machine)
.setRackName(
"r-"
+ rack)
.setStorageEnabledCount(
numberOfStorageEnabledMembersPerMachine)
.buildAndConfigureForNoClient());
}
System.arraycopy(memberGroup.getStartedMemberIds(),
rack * numberOfMachines
* numberOfStorageEnabledMembersPerMachine,
racks[rack],
0
, numberOfMachines
* numberOfStorageEnabledMembersPerMachine);
}
memberGroup.merge(ClusterMemberGroupUtils.newBuilder()
.setJmxMonitorCount(
1
).setLogLevel(
9
)
.buildAndConfigureForStorageDisabledClient());
assertThat(
"Cluster size check - includes storage disabled client and JMX monitor"
,
CacheFactory.ensureCluster().getMemberSet().size(),
is(expectedClusterSize +
2
));
assertThat(
"Member group check size is as expected - includes JMX monitor, but not storage disabled client"
,
memberGroup.getStartedMemberIds().length,
is(expectedClusterSize +
1
));
cache = CacheFactory.getCache(
"test"
);
}
/**
* Demonstrate SimpleAssignementStrategy.
*/
@Test
public
void
testSimpleAssignmentStrategy()
throws
Exception {
final
Map entries =
new
HashMap();
final
int
totalEntries =
1000
;
for
(
int
i =
0
; i < totalEntries; i++) {
entries.put(i,
"entry "
+ i);
}
cache.putAll(entries);
assertThat(cache.size(), is(totalEntries));
Random random =
new
Random();
int
rack = Math.abs(random.nextInt() % racks.length);
System.out.println(
"Stopping rack: "
+ rack);
memberGroup.stopMember(racks[rack]);
System.out
.println(
"Pausing to allow data to be recovered"
);
TimeUnit.SECONDS.sleep(memberGroup
.getSuggestedSleepAfterStopDuration()
* racks[rack].length *
10
);
assertThat(
"Partition lost"
,
getPartitionLostEventCount(), is(
0
));
assertThat(
"Cache size"
, cache.size(), is(totalEntries));
}
@After
public
void
tearDown() {
memberGroup.stopAll();
ClusterMemberGroupUtils
.shutdownCacheFactoryThenClusterMemberGroups(memberGroup);
}
/**
* Get the number of partitions lost.
*
* @return partitions lost
*/
private
int
getPartitionLostEventCount()
throws
Exception {
final
MBeanServerConnection connection = ManagementFactory
.getPlatformMBeanServer();
@SuppressWarnings
(
"unchecked"
)
final
Set members = ((PartitionedService) cache
.getCacheService()).getOwnershipEnabledMembers();
final
String serviceName = cache.getCacheService()
.getInfo().getServiceName();
int
lostPartitions =
0
;
for
(Member member : members) {
String path =
"Coherence:type=PartitionListener,name=PartitionLostCount,service="
+ serviceName
+
",id=PartitionLost,nodeId="
+ member.getId();
lostPartitions += (Integer) connection.getAttribute(
new
ObjectName(path),
"PartitionLostCount"
);
}
return
lostPartitions;
}
}