Package org.asteriskjava.manager.internal

Source Code of org.asteriskjava.manager.internal.ManagerConnectionImplTest

/*
*  Copyright 2004-2006 Stefan Reuter
*
*  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 org.asteriskjava.manager.internal;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.asteriskjava.AsteriskVersion;
import org.asteriskjava.manager.AuthenticationFailedException;
import org.asteriskjava.manager.ManagerConnectionState;
import org.asteriskjava.manager.ManagerEventListener;
import org.asteriskjava.manager.TimeoutException;
import org.asteriskjava.manager.action.CommandAction;
import org.asteriskjava.manager.action.PingAction;
import org.asteriskjava.manager.action.StatusAction;
import org.asteriskjava.manager.event.ConnectEvent;
import org.asteriskjava.manager.event.DisconnectEvent;
import org.asteriskjava.manager.event.ManagerEvent;
import org.asteriskjava.manager.event.NewChannelEvent;
import org.asteriskjava.manager.response.ManagerResponse;
import org.asteriskjava.util.SocketConnectionFacade;
import org.junit.Before;
import org.junit.Test;

public class ManagerConnectionImplTest
{
    protected SocketConnectionFacade mockSocket;
    protected ManagerWriterMock mockWriter;
    protected ManagerReaderMock mockReader;
    protected MockedManagerConnectionImpl mc;

    @Before
   public void setUp() throws Exception
    {
        mockWriter = new ManagerWriterMock();
        mockWriter.setExpectedUsername("username");
        // md5 sum of 12345password
        mockWriter.setExpectedKey("40b1b887502902a8ce61a16e44630f7c");

        mockReader = new ManagerReaderMock();
        mockSocket = createMock(SocketConnectionFacade.class);
        mc = new MockedManagerConnectionImpl(mockReader, mockWriter, mockSocket);
        mockWriter.setDispatcher(mc);
    }

    @Test
    public void testDefaultConstructor()
    {
        assertEquals("Invalid default hostname", "localhost", mc.getHostname());
        assertEquals("Invalid default port", 5038, mc.getPort());
    }

    @Test
    public void testRegisterUserEventClass()
    {
        ManagerReader managerReader;

        managerReader = createMock(ManagerReader.class);

        managerReader.registerEventClass(MyUserEvent.class);
        replay(managerReader);

        mc = new MockedManagerConnectionImpl(managerReader, mockWriter, mockSocket);
        mc.registerUserEventClass(MyUserEvent.class);

        assertEquals("unexpected call to createSocket", 0, mc.createSocketCalls);
        assertEquals("unexpected call to createWriter", 0, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        verify(managerReader);
    }

    @Test
    public void testLogin() throws Exception
    {
        MockedManagerEventListener listener;
        long startTime;
        long endTime;
        long duration;

        listener = new MockedManagerEventListener();

        replay(mockSocket);

        mc.setUsername("username");
        mc.setPassword("password");
        mc.addEventListener(listener);
        mc.setDefaultResponseTimeout(5000);
       
        startTime = System.currentTimeMillis();
        mc.login();
        endTime = System.currentTimeMillis();
        duration = endTime - startTime;

        assertEquals("createSocket not called 1 time", 1, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("challenge action not sent 1 time", 1, mockWriter.challengeActionsSent);
        assertEquals("login action not sent 1 time", 1, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);
        assertEquals("setSocket() not called 1 time", 1, mockReader.setSocketCalls);
        // Some time for the reader thread to be started. Otherwise run() might
        // not yet have been
        // called.
        try
        {
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
            // ugly hack to make this work when the thread is interrupted coz a
            // response has been received but the ManagerConnection was not yet
            // sleeping
            Thread.sleep(100);
        }
        assertEquals("run() not called 1 time", 1, mockReader.runCalls);
        assertEquals("unexpected call to die()", 0, mockReader.dieCalls);

        assertEquals("state is not CONNECTED", ManagerConnectionState.CONNECTED, mc.getState());

        assertEquals("must have handled exactly one events", 1, listener.eventsHandled.size());
/*
        assertTrue(
                "first event handled must be a ProtocolIdentifierReceivedEvent",
                listener.eventsHandled.get(0) instanceof ProtocolIdentifierReceivedEvent);
*/
        assertTrue("event handled must be a ConnectEvent",
                listener.eventsHandled.get(0) instanceof ConnectEvent);

        verify(mockSocket);
        assertTrue("login() took longer than 2 second, probably a notify error (duration was " + duration + " is msec)", duration <= 2000);
    }

    @Test
    public void testLoginIncorrectKey() throws Exception
    {
        mockSocket.close();
        replay(mockSocket);

        mockWriter.setExpectedUsername("username");
        // md5 sum of 12345password
        mockWriter.setExpectedKey("40b1b887502902a8ce61a16e44630f7c");

        mc.setUsername("username");
        mc.setPassword("wrong password");

        try
        {
            mc.login();
            fail("No AuthenticationFailedException thrown");
        }
        catch (AuthenticationFailedException e)
        {
        }

        assertEquals("createSocket not called 1 time", 1, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("challenge action not sent 1 time", 1, mockWriter.challengeActionsSent);
        assertEquals("login action not sent 1 time", 1, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);
        assertEquals("setSocket() not called 1 time", 1, mockReader.setSocketCalls);
        // Some time for the reader thread to be started. Otherwise run() might
        // not yet have been
        // called.
        try
        {
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
            // ugly hack to make this work when the thread is interrupted coz a
            // response has been received but the ManagerConnection was not yet
            // sleeping
            Thread.sleep(100);
        }
        assertEquals("run() not called 1 time", 1, mockReader.runCalls);
        assertEquals("unexpected call to die()", 0, mockReader.dieCalls);

        verify(mockSocket);
    }

    @Test
    public void testLoginIOExceptionOnConnect() throws Exception
    {
        replay(mockSocket);

        mc.setThrowIOExceptionOnFirstSocketCreate(true);
        try
        {
            mc.login();
            fail("No IOException thrown");
        }
        catch (IOException e)
        {
        }

        assertEquals("createSocket not called 1 time", 1, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("unexpected challenge action sent", 0, mockWriter.challengeActionsSent);
        assertEquals("unexpected login action sent", 0, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);

        assertEquals("unexpected call to setSocket()", 0, mockReader.setSocketCalls);
        assertEquals("unexpected call to run()", 0, mockReader.runCalls);
        assertEquals("unexpected call to die()", 0, mockReader.dieCalls);

        verify(mockSocket);
    }

    @Test
    public void testLoginTimeoutOnConnect() throws Exception
    {
        mc.setDefaultResponseTimeout(50);

        mockSocket.close();
        replay(mockSocket);

        // provoke timeout
        mockWriter.setSendProtocolIdentifierReceivedEvent(false);

        try
        {
            mc.login();
            fail("No TimeoutException on login()");
        }
        catch (TimeoutException e)
        {
            assertEquals("Timeout waiting for protocol identifier", e.getMessage());
        }

        assertEquals("createSocket not called 1 time", 1, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("unexpected challenge action sent", 0, mockWriter.challengeActionsSent);
        assertEquals("unexpected login action sent", 0, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);

        assertEquals("setSocket() not called 1 time", 1, mockReader.setSocketCalls);
        // Some time for the reader thread to be started. Otherwise run() might
        // not yet have been
        // called.
        Thread.sleep(10);
        assertEquals("run() not called 1 time", 1, mockReader.runCalls);
        assertEquals("unexpected call to die()", 0, mockReader.dieCalls);

        verify(mockSocket);
    }

    @Test
    public void testLoginTimeoutOnChallengeAction() throws Exception
    {
        mc.setDefaultResponseTimeout(200);

        mockSocket.close();
        replay(mockSocket);

        // provoke timeout
        mockWriter.setSendResponse(false);

        try
        {
            mc.login();
            fail("No TimeoutException on login()");
        }
        catch (AuthenticationFailedException e)
        {
            assertEquals("Unable to send challenge action", e.getMessage());
            assertEquals("Timeout waiting for response to Challenge", e.getCause().getMessage());
            assertTrue(e.getCause() instanceof TimeoutException);
        }

        assertEquals("createSocket not called 1 time", 1, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("challenge action not sent 1 time", 1, mockWriter.challengeActionsSent);
        assertEquals("unexpected login action sent", 0, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);

        assertEquals("setSocket() not called 1 time", 1, mockReader.setSocketCalls);
        // Some time for the reader thread to be started. Otherwise run() might
        // not yet have been
        // called.
        Thread.sleep(10);
        assertEquals("run() not called 1 time", 1, mockReader.runCalls);
        assertEquals("unexpected call to die()", 0, mockReader.dieCalls);

        verify(mockSocket);
    }

    @Test
    public void testLogoffWhenConnected() throws Exception
    {
        mockSocket.close();
        replay(mockSocket);

        // fake connect
        mc.connect();
        mc.setState(ManagerConnectionState.CONNECTED);

        mc.logoff();

        assertEquals("logoff action not sent 1 time", 1,
                mockWriter.logoffActionsSent);
        verify(mockSocket);
    }

    @Test
    public void testLogoffWhenNotConnected() throws Exception
    {
        replay(mockSocket);

        try
        {
            mc.logoff();
            fail("Expected IllegalStateException when calling logoff when not connected");
        }
        catch (IllegalStateException e)
        {
            // fine
        }

        assertEquals("unexpected logoff action sent", 0, mockWriter.logoffActionsSent);
        verify(mockSocket);
    }

    @Test
    public void testSendActionWithNullAction() throws Exception
    {
        // fake connect
        mc.connect();
        try
        {
            mc.sendAction(null);
            fail("No IllgealArgumentException thrown");
        }
        catch (IllegalArgumentException e)
        {
        }
    }

    @Test
    public void testSendActionWhenNotConnected() throws Exception
    {
        StatusAction statusAction;

        statusAction = new StatusAction();

        try
        {
            mc.sendAction(statusAction);
            fail("No IllegalStateException thrown");
        }
        catch (IllegalStateException e)
        {
        }
    }

    @Test
    public void testSendAction() throws Exception
    {
        StatusAction statusAction;
        ManagerResponse response;

        statusAction = new StatusAction();
        statusAction.setActionId("123");

        // fake connect
        mc.connect();
        mc.setState(ManagerConnectionState.CONNECTED);
        response = mc.sendAction(statusAction);

        assertEquals("incorrect actionId in action", "123", statusAction.getActionId());
        assertEquals("incorrect actionId in response", "123", response.getActionId());
        assertEquals("incorrect response", "Success", response.getResponse());

        assertEquals("other actions not sent 1 time", 1, mockWriter.otherActionsSent);
    }

    @Test
    public void testSendActionTimeout() throws Exception
    {
        StatusAction statusAction;

        statusAction = new StatusAction();
        statusAction.setActionId("123");

        mc.setDefaultResponseTimeout(200);
        // fake connect
        mc.connect();
        mc.setState(ManagerConnectionState.CONNECTED);

        // provoke timeout
        mockWriter.setSendResponse(false);
        try
        {
            mc.sendAction(statusAction);
            fail("No TimeoutException thrown");
        }
        catch (TimeoutException e)
        {
        }

        assertEquals("other actions not sent 1 time", 1, mockWriter.otherActionsSent);
    }

    @Test
    public void testDispatchResponseUnexpectedResponse()
    {
        ManagerResponse response;

        response = new ManagerResponse();
        // internalActionId: 123_0
        response.setActionId("123_0-abc");
        response.setResponse("Success");

        // expected result is ignoring the response and logging
        mc.dispatchResponse(response);
    }

    @Test
    public void testDispatchResponseMissingInternalActionId()
    {
        ManagerResponse response;

        response = new ManagerResponse();
        response.setActionId("abc");
        response.setResponse("Success");

        // expected result is ignoring the response and logging
        mc.dispatchResponse(response);
    }

    @Test
    public void testDispatchResponseNullActionId()
    {
        ManagerResponse response;

        response = new ManagerResponse();
        response.setActionId(null);
        response.setResponse("Success");

        // expected result is ignoring the response and logging
        mc.dispatchResponse(response);
    }
   
    @Test
    public void testDispatchResponseNullResponse()
    {
        // expected result is ignoring and logging
        mc.dispatchResponse(null);
    }

    @Test
    public void testReconnect() throws Exception
    {
        DisconnectEvent disconnectEvent;

        replay(mockSocket);
        disconnectEvent = new DisconnectEvent(this);

        // fake successful login
        mc.setState(ManagerConnectionState.CONNECTED);

        mc.setUsername("username");
        mc.setPassword("password");

        mc.dispatchEvent(disconnectEvent);
       
        // wait for reconnect thread to do its work
        Thread.sleep(1000);

        assertEquals("createSocket not called 1 time", 1, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("challenge action not sent 1 time", 1, mockWriter.challengeActionsSent);
        assertEquals("login action not sent 1 time", 1, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);

        assertEquals("state is not CONNECTED", ManagerConnectionState.CONNECTED, mc.getState());

        verify(mockSocket);
    }

    @Test
    public void testReconnectWithIOException() throws Exception
    {
        DisconnectEvent disconnectEvent;

        replay(mockSocket);
        disconnectEvent = new DisconnectEvent(this);

        // fake successful login
        mc.setState(ManagerConnectionState.CONNECTED);

        mc.setThrowIOExceptionOnFirstSocketCreate(true);

        mc.setUsername("username");
        mc.setPassword("password");

        mc.dispatchEvent(disconnectEvent);

        // wait for reconnect thread to do its work
        Thread.sleep(1000);

        assertEquals("createSocket not called 1 time", 2, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("challenge action not sent 1 time", 1, mockWriter.challengeActionsSent);
        assertEquals("login action not sent 1 time", 1, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);

        assertEquals("state is not CONNECTED", ManagerConnectionState.CONNECTED, mc.getState());

        verify(mockSocket);
    }

    @Test
    public void testReconnectWithTimeoutException() throws Exception
    {
        DisconnectEvent disconnectEvent;

        mockSocket.close();
        replay(mockSocket);
        disconnectEvent = new DisconnectEvent(this);

        // fake successful login
        mc.setState(ManagerConnectionState.CONNECTED);

        mc.setThrowTimeoutExceptionOnFirstLogin(true);

        mc.setUsername("username");
        mc.setPassword("password");

        mc.dispatchEvent(disconnectEvent);

        // wait for reconnect thread to do its work
        Thread.sleep(1000);

        assertEquals("createSocket not called 2 time", 2, mc.createSocketCalls);
        assertEquals("createWriter not called 1 time", 1, mc.createWriterCalls);
        assertEquals("createReader not called 1 time", 1, mc.createReaderCalls);

        assertEquals("challenge action not sent 1 time", 1, mockWriter.challengeActionsSent);
        assertEquals("login action not sent 1 time", 1, mockWriter.loginActionsSent);
        assertEquals("unexpected other actions sent", 0, mockWriter.otherActionsSent);

        assertEquals("state is not CONNECTED", ManagerConnectionState.CONNECTED, mc.getState());

        verify(mockSocket);
    }

    @SuppressWarnings("unchecked")
    @Test
    public void testDispatchEventWithMultipleEventHandlers()
    {
        final int count = 20;
        ManagerEvent event;
        final List<Integer> list;

        // verify that event handlers are called in the correct order
        event = new NewChannelEvent(this);
        list = createMock(List.class);
        for (int i = 0; i < count; i++)
        {
            final int index = i;
            expect(list.add(index)).andReturn(true);
            mc.addEventListener(new ManagerEventListener()
            {
                public void onManagerEvent(ManagerEvent event)
                {
                    list.add(index);
                }
            });
        }

        replay(list);
        mc.dispatchEvent(event);
        verify(list);
    }

    @Test
    public void testIsShowVersionCommandAction()
    {
        assertTrue(mc.isShowVersionCommandAction(new CommandAction("show version")));
        assertTrue(mc.isShowVersionCommandAction(new CommandAction("core show version")));
        assertTrue(mc.isShowVersionCommandAction(new CommandAction("core show version foo bar")));
        assertFalse(mc.isShowVersionCommandAction(new CommandAction("foo show version")));
        assertFalse(mc.isShowVersionCommandAction(new PingAction()));
    }

    private class MockedManagerEventListener implements ManagerEventListener
    {
        List<ManagerEvent> eventsHandled;

        public MockedManagerEventListener()
        {
            this.eventsHandled = new ArrayList<ManagerEvent>();
        }

        public void onManagerEvent(ManagerEvent event)
        {
            eventsHandled.add(event);
        }
    }

    private class MockedManagerConnectionImpl
            extends
                ManagerConnectionImpl
    {
        ManagerReader mockReader;
        ManagerWriter mockWriter;
        SocketConnectionFacade mockSocket;

        private boolean throwIOExceptionOnFirstSocketCreate = false;
        private boolean throwTimeoutExceptionOnFirstLogin = false;

        public int createReaderCalls = 0;
        public int createWriterCalls = 0;
        public int createSocketCalls = 0;
       
        public int loginCalls = 0;

        public MockedManagerConnectionImpl(ManagerReader mockReader,
                ManagerWriter mockWriter, SocketConnectionFacade mockSocket)
        {
            super();
            this.mockReader = mockReader;
            this.mockWriter = mockWriter;
            this.mockSocket = mockSocket;
        }

        public void setThrowTimeoutExceptionOnFirstLogin(boolean b)
        {
            this.throwTimeoutExceptionOnFirstLogin = b;
        }

        public void setThrowIOExceptionOnFirstSocketCreate(boolean b)
        {
            this.throwIOExceptionOnFirstSocketCreate = b;
        }

        @Override
        public String getUsername()
        {
            return username;
        }

        @Override
        public String getPassword()
        {
            return password;
        }

        public void setState(ManagerConnectionState state)
        {
            this.state = state;
        }

        @Override
        protected ManagerReader createReader(Dispatcher d, Object source)
        {
            createReaderCalls++;
            return mockReader;
        }

        @Override
        protected ManagerWriter createWriter()
        {
            createWriterCalls++;
            return mockWriter;
        }

        @Override
        protected SocketConnectionFacade createSocket() throws IOException
        {
            createSocketCalls++;

            if (throwIOExceptionOnFirstSocketCreate && createSocketCalls == 1)
            {
                throw new IOException();
            }
            return mockSocket;
        }
       
        @Override
        protected void doLogin(long timeout, String events) throws IOException,
            AuthenticationFailedException, TimeoutException
        {
            loginCalls++;

            if (throwTimeoutExceptionOnFirstLogin && loginCalls == 1)
            {
                disconnect();
                throw new TimeoutException("Provoked timeout");
            }
            super.doLogin(timeout, events);
        }
       
        @Override
      protected AsteriskVersion determineVersion()
        {
            return null;
        }
    }
}
TOP

Related Classes of org.asteriskjava.manager.internal.ManagerConnectionImplTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.