Add unit tests for GMSHealthMonitor tcp check
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/7cbb5db0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/7cbb5db0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/7cbb5db0 Branch: refs/heads/feature/GEODE-291 Commit: 7cbb5db091107267da87243259c09d9d047ffbbf Parents: 35394ef Author: Jason Huynh <[email protected]> Authored: Thu Dec 10 10:02:24 2015 -0800 Committer: Jason Huynh <[email protected]> Committed: Thu Dec 10 10:17:00 2015 -0800 ---------------------------------------------------------------------- .../membership/gms/fd/GMSHealthMonitor.java | 34 ++++++++---- .../gms/fd/GMSHealthMonitorJUnitTest.java | 57 ++++++++++++++++++-- 2 files changed, 76 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/7cbb5db0/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitor.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitor.java index cc64f9b..7709114 100755 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitor.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitor.java @@ -472,6 +472,7 @@ public class GMSHealthMonitor implements HealthMonitor, MessageHandler { TimeStamp ts = memberTimeStamps.get(suspectMember); return (ts != null && (System.currentTimeMillis() - ts.getTime()) <= memberTimeout); } + /** * During final check, establish TCP connection between current member and suspect member. @@ -486,6 +487,26 @@ public class GMSHealthMonitor implements HealthMonitor, MessageHandler { logger.debug("Checking member {} with TCP socket connection {}:{}.", suspectMember, suspectMember.getInetAddress(), port); clientSocket = SocketCreator.getDefaultInstance().connect(suspectMember.getInetAddress(), port, (int)memberTimeout, new ConnectTimeoutTask(services.getTimer(), memberTimeout), false, -1, false); + return doTCPCheckMember(suspectMember, clientSocket); + } + catch (IOException e) { + logger.debug("Unexpected exception", e); + } + finally { + try { + if (clientSocket != null) { + clientSocket.close(); + } + } catch (IOException e) { + logger.trace("Unexpected exception", e); + } + } + return false; + } + + //Package protected for testing purposes + boolean doTCPCheckMember(InternalDistributedMember suspectMember, Socket clientSocket) { + try { if (clientSocket.isConnected()) { clientSocket.setSoTimeout((int) services.getConfig().getMemberTimeout()); InputStream in = clientSocket.getInputStream(); @@ -513,17 +534,8 @@ public class GMSHealthMonitor implements HealthMonitor, MessageHandler { logger.debug("tcp/ip connection timed out"); return false; } catch (IOException e) { - logger.debug("Unexpected exception", e); - } finally { - try { - if (clientSocket != null) { - clientSocket.close(); - } - } catch (IOException e) { - logger.trace("Unexpected exception", e); - } - } - + logger.trace("Unexpected exception", e); + } return false; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/7cbb5db0/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java index c4ac3a6..eb17ca8 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/fd/GMSHealthMonitorJUnitTest.java @@ -79,7 +79,7 @@ public class GMSHealthMonitorJUnitTest { @Before public void initMocks() throws UnknownHostException { - System.setProperty("gemfire.bind-address", "localhost"); + //System.setProperty("gemfire.bind-address", "localhost"); mockDistConfig = mock(DistributionConfig.class); mockConfig = mock(ServiceConfig.class); messenger = mock(Messenger.class); @@ -121,7 +121,7 @@ public class GMSHealthMonitorJUnitTest { @After public void tearDown() { gmsHealthMonitor.stop(); - System.getProperties().remove("gemfire.bind-address"); + //System.getProperties().remove("gemfire.bind-address"); } @Test @@ -562,12 +562,61 @@ public class GMSHealthMonitorJUnitTest { when(smm.getDSFID()).thenCallRealMethod(); gmsHealthMonitor.processMessage(smm); } - - private GMSMember createGMSMember(short version, int viewId, long msb, long lsb) { + + @Test + public void testDoTCPCheckMemberWithOkStatus() throws Exception { + executeTestDoTCPCheck(GMSHealthMonitor.OK, true); + } + + @Test + public void testDoTCPCheckMemberWithErrorStatus() throws Exception { + executeTestDoTCPCheck(GMSHealthMonitor.ERROR, false); + } + + @Test + public void testDoTCPCheckMemberWithUnkownStatus() throws Exception { + executeTestDoTCPCheck(GMSHealthMonitor.ERROR + 100, false); + } + + private void executeTestDoTCPCheck(int receivedStatus, boolean expectedResult) throws Exception { + InternalDistributedMember otherMember = createInternalDistributedMember(Version.CURRENT_ORDINAL, 0, 1, 1); + InternalDistributedMember gmsMember = createInternalDistributedMember(Version.CURRENT_ORDINAL, 0, 1, 1); + + //Set up the incoming/received bytes. We just wrap output streams and write out the gms member information + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos.write(receivedStatus); + + byte[] receivedBytes = baos.toByteArray(); + InputStream mockInputStream = new ByteArrayInputStream(receivedBytes); + + Socket fakeSocket = mock(Socket.class); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + when(fakeSocket.getInputStream()).thenReturn(mockInputStream); + when(fakeSocket.getOutputStream()).thenReturn(outputStream); + when(fakeSocket.isConnected()).thenReturn(true); + + Assert.assertEquals(expectedResult, gmsHealthMonitor.doTCPCheckMember(otherMember, fakeSocket)); + + //we can check to see if the gms member information was written out by the tcp check + byte[] bytesWritten = outputStream.toByteArray(); + Assert.assertArrayEquals(writeMemberToBytes((GMSMember)gmsMember.getNetMember()), bytesWritten); + } + + private InternalDistributedMember createInternalDistributedMember(short version, int viewId, long msb, long lsb) throws UnknownHostException{ + GMSMember gmsMember = createGMSMember(version, viewId, msb, lsb); + InternalDistributedMember idm = new InternalDistributedMember("localhost", 9000, Version.CURRENT, gmsMember); + //We set to our expected test viewId in the IDM as well as reseting the gms member + idm.setVmViewId(viewId); + gmsMember.setBirthViewId(viewId); + return idm; + } + + private GMSMember createGMSMember(short version, int viewId, long msb, long lsb) throws UnknownHostException{ GMSMember gmsMember = new GMSMember(); gmsMember.setVersionOrdinal(version); gmsMember.setBirthViewId(viewId); gmsMember.setUUID(new UUID(msb, lsb)); + gmsMember.setInetAddr(InetAddress.getLocalHost()); return gmsMember; }
