mil.dod.th.ose.remote/test/mil/dod/th/ose/remote/TestSocketMessageListener.java
@Test
    public void testRunMultipleReads() throws InterruptedException, IOException
    {
        int sourceId = 100;
        
        // setup the message to be received
        BaseNamespace baseMessage = BaseNamespace.newBuilder().
                setType(BaseMessageType.RequestControllerInfo).
                build();
        
        final TerraHarvestMessage message = 
                TerraHarvestMessageHelper.createTerraHarvestMessage(sourceId, 1, Namespace.Base, 100, baseMessage);

        // simulate received message from socket
        Map<String, Object> props = new HashMap<String, Object>();
        Socket socket = mock(Socket.class);
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        message.writeDelimitedTo(output);
        
        InputStream inStream = mock(InputStream.class);
        // mock initial byte for size
        final int messageSize = output.toByteArray()[0];
        when(inStream.read()).thenReturn(messageSize);
        // mock rest of message returned in two different segments
        when(inStream.read(Mockito.any(byte[].class), anyInt(), anyInt())).thenAnswer(new Answer<Integer>()
        {
            private int step = 0;

            @Override
            public Integer answer(InvocationOnMock invocation) throws Throwable
            {
                byte[] buffer = (byte[])invocation.getArguments()[0];
                if (step == 0)  // first read will get the first half of the message
                {
                    System.arraycopy(output.toByteArray(), 1, buffer, 0, 4);
                    step++;
                    return 4;
                }
                
                Thread.sleep(50); // simulate break between reads
                // copy in the rest of the message buffer to be read back
                System.arraycopy(output.toByteArray(), 5, buffer, 4, messageSize - 4);
                step = 0; // reset to first step to get 1st half next time
                return 4;
            }
        });
        
        when(socket.getInputStream()).thenReturn(inStream);
        props.put(SocketMessageListener.SOCKET_PROP_KEY, socket);
        // mock the channel that will be sent in map
        AbstractSocketChannel channel = mock(AbstractSocketChannel.class);
        props.put(SocketMessageListener.CHANNEL_PROP_KEY, channel);
        m_SUT.activate(props);
        
        Thread thread = new Thread(m_SUT);
        thread.start();
        
        // wait to give thread time to start and try to read message
        Thread.sleep(1000);
        
        // the socket should read in the message and parse as the same message
        verify(m_MessageRouter, atLeastOnce()).handleMessage(message, channel);
        
        // thread will continue to read in the same message over and over, so must deactivate
        m_SUT.deactivate();
        
        thread.join(300);
        
        assertThat(thread.isAlive(), is(false));
        
        // ensure input stream and socket gets closed
        verify(inStream).close();
        verify(socket).close();
        
        // verify debug logging
        verify(m_Logging, atLeast(1)).debug(anyString());       
    }
/**
     * Verify that if the input stream only returns part of the message, the listener will keep on reading until the 
     * whole message is there
     */
Verify that if the input stream only returns part of the message, the listener will keep on reading until the
whole message is there
Verify that if the input stream only returns part of the message the listener will keep on reading until the whole message is there
@Test
    public void testRunMultipleReads() throws InterruptedException, IOException
    {
        int sourceId = 100;
        BaseNamespace baseMessage = BaseNamespace.newBuilder().
                setType(BaseMessageType.RequestControllerInfo).
                build();
        final TerraHarvestMessage message = 
                TerraHarvestMessageHelper.createTerraHarvestMessage(sourceId, 1, Namespace.Base, 100, baseMessage);
        Map<String, Object> props = new HashMap<String, Object>();
        Socket socket = mock(Socket.class);
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        message.writeDelimitedTo(output);
        InputStream inStream = mock(InputStream.class);
        final int messageSize = output.toByteArray()[0];
        when(inStream.read()).thenReturn(messageSize);
        when(inStream.read(Mockito.any(byte[].class), anyInt(), anyInt())).thenAnswer(new Answer<Integer>()
        {
            private int step = 0;
            @Override
            public Integer answer(InvocationOnMock invocation) throws Throwable
            {
                byte[] buffer = (byte[])invocation.getArguments()[0];
                if (step == 0)  
                {
                    System.arraycopy(output.toByteArray(), 1, buffer, 0, 4);
                    step++;
                    return 4;
                }
                Thread.sleep(50); 
                System.arraycopy(output.toByteArray(), 5, buffer, 4, messageSize - 4);
                step = 0; 
                return 4;
            }
        });
        when(socket.getInputStream()).thenReturn(inStream);
        props.put(SocketMessageListener.SOCKET_PROP_KEY, socket);
        AbstractSocketChannel channel = mock(AbstractSocketChannel.class);
        props.put(SocketMessageListener.CHANNEL_PROP_KEY, channel);
        m_SUT.activate(props);
        Thread thread = new Thread(m_SUT);
        thread.start();
        Thread.sleep(1000);
        verify(m_MessageRouter, atLeastOnce()).handleMessage(message, channel);
        m_SUT.deactivate();
        thread.join(300);
        assertThat(thread.isAlive(), is(false));
        verify(inStream).close();
        verify(socket).close();
        verify(m_Logging, atLeast(1)).debug(anyString());       
    }
