@Test public void testRemoveMemberExceptions() { createGroup(2); ReplicatedEnvironment master = repEnvInfo[0].getEnv(); assertTrue(master.getState().isMaster()); RepNode masterRep = repEnvInfo[0].getRepNode(); try { masterRep.removeMember(master.getNodeName()); fail("Exception expected."); } catch (MasterStateException e) { // Expected } try { masterRep.removeMember("unknown node foobar"); fail("Exception expected."); } catch (MemberNotFoundException e) { // Expected } masterRep.removeMember(repEnvInfo[1].getRepNode().getNodeName()); try { masterRep.removeMember(repEnvInfo[1].getRepNode().getNodeName()); fail("Exception expected."); } catch (MemberNotFoundException e) { // Expected } repEnvInfo[1].closeEnv(); }
@Override protected void preLogCommitHook() { super.preLogCommitHook(); RepNode rmMasterNode = repEnvInfo[0].getRepNode(); int size = rmMasterNode.getGroup().getAllElectableMembers().size(); int delNodes = ((size & 1) == 1) ? 2 : 1; int closeNodeIndex = (size - delNodes) - 1; /* * The loop below simulates the concurrent removal of a node while * a transaction is in progress. It deletes a sufficient number of * nodes so as to get a lower simple nodes to get to a new lower * simple majority. */ for (int i = repEnvInfo.length - 1; delNodes-- > 0; i--) { repEnvInfo[i].closeEnv(); rmMasterNode.removeMember(repEnvInfo[i].getRepConfig().getNodeName(), delete); } /* * Shut down an additional undeleted Replica to provoke a * lack of acks based on the old simple majority. */ repEnvInfo[closeNodeIndex].closeEnv(); }
/* * Tests internal node removal APIs. */ @Test public void testRemoveMember() { createGroup(groupSize); ReplicatedEnvironment master = repEnvInfo[0].getEnv(); assertTrue(master.getState().isMaster()); RepNode masterRep = repEnvInfo[0].getRepNode(); /* Reduce the group size all the way down to one. */ for (int i = 1; i < groupSize; i++) { assertTrue(!RepInternal.isClosed(repEnvInfo[i].getEnv())); masterRep.removeMember(repEnvInfo[i].getEnv().getNodeName()); assertEquals((groupSize - i), masterRep.getGroup().getElectableGroupSize()); } /* Close the replica handles*/ for (int i = groupSize - 1; i > 0; i--) { repEnvInfo[i].closeEnv(); } /* Attempting to re-open them with the same node names should fail. */ for (int i = 1; i < groupSize; i++) { try { repEnvInfo[i].openEnv(); fail("Exception expected"); } catch (EnvironmentFailureException e) { /* Expected, the master should reject the attempt. */ assertEquals(EnvironmentFailureReason.HANDSHAKE_ERROR, e.getReason()); } } /* Doing the same but with different node names should be ok. */ for (int i = 1; i < groupSize; i++) { final RepEnvInfo ri = repEnvInfo[i]; final ReplicationConfig repConfig = ri.getRepConfig(); TestUtils.removeLogFiles("RemoveRepEnvironments", ri.getEnvHome(), false); repConfig.setNodeName("ReplaceNode_" + i); ri.openEnv(); assertEquals(i + 1, masterRep.getGroup().getElectableGroupSize()); } master.close(); }
/* * Tests internal node deletion APIs. */ @Test public void testDeleteMember() { createGroup(groupSize); ReplicatedEnvironment master = repEnvInfo[0].getEnv(); assertTrue(master.getState().isMaster()); RepNode masterRep = repEnvInfo[0].getRepNode(); /* Reduce the group size all the way down to one. */ for (int i = 1; i < groupSize; i++) { assertTrue(!RepInternal.isClosed(repEnvInfo[i].getEnv())); final String delName = repEnvInfo[i].getEnv().getNodeName(); repEnvInfo[i].closeEnv(); masterRep.removeMember(delName, true); assertEquals((groupSize - i), masterRep.getGroup().getElectableGroupSize()); } /* * Attempting to re-open them with the same node names should succeed */ for (int i = 1; i < groupSize; i++) { repEnvInfo[i].openEnv(); } }