/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.internal.partition.impl; import com.hazelcast.config.Config; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.nio.Address; import com.hazelcast.partition.NoDataMemberInClusterException; import com.hazelcast.test.AssertTask; import com.hazelcast.test.HazelcastParallelClassRunner; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.TestHazelcastInstanceFactory; import com.hazelcast.test.annotation.ParallelTest; import com.hazelcast.test.annotation.QuickTest; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import java.util.List; import java.util.Map; import static java.util.Arrays.asList; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; @RunWith(HazelcastParallelClassRunner.class) @Category({QuickTest.class, ParallelTest.class}) public class InternalPartitionServiceLiteMemberTest extends HazelcastTestSupport { private final Config liteMemberConfig = new Config().setLiteMember(true); /** * PARTITION ASSIGNMENT **/ @Test public void test_partitionsNotAssigned_withLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance instance = factory.newHazelcastInstance(liteMemberConfig); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); partitionService.firstArrangement(); for (int i = 0; i < partitionService.getPartitionCount(); i++) { assertNull(partitionService.getPartition(i).getOwnerOrNull()); } } @Test public void test_partitionsAreAssigned_afterDataMemberJoins() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance liteInstance = factory.newHazelcastInstance(liteMemberConfig); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(liteInstance); partitionService.firstArrangement(); final HazelcastInstance dataInstance = factory.newHazelcastInstance(); warmUpPartitions(liteInstance, dataInstance); for (int i = 0; i < partitionService.getPartitionCount(); i++) { assertEquals(getNode(dataInstance).getThisAddress(), partitionService.getPartition(i).getOwnerOrNull()); } } /** * GET PARTITION **/ @Test public void test_getPartition_nullPartitionOwnerOnMasterLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance instance = factory.newHazelcastInstance(liteMemberConfig); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); assertNull(partitionService.getPartition(0).getOwnerOrNull()); } @Test public void test_getPartition_nullPartitionOwnerOnNonMasterLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, master, other); for (HazelcastInstance instance : asList(master, other)) { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); for (int partitionId = 0; partitionId < partitionService.getPartitionCount(); partitionId++) { assertNull(partitionService.getPartition(0).getOwnerOrNull()); } } } @Test public void test_getPartition_afterLiteMemberLeavesTheCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance dataInstance = factory.newHazelcastInstance(); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); warmUpPartitions(dataInstance, lite); lite.getLifecycleService().shutdown(); assertClusterSizeEventually(1, dataInstance); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(dataInstance); for (int i = 0; i < partitionService.getPartitionCount(); i++) { assertEquals(getNode(dataInstance).getThisAddress(), partitionService.getPartition(i).getOwnerOrNull()); } } @Test public void test_getPartition_afterDataMemberLeavesTheCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(3); final HazelcastInstance master = factory.newHazelcastInstance(); final HazelcastInstance dataInstance = factory.newHazelcastInstance(); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); warmUpPartitions(lite); dataInstance.getLifecycleService().shutdown(); for (HazelcastInstance instance : asList(master, lite)) { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); assertTrueEventually(new AssertTask() { @Override public void run() throws Exception { for (int i = 0; i < partitionService.getPartitionCount(); i++) { assertEquals(getNode(master).getThisAddress(), partitionService.getPartition(i).getOwnerOrNull()); } } }); } } /** * GET PARTITION OWNER **/ @Test public void test_getPartitionOwner_onMasterLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance instance = factory.newHazelcastInstance(liteMemberConfig); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); assertNull(partitionService.getPartitionOwner(0)); } @Test public void test_getPartitionOwner_onNonMasterLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, master, other); for (HazelcastInstance instance : asList(master, other)) { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); assertNull(partitionService.getPartitionOwner(0)); } } @Test(expected = NoDataMemberInClusterException.class) public void test_getPartitionOwnerOrWait_onMasterLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance instance = factory.newHazelcastInstance(liteMemberConfig); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); partitionService.getPartitionOwnerOrWait(0); } @Test(expected = NoDataMemberInClusterException.class) public void test_getPartitionOwnerOrWait_onNonMasterLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, master, other); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(other); partitionService.getPartitionOwnerOrWait(0); } @Test public void test_getPartitionOwnerOrWait_onLiteMemberAfterDataMemberTerminates() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); warmUpPartitions(master, lite); master.getLifecycleService().terminate(); assertTrueEventually(new AssertTask() { @Override public void run() throws Exception { try { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(lite); partitionService.getPartitionOwnerOrWait(0); fail(); } catch (NoDataMemberInClusterException expected) { ignore(expected); } } }); } @Test public void test_getPartitionOwnerOrWait_onLiteMemberAfterDataMemberShutsDown() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, master, lite); warmUpPartitions(master, lite); master.getLifecycleService().shutdown(); assertTrueEventually(new AssertTask() { @Override public void run() throws Exception { try { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(lite); partitionService.getPartitionOwnerOrWait(0); fail(); } catch (NoDataMemberInClusterException expected) { ignore(expected); } } }); } /** * GRACEFUL SHUTDOWN **/ @Test(timeout = 120000) public void test_liteMemberCanShutdownSafely_withClusterSize1() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); lite.getLifecycleService().shutdown(); } @Test(timeout = 120000) public void test_liteMemberCanShutdownSafely_withClusterSize2() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite1 = factory.newHazelcastInstance(liteMemberConfig); factory.newHazelcastInstance(liteMemberConfig); lite1.getLifecycleService().shutdown(); } @Test(timeout = 120000) public void test_liteMemberCanShutdownSafely_whenDataMemberExistsInCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); warmUpPartitions(lite, other); lite.getLifecycleService().shutdown(); } @Test(timeout = 120000) public void test_dataMemberCanShutdownSafely_withClusterSize1() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance master = factory.newHazelcastInstance(); master.getLifecycleService().shutdown(); } @Test(timeout = 120000) public void test_dataMemberCanShutdownSafely_whenOnlyLiteMemberExistsInCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); warmUpPartitions(master, lite); master.getLifecycleService().shutdown(); } /** * TERMINATE **/ @Test(timeout = 120000) public void test_liteMemberCanTerminate_withClusterSize1() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); lite.getLifecycleService().terminate(); } @Test(timeout = 120000) public void test_liteMemberCanTerminate_withClusterSize2() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite1 = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance lite2 = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, lite1, lite2); lite1.getLifecycleService().terminate(); } @Test(timeout = 120000) public void test_liteMemberCanTerminate_whenDataMemberExistsInCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); warmUpPartitions(lite, other); lite.getLifecycleService().terminate(); } @Test(timeout = 120000) public void test_dataMemberCanTerminate_withClusterSize1() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance master = factory.newHazelcastInstance(); master.getLifecycleService().terminate(); } @Test(timeout = 120000) public void test_dataMemberCanTerminate_whenOnlyLiteMemberExistsInCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance master = factory.newHazelcastInstance(); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); warmUpPartitions(master, lite); master.getLifecycleService().terminate(); } /** * GET MEMBER PARTITIONS MAP **/ @Test(expected = NoDataMemberInClusterException.class) public void test_getMemberPartitionsMap_withOnlyLiteMembers() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(lite); partitionService.getMemberPartitionsMap(); } @Test public void test_getMemberPartitionsMap_withLiteAndDataMembers() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance dataInstance = factory.newHazelcastInstance(); warmUpPartitions(lite, dataInstance); final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(lite); final Map<Address, List<Integer>> partitionsMap = partitionService.getMemberPartitionsMap(); assertEquals(1, partitionsMap.size()); final List<Integer> partitions = partitionsMap.get(getAddress(dataInstance)); assertNotNull(partitions); assertFalse(partitions.isEmpty()); } /** * MEMBER GROUP SIZE **/ @Test public void test_memberGroupSize_withSingleLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); assertMemberGroupsSizeEventually(lite, 0); } @Test public void test_memberGroupSize_withMultipleLiteMembers() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance lite2 = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, lite, lite2); for (HazelcastInstance instance : asList(lite, lite2)) { assertMemberGroupsSizeEventually(instance, 0); } } @Test public void test_memberGroupSize_withOneLiteMemberAndOneDataMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); assertClusterSize(2, lite, other); for (HazelcastInstance instance : asList(lite, other)) { assertMemberGroupsSizeEventually(instance, 1); } } @Test public void test_memberGroupSize_afterDataMemberLeavesTheCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); assertClusterSize(2, lite, other); for (HazelcastInstance instance : asList(lite, other)) { assertMemberGroupsSizeEventually(instance, 1); } other.getLifecycleService().shutdown(); assertClusterSizeEventually(1, lite); assertMemberGroupsSizeEventually(lite, 0); } @Test public void test_memberGroupSize_afterLiteMemberLeavesTheCluster() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); assertClusterSize(2, lite, other); for (HazelcastInstance instance : asList(lite, other)) { assertMemberGroupsSizeEventually(instance, 1); } lite.getLifecycleService().shutdown(); assertClusterSizeEventually(1, other); assertMemberGroupsSizeEventually(other, 1); } private void assertMemberGroupsSizeEventually(final HazelcastInstance instance, final int memberGroupSize) { assertTrueEventually(new AssertTask() { @Override public void run() throws Exception { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); assertEquals(memberGroupSize, partitionService.getMemberGroupsSize()); } }); } /** * MAX BACKUP COUNT **/ @Test public void test_maxBackupCount_withSingleLiteMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); assertMaxBackupCountEventually(lite, 0); } @Test public void test_maxBackupCount_withTwoLiteMembers() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance lite2 = factory.newHazelcastInstance(liteMemberConfig); assertClusterSize(2, lite, lite2); for (HazelcastInstance instance : asList(lite, lite2)) { assertMaxBackupCountEventually(instance, 0); } } @Test public void test_maxBackupCount_withOneLiteMemberAndOneDataMember() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); assertClusterSize(2, lite, other); for (HazelcastInstance instance : asList(lite, other)) { assertMaxBackupCountEventually(instance, 0); } } @Test public void test_maxBackupCount_withOneLiteMemberAndTwoDataMembers() { final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(3); final HazelcastInstance lite = factory.newHazelcastInstance(liteMemberConfig); final HazelcastInstance other = factory.newHazelcastInstance(); final HazelcastInstance other2 = factory.newHazelcastInstance(); assertClusterSize(3, lite, other2); assertClusterSizeEventually(3, other); for (HazelcastInstance instance : asList(lite, other, other2)) { assertMaxBackupCountEventually(instance, 1); } } private void assertMaxBackupCountEventually(final HazelcastInstance instance, final int maxBackupCount) { assertTrueEventually(new AssertTask() { @Override public void run() throws Exception { final InternalPartitionServiceImpl partitionService = getInternalPartitionServiceImpl(instance); assertEquals(maxBackupCount, partitionService.getMaxAllowedBackupCount()); } }); } private InternalPartitionServiceImpl getInternalPartitionServiceImpl(HazelcastInstance instance) { return (InternalPartitionServiceImpl) getNode(instance).getPartitionService(); } }