@ Test public void testRunMultipleReads ( ) throws InterruptedException , IOException { int sourceId = 100 ; BaseNamespace baseMessage = BaseNamespace . newBuilder ( ) . setType ( BaseMessageType . RequestControllerInfo ) . build ( ) ; final TerraHarvestMessage message = TerraHarvestMessageHelper . createTerraHarvestMessage ( sourceId , 1 , Namespace . Base , 100 , baseMessage ) ; Map < String , Object > props = new HashMap < String , Object > ( ) ; Socket socket = mock ( Socket . class ) ; final ByteArrayOutputStream output = new ByteArrayOutputStream ( ) ; message . writeDelimitedTo ( output ) ; InputStream inStream = mock ( InputStream . class ) ; final int messageSize = output . toByteArray ( ) [ 0 ] ; when ( inStream . read ( ) ) . thenReturn ( messageSize ) ; when ( inStream . read ( Mockito . any ( byte [ ] . class ) , anyInt ( ) , anyInt ( ) ) ) . thenAnswer ( new Answer < Integer > ( ) { private int step = 0 ; @ Override public Integer answer ( InvocationOnMock invocation ) throws Throwable { byte [ ] buffer = ( byte [ ] ) invocation . getArguments ( ) [ 0 ] ; if ( step == 0 ) { System . arraycopy ( output . toByteArray ( ) , 1 , buffer , 0 , 4 ) ; step ++ ; return 4 ; } Thread . sleep ( 50 ) ; System . arraycopy ( output . toByteArray ( ) , 5 , buffer , 4 , messageSize - 4 ) ; step = 0 ; return 4 ; } } ) ; when ( socket . getInputStream ( ) ) . thenReturn ( inStream ) ; props . put ( SocketMessageListener . SOCKET_PROP_KEY , socket ) ; AbstractSocketChannel channel = mock ( AbstractSocketChannel . class ) ; props . put ( SocketMessageListener . CHANNEL_PROP_KEY , channel ) ; m_SUT . activate ( props ) ; Thread thread = new Thread ( m_SUT ) ; thread . start ( ) ; Thread . sleep ( 1000 ) ; verify ( m_MessageRouter , atLeastOnce ( ) ) . handleMessage ( message , channel ) ; m_SUT . deactivate ( ) ; thread . join ( 300 ) ; assertThat ( thread . isAlive ( ) , is ( false ) ) ; verify ( inStream ) . close ( ) ; verify ( socket ) . close ( ) ; verify ( m_Logging , atLeast ( 1 ) ) . debug ( anyString ( ) ) ; }
Verify that if the input stream only returns part of the message, the listener will keep on reading until the
 whole message is there
Verify that if the input stream only returns part of the message the listener will keep on reading until the whole message is there
// setup the message to be received // simulate received message from socket // mock initial byte for size // mock rest of message returned in two different segments // first read will get the first half of the message // simulate break between reads // copy in the rest of the message buffer to be read back // reset to first step to get 1st half next time // mock the channel that will be sent in map // wait to give thread time to start and try to read message // the socket should read in the message and parse as the same message // thread will continue to read in the same message over and over, so must deactivate // ensure input stream and socket gets closed // verify debug logging