/** * Copyright 2010 Voxeo Corporation * * 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.voxeo.moho.sip; import java.io.IOException; import java.util.Map; import javax.media.mscontrol.MediaSession; import javax.media.mscontrol.MsControlException; import javax.media.mscontrol.MsControlFactory; import javax.media.mscontrol.Parameters; import javax.media.mscontrol.join.Joinable; import javax.media.mscontrol.join.Joinable.Direction; import javax.media.mscontrol.networkconnection.NetworkConnection; import javax.media.mscontrol.networkconnection.SdpPortManager; import javax.media.mscontrol.networkconnection.SdpPortManagerEvent; import javax.media.mscontrol.networkconnection.SdpPortManagerException; import javax.sdp.SdpFactory; import javax.servlet.sip.Address; import javax.servlet.sip.SipApplicationSession; import javax.servlet.sip.SipFactory; import javax.servlet.sip.SipServlet; import javax.servlet.sip.SipServletRequest; import javax.servlet.sip.SipServletResponse; import javax.servlet.sip.SipSession; import javax.servlet.sip.ar.SipApplicationRoutingDirective; import junit.framework.TestCase; import org.hamcrest.Description; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.States; import org.jmock.api.Action; import org.jmock.api.Invocation; import org.jmock.lib.legacy.ClassImposteriser; import org.junit.Ignore; import org.junit.Test; import com.voxeo.moho.ApplicationContextImpl; import com.voxeo.moho.BusyException; import com.voxeo.moho.Call; import com.voxeo.moho.JoinData; import com.voxeo.moho.Participant; import com.voxeo.moho.Participant.JoinType; import com.voxeo.moho.common.event.MohoCallCompleteEvent; import com.voxeo.moho.common.event.MohoJoinCompleteEvent; import com.voxeo.moho.event.JoinCompleteEvent; import com.voxeo.moho.event.Observer; import com.voxeo.moho.media.fake.MockNetworkConnection; import com.voxeo.moho.media.fake.MockParameters; import com.voxeo.moho.sip.SIPCall.State; import com.voxeo.moho.sip.SIPIncomingCallTest.TestApp; import com.voxeo.moho.sip.fake.MockSipServlet; import com.voxeo.moho.sip.fake.MockSipServletRequest; import com.voxeo.moho.sip.fake.MockSipServletResponse; import com.voxeo.moho.sip.fake.MockSipSession; import com.voxeo.moho.spi.ExecutionContext; @Ignore public class SIPOutgoingCallTest extends TestCase { Mockery mockery = new Mockery() { { setImposteriser(ClassImposteriser.INSTANCE); } }; // JSR309 mock MsControlFactory msFactory = mockery.mock(MsControlFactory.class); MediaSession mediaSession = mockery.mock(MediaSession.class); MockNetworkConnection network = mockery.mock(MockNetworkConnection.class); SdpPortManager sdpManager = mockery.mock(SdpPortManager.class); // JSR289 mock SipServlet servlet = new MockSipServlet(mockery); SipApplicationSession appSession = mockery.mock(SipApplicationSession.class); MockSipSession session = mockery.mock(MockSipSession.class); MockSipServletRequest initInviteReq = mockery.mock(MockSipServletRequest.class); // Moho TestApp app = mockery.mock(TestApp.class); // ApplicationContextImpl is simple, no need to mock it. ExecutionContext appContext = null; SipFactory sipFactory = null; SdpFactory sdpFactory = null; SIPEndpoint from = mockery.mock(SIPEndpoint.class, "from");; SIPEndpoint to = mockery.mock(SIPEndpoint.class, "to"); Address fromAddr = mockery.mock(Address.class, "fromAddr"); Address toAddr = mockery.mock(Address.class, "toAddr"); byte[] msReqSDP = new byte[10]; byte[] respSDP = new byte[10]; // testing object private SIPOutgoingCall sipcall; @Override protected void setUp() throws Exception { super.setUp(); if (appContext == null) { appContext = new ApplicationContextImpl(app, msFactory, servlet); sipFactory = appContext.getSipFactory(); sdpFactory = appContext.getSdpFactory(); } initInviteReq.setSession(session); initInviteReq.setMethod("INVITE"); initInviteReq.setIsInitial(true); // common Expectations. mockery.checking(new Expectations() { { allowing(session).getRemoteParty(); will(returnValue(toAddr)); allowing(session).getApplicationSession(); will(returnValue(appSession)); allowing(network).getSdpPortManager(); will(returnValue(sdpManager)); allowing(mediaSession).createParameters(); will(returnValue(new MockParameters())); allowing(mediaSession).setParameters(with(any(MockParameters.class))); allowing(session).getCallId(); will(returnValue("test")); allowing(initInviteReq).setRoutingDirective(with(any(SipApplicationRoutingDirective.class)), with(any(SipServletRequest.class))); allowing(toAddr).getURI(); will(returnValue(null)); allowing(initInviteReq).setRequestURI(null); } }); try { mockery.checking(new Expectations() { { allowing(from).getSipAddress(); will(returnValue(fromAddr)); allowing(to).getSipAddress(); will(returnValue(toAddr)); } }); } catch (Exception ex) { ex.printStackTrace(); } // create outgoingcall expectations. try { mockery.checking(new Expectations() { { oneOf(sipFactory).createApplicationSession(); will(returnValue(appSession)); oneOf(sipFactory).createRequest(appSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } sipcall = new SIPOutgoingCall(appContext, from, to, null); } @Override protected void tearDown() throws Exception { super.tearDown(); appContext.destroy(); } // /** // * send req IOException // */ // @Test // public void testJoinWithSIPIOException() { // joinExceptionWithSIPExpectations("testJoin"); // // // execute // JoinCompleteEvent event = null; // try { // event = sipcall.join(Joinable.Direction.DUPLEX).get(); // // fail("can't catch exception"); // } // catch (Exception ex) { // // } // // // verify result // assertTrue(event.getCause() == JoinCompleteEvent.Cause.ERROR); // // assertTrue(sipcall.getSIPCallState() == State.FAILED); // // assertTrue(sipcall.getMediaObject() == null); // mockery.assertIsSatisfied(); // } /** * @param mockObjectNamePrefix */ private void joinExceptionWithSIPExpectations(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(initInviteReq); sipInviteResp.setStatus(200); sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); final MockSipServletRequest cancelReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "cancelReq"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(msFactory).createMediaSession(); will(returnValue(mediaSession)); oneOf(mediaSession) .createNetworkConnection(with(equal(NetworkConnection.BASIC)), with(any(Parameters.class))); will(returnValue(network)); oneOf(sdpManager).addListener(sipcall); oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); final SipApplicationSession createdAppSession = mockery .mock(SipApplicationSession.class, "createdAppSession"); // create outgoingcall expectations. try { mockery.checking(new Expectations() { { oneOf(sipFactory).createApplicationSession(); will(returnValue(createdAppSession)); oneOf(sipFactory).createRequest(createdAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { allowing(sdpPortManagerEvent).isSuccessful(); will(returnValue(true)); allowing(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); allowing(sdpPortManagerEvent).getMediaServerSdp(); will(returnValue(msReqSDP)); oneOf(initInviteReq).setContent(msReqSDP, "application/sdp"); // throw io exception. oneOf(initInviteReq).send(); will(throwException(new IOException("SIP IOException"))); } }); } catch (Exception ex) { ex.printStackTrace(); } try { mockery.checking(new Expectations() { { allowing(mediaSession).release(); allowing(network).release(); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * send ack io exception. */ public void testJoinWithSIPIOException2() { joinExceptionWithSIPExpectations2("testJoin"); sipcall.addObserver(new MyObserver()); // execute JoinCompleteEvent event = null; try { event = sipcall.join(Joinable.Direction.DUPLEX).get(); // fail("can't catch exception"); } catch (Exception ex) { } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.ERROR); // assertTrue(sipcall.getSIPCallState() == State.FAILED); // assertTrue(sipcall.getMediaObject() == null); mockery.assertIsSatisfied(); } public class MyObserver implements Observer { @com.voxeo.moho.State public void listenCallcomplete(MohoCallCompleteEvent event) { System.out.println("received==========>"); } } /** * @param mockObjectNamePrefix */ private void joinExceptionWithSIPExpectations2(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(initInviteReq); sipInviteResp.setStatus(200); sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); final MockSipServletRequest byeReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "byeReq"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent2 = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "2sdpPortManagerEvent"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(msFactory).createMediaSession(); will(returnValue(mediaSession)); oneOf(mediaSession) .createNetworkConnection(with(equal(NetworkConnection.BASIC)), with(any(Parameters.class))); will(returnValue(network)); oneOf(sdpManager).addListener(sipcall); oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); final SipApplicationSession createdAppSession = mockery .mock(SipApplicationSession.class, "createdAppSession"); // create outgoingcall expectations. try { mockery.checking(new Expectations() { { oneOf(sipFactory).createApplicationSession(); will(returnValue(createdAppSession)); oneOf(sipFactory).createRequest(createdAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { allowing(sdpPortManagerEvent).isSuccessful(); will(returnValue(true)); allowing(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); allowing(sdpPortManagerEvent).getMediaServerSdp(); will(returnValue(msReqSDP)); allowing(sdpPortManagerEvent2).isSuccessful(); will(returnValue(true)); allowing(sdpPortManagerEvent2).getEventType(); will(returnValue(SdpPortManagerEvent.ANSWER_PROCESSED)); oneOf(initInviteReq).setContent(msReqSDP, "application/sdp"); oneOf(initInviteReq).send(); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { sipcall.doResponse(sipInviteResp, null); } catch (Exception e) { // e.printStackTrace(); } } }); th.start(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // process response try { mockery.checking(new Expectations() { { oneOf(sdpManager).processSdpAnswer(with(any(byte[].class))); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent2));} }); } catch (Exception ex) { ex.printStackTrace(); } // process sdp answer processed try { mockery.checking(new Expectations() { { oneOf(sipInviteResp).createAck(); will(returnValue(sipInviteAck)); oneOf(sipInviteAck).send(); will(throwException(new IOException("send ack io exception"))); } }); } catch (Exception ex) { ex.printStackTrace(); } try { mockery.checking(new Expectations() { { allowing(mediaSession).release(); allowing(network).release(); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * sip response busy. */ public void testJoinWithUnsuccessSipResp() { joinExceptionWithUnsuccessSipResp("testJoin"); sipcall.addObserver(new MyObserver()); // execute JoinCompleteEvent event = null; try { event = sipcall.join(Joinable.Direction.DUPLEX).get(); // fail("can't catch join exception"); } catch (Exception ex) { assertTrue(ex.getCause() instanceof BusyException); } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.BUSY); // assertTrue(sipcall.getSIPCallState() == State.FAILED); // assertTrue(sipcall.getMediaObject() == null); mockery.assertIsSatisfied(); } /** * @param mockObjectNamePrefix */ private void joinExceptionWithUnsuccessSipResp(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(initInviteReq); sipInviteResp.setStatus(SipServletResponse.SC_BUSY_HERE); sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(msFactory).createMediaSession(); will(returnValue(mediaSession)); oneOf(mediaSession) .createNetworkConnection(with(equal(NetworkConnection.BASIC)), with(any(Parameters.class))); will(returnValue(network)); oneOf(sdpManager).addListener(sipcall); oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); final SipApplicationSession createdAppSession = mockery .mock(SipApplicationSession.class, "createdAppSession"); // create outgoingcall expectations. try { mockery.checking(new Expectations() { { oneOf(sipFactory).createApplicationSession(); will(returnValue(createdAppSession)); oneOf(sipFactory).createRequest(createdAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { oneOf(sdpPortManagerEvent).isSuccessful(); will(returnValue(true)); oneOf(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); oneOf(sdpPortManagerEvent).getMediaServerSdp(); will(returnValue(msReqSDP)); oneOf(initInviteReq).setContent(msReqSDP, "application/sdp"); oneOf(initInviteReq).send(); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { sipcall.doResponse(sipInviteResp, null); } catch (Exception e) { e.printStackTrace(); } } }); th.start(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // TODO roll back to the original state?? try { mockery.checking(new Expectations() { { allowing(mediaSession).release(); allowing(network).release(); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * process sdp answer exception. */ public void testJoinWithMediaException() { joinExceptionWithMediaExpectations("testJoin"); // execute JoinCompleteEvent event = null; try { event = sipcall.join(Joinable.Direction.DUPLEX).get(); } catch (Exception ex) { } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.ERROR); mockery.assertIsSatisfied(); } /** * @param mockObjectNamePrefix */ private void joinExceptionWithMediaExpectations(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(initInviteReq); sipInviteResp.setStatus(200); sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); final MockSipServletRequest byeReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "byeReq"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(msFactory).createMediaSession(); will(returnValue(mediaSession)); oneOf(mediaSession) .createNetworkConnection(with(equal(NetworkConnection.BASIC)), with(any(Parameters.class))); will(returnValue(network)); oneOf(sdpManager).addListener(sipcall); oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); final SipApplicationSession createdAppSession = mockery .mock(SipApplicationSession.class, "createdAppSession"); // create outgoingcall expectations. try { mockery.checking(new Expectations() { { oneOf(sipFactory).createApplicationSession(); will(returnValue(createdAppSession)); oneOf(sipFactory).createRequest(createdAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { oneOf(sdpPortManagerEvent).isSuccessful(); will(returnValue(true)); oneOf(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); oneOf(sdpPortManagerEvent).getMediaServerSdp(); will(returnValue(msReqSDP)); oneOf(initInviteReq).setContent(msReqSDP, "application/sdp"); oneOf(initInviteReq).send(); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { sipcall.doResponse(sipInviteResp, null); } catch (Exception e) { // e.printStackTrace(); } } }); th.start(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // process response try { mockery.checking(new Expectations() { { // throw SdpPortManagerException. oneOf(sdpManager).processSdpAnswer(respSDP); will(throwException(new SdpPortManagerException("processSdpAnswer Exception"))); } }); } catch (Exception ex) { ex.printStackTrace(); } try { mockery.checking(new Expectations() { { allowing(mediaSession).release(); allowing(network).release(); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * generate sdp offer result in unsuccess. ?? Media2NOJoinDelegate line 30, * when media server response with an unsuccessful answer, the code can't tell * the error information. */ public void testJoinWithErrorMediaResp() { joinWithErrorMediaRespExpectations("testJoin"); // execute JoinCompleteEvent event = null; try { event = sipcall.join(Joinable.Direction.DUPLEX).get(); } catch (Exception ex) { } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.ERROR); mockery.assertIsSatisfied(); } /** * @param mockObjectNamePrefix */ private void joinWithErrorMediaRespExpectations(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(initInviteReq); sipInviteResp.setStatus(200); sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); final MockSipServletRequest cancelReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "cancelReq"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(msFactory).createMediaSession(); will(returnValue(mediaSession)); oneOf(mediaSession) .createNetworkConnection(with(equal(NetworkConnection.BASIC)), with(any(Parameters.class))); will(returnValue(network)); oneOf(sdpManager).addListener(sipcall); oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { allowing(sdpPortManagerEvent).isSuccessful(); will(returnValue(false)); allowing(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); } }); } catch (Exception ex) { ex.printStackTrace(); } try { mockery.checking(new Expectations() { { allowing(network).release(); allowing(mediaSession).release(); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * testJoin. */ public void testJoin() { joinExpectations("testJoin"); // execute try { sipcall.join(Joinable.Direction.DUPLEX).get(); } catch (Exception ex) { ex.printStackTrace(); fail(ex.getMessage()); } // verify result assertEquals(sipcall.getSIPCallState(), SIPCall.State.ANSWERED); assertTrue(sipcall.getMediaObject() == network); mockery.assertIsSatisfied(); } /** * @param mockObjectNamePrefix */ private void joinExpectations(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(initInviteReq); sipInviteResp.setStatus(200); sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEventAnswerProcessed = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEventAnswerProcessed"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(msFactory).createMediaSession(); will(returnValue(mediaSession)); oneOf(mediaSession) .createNetworkConnection(with(equal(NetworkConnection.BASIC)), with(any(Parameters.class))); will(returnValue(network)); oneOf(sdpManager).addListener(sipcall); oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); final SipApplicationSession createdAppSession = mockery .mock(SipApplicationSession.class, "createdAppSession"); // create outgoingcall expectations. try { mockery.checking(new Expectations() { { oneOf(sipFactory).createApplicationSession(); will(returnValue(createdAppSession)); oneOf(sipFactory).createRequest(createdAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { oneOf(sdpPortManagerEvent).isSuccessful(); will(returnValue(true)); oneOf(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); oneOf(sdpPortManagerEvent).getMediaServerSdp(); will(returnValue(msReqSDP)); oneOf(initInviteReq).setContent(msReqSDP, "application/sdp"); oneOf(initInviteReq).send(); will(new MockClientDoResponseAction(sipcall, sipInviteResp, null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { oneOf(sdpPortManagerEventAnswerProcessed).isSuccessful(); will(returnValue(true)); allowing(sdpPortManagerEventAnswerProcessed).getEventType(); will(returnValue(SdpPortManagerEvent.ANSWER_PROCESSED)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process response try { mockery.checking(new Expectations() { { oneOf(sdpManager).processSdpAnswer(respSDP); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEventAnswerProcessed)); oneOf(sipInviteResp).createAck(); will(returnValue(sipInviteAck)); oneOf(sipInviteAck).send(); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * test join(). join(). */ public void testJoinAfterJoin() { joinExpectations("testJoinAfterJoin1"); serverReInviteExpectations("testJoinAfterJoin2"); // execute try { sipcall.join(Joinable.Direction.DUPLEX).get(); sipcall.join(Joinable.Direction.SEND).get(); } catch (Exception ex) { ex.printStackTrace(); fail(ex.getMessage()); } // verify result assertEquals(sipcall.getSIPCallState(), SIPCall.State.ANSWERED); assertTrue(sipcall.getMediaObject() != null); mockery.assertIsSatisfied(); } /** * */ private void serverReInviteExpectations(String mockObjectNamePrefix) { // prepare; // mock jsr289 object. final byte[] msReinviteReqSDP = new byte[10]; final MockSipServletRequest reInviteReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "reInviteReq"); reInviteReq.setMethod("INVITE"); reInviteReq.setIsInitial(false); reInviteReq.setRawContent(msReinviteReqSDP); reInviteReq.setContentType("application/sdp"); final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); reInviteReq.setResponse(sipInviteResp); sipInviteResp.setRequest(reInviteReq); sipInviteResp.setStatus(200); final byte[] respSDP = new byte[10]; sipInviteResp.setRawContent(respSDP); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEvent = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEvent"); // mock jsr309 object final SdpPortManagerEvent sdpPortManagerEventAnswerProcessed = mockery.mock(SdpPortManagerEvent.class, mockObjectNamePrefix + "sdpPortManagerEventAnswerProcessed"); // invoke join() try { mockery.checking(new Expectations() { { oneOf(sdpManager).generateSdpOffer(); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEvent)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { oneOf(sdpPortManagerEvent).isSuccessful(); will(returnValue(true)); oneOf(sdpPortManagerEvent).getEventType(); will(returnValue(SdpPortManagerEvent.OFFER_GENERATED)); oneOf(sdpPortManagerEvent).getMediaServerSdp(); will(returnValue(msReinviteReqSDP)); oneOf(session).createRequest("INVITE"); will(returnValue(reInviteReq)); oneOf(reInviteReq).setContent(msReinviteReqSDP, "application/sdp"); oneOf(reInviteReq).send(); will(new MockClientDoResponseAction(sipcall, sipInviteResp, null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process response try { mockery.checking(new Expectations() { { oneOf(sdpManager).processSdpAnswer(respSDP); will(new MockMediaServerSdpPortManagerEventAction(sipcall, sdpPortManagerEventAnswerProcessed)); oneOf(sipInviteResp).createAck(); will(returnValue(sipInviteAck)); oneOf(sipInviteAck).send(); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sdpPortManagerEvent try { mockery.checking(new Expectations() { { oneOf(sdpPortManagerEventAnswerProcessed).isSuccessful(); will(returnValue(true)); allowing(sdpPortManagerEventAnswerProcessed).getEventType(); will(returnValue(SdpPortManagerEvent.ANSWER_PROCESSED)); } }); } catch (Exception ex) { ex.printStackTrace(); } } /** * */ public void testJoinOutgoingCallBridge() { joinExpectations("testJoinOutgoingCallBridge"); // Outgoingcall mock. // mock moho SIPOutgoingCall final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, "outgoingCall"); final MockNetworkConnection outgoingCallNetwork = mockery.mock(MockNetworkConnection.class, "outgoingCallNetwork"); final States incomingCallStates = mockery.states("incomingCall"); incomingCallStates.become("incomingCallInit"); try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).setJoiningPeer(with(any(JoinData.class))); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).getRemoteSdp(); will(returnValue(null)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(incomingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getSIPCallState(); will(returnValue(State.INVITING)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).getSIPCallState(); will(returnValue(State.ANSWERED)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getMediaObject(); will(returnValue(null)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).getMediaObject(); will(returnValue(outgoingCallNetwork)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getParticipants(with(any(Direction.class))); will(returnValue(new Participant[]{})); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // outgoingCall join(). try { mockery.checking(new Expectations() { { oneOf(outgoingCall).join(Direction.DUPLEX); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { incomingCallStates.become("resped"); sipcall.getJoinDelegate().doJoin(); return null; } }); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } // linkNetworkConnection try { mockery.checking(new Expectations() { { //oneOf(network).join(Direction.DUPLEX, outgoingCallNetwork); } }); } catch (Exception ex) { ex.printStackTrace(); } // linkCall try { mockery.checking(new Expectations() { { oneOf(outgoingCall).addPeer(sipcall, JoinType.BRIDGE, Direction.DUPLEX); oneOf(outgoingCall).dispatch(with(any(JoinCompleteEvent.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } // execute JoinCompleteEvent event = null; try { event = sipcall.join(outgoingCall, JoinType.BRIDGE, Direction.DUPLEX).get(); } catch (Exception ex) { ex.printStackTrace(); fail(ex.getMessage()); } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.JOINED); mockery.assertIsSatisfied(); } /** * send req io exception. */ public void testJoinOutgoingCallBridgeWithSIPIOException() { joinExceptionWithSIPExpectations("testJoinOutgoingCallBridge"); // Outgoingcall mock. // mock moho SIPOutgoingCall final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, "outgoingCall"); final NetworkConnection outgoingCallNetwork = mockery.mock(NetworkConnection.class, "outgoingCallNetwork"); final States incomingCallStates = mockery.states("incomingCall"); incomingCallStates.become("incomingCallInit"); try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).setJoiningPeer(with(any(JoinData.class))); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).getRemoteSdp(); will(returnValue(null)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(incomingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getMediaObject(); will(returnValue(null)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).getMediaObject(); will(returnValue(outgoingCallNetwork)); when(incomingCallStates.is("resped")); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); oneOf(outgoingCall).dispatch(with(any(MohoJoinCompleteEvent.class))); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // execute JoinCompleteEvent event = null; try { event = sipcall.join(outgoingCall, JoinType.BRIDGE, Direction.DUPLEX).get(); // fail("can't catch exception."); } catch (Exception ex) { } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.ERROR); mockery.assertIsSatisfied(); } /** * TODO if the last link operation (jsr309 join) throws exception, should we * roll back to the original state? */ public void testJoinOutgoingCallBridgeWithMediaException() { joinExpectations("testJoinOutgoingCallBridge"); // Outgoingcall mock. // mock moho SIPOutgoingCall final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, "outgoingCall"); final MockNetworkConnection outgoingCallNetwork = mockery.mock(MockNetworkConnection.class, "outgoingCallNetwork"); final States incomingCallStates = mockery.states("incomingCall"); incomingCallStates.become("incomingCallInit"); try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).setJoiningPeer(with(any(JoinData.class))); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).getRemoteSdp(); will(returnValue(null)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(incomingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getSIPCallState(); will(returnValue(State.INVITING)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).getSIPCallState(); will(returnValue(State.ANSWERED)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getMediaObject(); will(returnValue(null)); when(incomingCallStates.is("incomingCallInit")); allowing(outgoingCall).getMediaObject(); will(returnValue(outgoingCallNetwork)); when(incomingCallStates.is("resped")); allowing(outgoingCall).getParticipants(with(any(Direction.class))); will(returnValue(new Participant[]{})); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); oneOf(outgoingCall).dispatch(with(any(MohoJoinCompleteEvent.class))); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); oneOf(outgoingCall).addPeer(with(any(Call.class)), with(any(JoinType.class)), with(any(Direction.class))); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // outgoingCall join(). try { mockery.checking(new Expectations() { { oneOf(outgoingCall).join(Direction.DUPLEX); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { incomingCallStates.become("resped"); sipcall.getJoinDelegate().doJoin(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // linkNetworkConnection try { mockery.checking(new Expectations() { { // throw exception. //oneOf(network).join(Direction.DUPLEX, outgoingCallNetwork); } }); } catch (Exception ex) { ex.printStackTrace(); } // execute JoinCompleteEvent event = null; try { event = sipcall.join(outgoingCall, JoinType.BRIDGE, Direction.DUPLEX).get(); } catch (Exception ex) { // ex.printStackTrace(); } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.JOINED); mockery.assertIsSatisfied(); } // ====================join outgoingcall direct. /** * */ public void testJoinOutgoingCallDirect() { SIPOutgoingCall outgoingCall = joinOutgoingCallDirectExpectations("testJoinOutgoingCallDirect"); // execute try { sipcall.join(outgoingCall, JoinType.DIRECT, Direction.DUPLEX).get(); } catch (Throwable ex) { ex.printStackTrace(); } // verify result assertEquals(sipcall.getSIPCallState(), SIPCall.State.ANSWERED); assertTrue(sipcall.getMediaObject() == null); assertTrue(sipcall.getPeers()[0] == outgoingCall); mockery.assertIsSatisfied(); } private SIPOutgoingCall joinOutgoingCallDirectExpectations(String mockObjectNamePrefix) { // prepare // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); sipInviteResp.setStatus(200); sipInviteResp.setRequest(initInviteReq); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRawContent(respSDP); sipInviteResp.setContentType("application/sdp"); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); sipInviteAck.setMethod("ACK"); // mock moho SIPOutgoingCall final SipSession outgoingSession = mockery.mock(SipSession.class, "outgoingCallSession"); final SipApplicationSession outgoingAppSession = mockery.mock(SipApplicationSession.class, "outgoingCallApplicationSession"); final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, mockObjectNamePrefix + "outgoingCall"); final MockSipServletRequest outgoingCallInviteReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteReq"); outgoingCallInviteReq.setMethod("INVITE"); outgoingCallInviteReq.setIsInitial(true); final MockSipServletResponse outgoingCallInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "outgoingCallInviteResp"); outgoingCallInviteResp.setStatus(200); outgoingCallInviteResp.setReasonPhrase("OK"); final byte[] outgoingCallRespSDP = new byte[10]; outgoingCallInviteResp.setRawContent(outgoingCallRespSDP); outgoingCallInviteResp.setContentType("application/sdp"); final MockSipServletRequest outgoingCallInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteAck"); outgoingCallInviteAck.setMethod("ACK"); final States outgoingCallStates = mockery.states("outgoingCall"); outgoingCallStates.become("outgoingCallInit"); // outgoingCall call(byte[]). try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).getSipInitnalRequest(); will(returnValue(outgoingCallInviteReq)); allowing(outgoingCall).getSipSession(); will(returnValue(outgoingSession)); allowing(outgoingSession).getApplicationSession(); will(returnValue(outgoingAppSession)); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); try { mockery.checking(new Expectations() { { oneOf(sipFactory).createRequest(outgoingAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } oneOf(outgoingCall).call(null); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { sipcall.getJoinDelegate().doInviteResponse(outgoingCallInviteResp, outgoingCall, null); } catch (Exception e) { e.printStackTrace(); } } }); th.start(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // linkCall try { mockery.checking(new Expectations() { { oneOf(outgoingCall).addPeer(sipcall, JoinType.DIRECT, Direction.DUPLEX); oneOf(outgoingCall).dispatch(with(any(JoinCompleteEvent.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } // process outgoingcall response. try { mockery.checking(new Expectations() { { oneOf(initInviteReq).setContent(outgoingCallRespSDP, "application/sdp"); oneOf(initInviteReq).send(); will(new MockClientDoResponseAction(sipcall, sipInviteResp, null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sipcall response. try { mockery.checking(new Expectations() { { oneOf(outgoingCall).setSIPCallState(State.ANSWERED); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { outgoingCallStates.become("resped"); return null; } }); // outgoing call ack. oneOf(outgoingCallInviteResp).createAck(); will(returnValue(outgoingCallInviteAck)); oneOf(outgoingCallInviteAck).setContent(respSDP, "application/sdp"); oneOf(outgoingCallInviteAck).send(); // sipcall ack oneOf(sipInviteResp).createAck(); will(returnValue(sipInviteAck)); oneOf(sipInviteAck).send(); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } return outgoingCall; } /** * */ public void testJoinOutgoingCallDirectWithSIPIOException() { SIPOutgoingCall outgoingCall = joinOutgoingCallDirectExpectationsWithSIPIOException("testJoinOutgoingCallDirectWithSIPIOException"); // execute JoinCompleteEvent event = null; try { event = sipcall.join(outgoingCall, JoinType.DIRECT, Direction.DUPLEX).get(); } catch (Throwable ex) { } // verify result assertTrue(event.getCause() == JoinCompleteEvent.Cause.ERROR); mockery.assertIsSatisfied(); } private SIPOutgoingCall joinOutgoingCallDirectExpectationsWithSIPIOException(String mockObjectNamePrefix) { // prepare // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipInviteResp"); sipInviteResp.setStatus(200); sipInviteResp.setRequest(initInviteReq); initInviteReq.setResponse(sipInviteResp); sipInviteResp.setRawContent(respSDP); sipInviteResp.setContentType("application/sdp"); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipInviteAck"); sipInviteAck.setMethod("ACK"); // mock moho SIPOutgoingCall final SipSession outgoingSession = mockery.mock(SipSession.class, "outgoingSipSession"); final SipApplicationSession outgoingAppSession = mockery.mock(SipApplicationSession.class, "outgoingAppSession"); final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, mockObjectNamePrefix + "outgoingCall"); final MockSipServletRequest outgoingCallInviteReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteReq"); outgoingCallInviteReq.setMethod("INVITE"); outgoingCallInviteReq.setIsInitial(true); final MockSipServletResponse outgoingCallInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "outgoingCallInviteResp"); outgoingCallInviteResp.setStatus(200); outgoingCallInviteResp.setReasonPhrase("OK"); final byte[] outgoingCallRespSDP = new byte[10]; outgoingCallInviteResp.setRawContent(outgoingCallRespSDP); outgoingCallInviteResp.setContentType("application/sdp"); final MockSipServletRequest outgoingCallInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteAck"); outgoingCallInviteAck.setMethod("ACK"); final States outgoingCallStates = mockery.states("outgoingCall"); outgoingCallStates.become("outgoingCallInit"); // outgoingCall call(byte[]). try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).setJoiningPeer(with(any(JoinData.class))); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).getSipInitnalRequest(); will(returnValue(outgoingCallInviteReq)); allowing(outgoingCall).getSipSession(); will(returnValue(outgoingSession)); allowing(outgoingSession).getApplicationSession(); will(returnValue(outgoingAppSession)); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); try { mockery.checking(new Expectations() { { oneOf(sipFactory).createRequest(outgoingAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } oneOf(outgoingCall).call(null); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { sipcall.getJoinDelegate().doInviteResponse(outgoingCallInviteResp, outgoingCall, null); } catch (Exception e) { e.printStackTrace(); } } }); th.start(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // process outgoingcall response. try { mockery.checking(new Expectations() { { oneOf(initInviteReq).setContent(outgoingCallRespSDP, "application/sdp"); oneOf(initInviteReq).send(); will(new MockClientDoResponseAction(sipcall, sipInviteResp, null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sipcall response. try { mockery.checking(new Expectations() { { // sipcall ack oneOf(sipInviteResp).createAck(); will(returnValue(sipInviteAck)); oneOf(sipInviteAck).send(); will(throwException(new IOException("send back ack io exception."))); } }); } catch (Exception ex) { // ex.printStackTrace(); } final MockSipServletRequest sipcallCancelReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipcallCancelReq"); try { mockery.checking(new Expectations() { { // oneOf(initInviteReq).createCancel(); // will(returnValue(sipcallCancelReq)); // // oneOf(sipcallCancelReq).send(); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).fail(with(any(Exception.class))); oneOf(outgoingCall).dispatch(with(any(JoinCompleteEvent.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } return outgoingCall; } /** * */ public void testJoinAnsweredOutgoingCallDirectAfterJoin() { joinExpectations("testJoinOutgoingCallDirectAfterJoin"); SIPOutgoingCall outgoingCall = joinAnsweredOutgoingCallDirectAfterJoinExpectations("testJoinAnsweredOutgoingCallDirectAfterJoin"); // execute JoinCompleteEvent event = null; try { sipcall.join().get(); assertTrue(sipcall.getRemoteSdp() != null); event = sipcall.join(outgoingCall, JoinType.DIRECT, Direction.DUPLEX).get(); } catch (Throwable ex) { ex.printStackTrace(); fail(ex.getMessage()); } // verify result assertEquals(sipcall.getSIPCallState(), SIPCall.State.ANSWERED); assertTrue(sipcall.getMediaObject() == null); assertTrue(sipcall.getPeers()[0] == outgoingCall); mockery.assertIsSatisfied(); } private SIPOutgoingCall joinAnsweredOutgoingCallDirectAfterJoinExpectations(String mockObjectNamePrefix) { // prepare // mock jsr289 object. final MockSipServletRequest sipReInviteReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipReInviteReq"); sipReInviteReq.setMethod("INVITE"); sipReInviteReq.setIsInitial(false); final MockSipServletResponse sipReInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipReInviteResp"); sipReInviteResp.setStatus(200); sipReInviteResp.setRequest(initInviteReq); initInviteReq.setResponse(sipReInviteResp); final MockSipServletRequest sipReInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipReInviteAck"); sipReInviteAck.setMethod("ACK"); // mock moho SIPOutgoingCall final SipSession outgoingSession = mockery.mock(SipSession.class, "outgoingSipSession"); final SipApplicationSession outgoingAppSession = mockery.mock(SipApplicationSession.class, "outgoingAppSession"); final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, mockObjectNamePrefix + "outgoingCall"); final MockSipServletRequest outgoingCallInviteReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteReq"); outgoingCallInviteReq.setMethod("INVITE"); outgoingCallInviteReq.setIsInitial(true); final MockSipServletResponse outgoingCallInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "outgoingCallInviteResp"); outgoingCallInviteResp.setStatus(200); outgoingCallInviteResp.setReasonPhrase("OK"); final byte[] outgoingCallRespSDP = new byte[10]; outgoingCallInviteResp.setRawContent(outgoingCallRespSDP); outgoingCallInviteResp.setContentType("application/sdp"); final MockSipServletRequest outgoingCallInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteAck"); outgoingCallInviteAck.setMethod("ACK"); final States outgoingCallStates = mockery.states("outgoingCall"); outgoingCallStates.become("resped"); // outgoingCall call(byte[]). try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).isDirectlyJoined(); will(returnValue(true)); allowing(outgoingCall).unlinkDirectlyPeer(); allowing(outgoingCall).getSipInitnalRequest(); will(returnValue(outgoingCallInviteReq)); allowing(outgoingCall).getRemoteSdp(); will(returnValue(outgoingCallRespSDP)); allowing(outgoingCall).getSipSession(); will(returnValue(outgoingSession)); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); allowing(outgoingSession).getApplicationSession(); will(returnValue(outgoingAppSession)); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); oneOf(outgoingCall).call(null); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { sipcall.getJoinDelegate().doInviteResponse(outgoingCallInviteResp, outgoingCall, null); } catch (Exception e) { e.printStackTrace(); } } }); th.start(); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // release sipcall try { mockery.checking(new Expectations() { { oneOf(network).release(); oneOf(mediaSession).release(); } }); } catch (Exception ex) { ex.printStackTrace(); } // linkCall try { mockery.checking(new Expectations() { { oneOf(outgoingCall).addPeer(sipcall, JoinType.DIRECT, Direction.DUPLEX); oneOf(outgoingCall).dispatch(with(any(JoinCompleteEvent.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } // process outgoingcall response. try { mockery.checking(new Expectations() { { oneOf(session).createRequest("INVITE"); will(returnValue(sipReInviteReq)); oneOf(sipReInviteReq).setContent(outgoingCallRespSDP, "application/sdp"); oneOf(sipReInviteReq).send(); will(new MockClientDoResponseAction(sipcall, sipReInviteResp, null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sipcall response. try { mockery.checking(new Expectations() { { // outgoing call ack. oneOf(outgoingCallInviteResp).createAck(); will(returnValue(outgoingCallInviteAck)); oneOf(outgoingCallInviteAck).send(); // sipcall ack oneOf(sipReInviteResp).createAck(); will(returnValue(sipReInviteAck)); oneOf(sipReInviteAck).send(); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } return outgoingCall; } /** * */ public void testJoinAnsweredOutgoingCallDirect() { SIPOutgoingCall outgoingCall = joinAnsweredOutgoingCallDirectExpectations("testJoinAnsweredOutgoingCallDirect"); // execute try { sipcall.join(outgoingCall, JoinType.DIRECT, Direction.DUPLEX).get(); } catch (Throwable ex) { ex.printStackTrace(); fail(ex.getMessage()); } // verify result assertEquals(sipcall.getSIPCallState(), SIPCall.State.ANSWERED); assertTrue(sipcall.getMediaObject() == null); assertTrue(sipcall.getPeers()[0] == outgoingCall); mockery.assertIsSatisfied(); } private SIPOutgoingCall joinAnsweredOutgoingCallDirectExpectations(String mockObjectNamePrefix) { // prepare // mock jsr289 object. final MockSipServletResponse sipInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "sipReInviteResp"); sipInviteResp.setStatus(200); sipInviteResp.setRequest(initInviteReq); initInviteReq.setResponse(sipInviteResp); final byte[] sipInviteRespSDP = new byte[10]; sipInviteResp.setRawContent(sipInviteRespSDP); sipInviteResp.setContentType("application/sdp"); final MockSipServletRequest sipInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "sipReInviteAck"); sipInviteAck.setMethod("ACK"); // mock moho SIPOutgoingCall final SipSession outgoingCallSession = mockery.mock(SipSession.class, mockObjectNamePrefix + "outgoingCallSession"); final SipApplicationSession outgoingAppSession = mockery.mock(SipApplicationSession.class, mockObjectNamePrefix + "outgoingCallAppSession"); final SIPOutgoingCall outgoingCall = mockery.mock(SIPOutgoingCall.class, mockObjectNamePrefix + "outgoingCall"); final String outgoingCallId = "testoutgoingCall"; final byte[] originOutgoingCallRespSDP = new byte[10]; final MockSipServletRequest outgoingCallInviteReq = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteReq"); outgoingCallInviteReq.setMethod("INVITE"); outgoingCallInviteReq.setIsInitial(true); final MockSipServletResponse outgoingCallInviteResp = mockery.mock(MockSipServletResponse.class, mockObjectNamePrefix + "outgoingCallInviteResp"); outgoingCallInviteResp.setStatus(200); outgoingCallInviteResp.setReasonPhrase("OK"); outgoingCallInviteResp.setRequest(outgoingCallInviteReq); outgoingCallInviteReq.setResponse(outgoingCallInviteResp); final MockSipServletRequest outgoingCallInviteAck = mockery.mock(MockSipServletRequest.class, mockObjectNamePrefix + "outgoingCallInviteAck"); outgoingCallInviteAck.setMethod("ACK"); final States outgoingCallStates = mockery.states("outgoingCall"); outgoingCallStates.become("resped"); // outgoingCall call(byte[]). try { mockery.checking(new Expectations() { { allowing(outgoingCall).getJoinDelegate(); will(returnValue(null)); allowing(outgoingCall).startJoin(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); allowing(outgoingCall).setCallDelegate(with(any(SIPCallDelegate.class))); allowing(outgoingCall).isAnswered(); will(returnValue(false)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).isNoAnswered(); will(returnValue(true)); when(outgoingCallStates.is("outgoingCallInit")); allowing(outgoingCall).getId(); will(returnValue(outgoingCallId)); allowing(outgoingCall).isTerminated(); will(returnValue(false)); allowing(outgoingCall).isAnswered(); will(returnValue(true)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).isNoAnswered(); will(returnValue(false)); when(outgoingCallStates.is("resped")); allowing(outgoingCall).getSipSession(); will(returnValue(outgoingCallSession)); allowing(outgoingCallSession).getApplicationSession(); will(returnValue(outgoingAppSession)); allowing(outgoingCall).getParticipants(); will(returnValue(new Participant[]{})); allowing(outgoingCall).setContinueRouting(with(any(SIPCallImpl.class))); allowing(outgoingCall).getSipRequest(); will(returnValue(null)); try { mockery.checking(new Expectations() { { oneOf(sipFactory).createRequest(outgoingAppSession, "INVITE", fromAddr, toAddr); will(returnValue(initInviteReq)); } }); } catch (Exception ex) { ex.printStackTrace(); } allowing(outgoingCall).getRemoteSdp(); will(returnValue(originOutgoingCallRespSDP)); allowing(outgoingCall).isDirectlyJoined(); will(returnValue(true)); allowing(outgoingCall).unlinkDirectlyPeer(); allowing(outgoingCall).continueQueuedJoin(); allowing(outgoingCall).queuedJoinSize(); will(returnValue(0)); } }); } catch (Exception ex) { ex.printStackTrace(); } // linkCall try { mockery.checking(new Expectations() { { oneOf(outgoingCall).addPeer(sipcall, JoinType.DIRECT, Direction.DUPLEX); oneOf(outgoingCall).dispatch(with(any(JoinCompleteEvent.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } // call sipcall try { mockery.checking(new Expectations() { { oneOf(initInviteReq).send(); will(new MockClientDoResponseAction(sipcall, sipInviteResp, null)); } }); } catch (Exception ex) { ex.printStackTrace(); } // process sipcall response try { mockery.checking(new Expectations() { { oneOf(outgoingCall).call(sipInviteRespSDP); will(new Action() { @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { sipcall.getJoinDelegate().doInviteResponse(outgoingCallInviteResp, outgoingCall, null); return null; } }); } }); } catch (Exception ex) { ex.printStackTrace(); } // process outgoingCall response. try { mockery.checking(new Expectations() { { // outgoing call ack. oneOf(outgoingCallInviteResp).createAck(); will(returnValue(outgoingCallInviteAck)); oneOf(outgoingCallInviteAck).send(); // sipcall ack oneOf(sipInviteResp).createAck(); will(returnValue(sipInviteAck)); oneOf(sipInviteAck).send(); oneOf(outgoingCall).joinDone(with(any(SIPOutgoingCall.class)), with(any(JoinDelegate.class))); } }); } catch (Exception ex) { ex.printStackTrace(); } return outgoingCall; } // ========================inner class=================================== // mock jsr289 client send back ack class MockClientDoAckAction implements Action { SipServletRequest _ack; SIPCallImpl _call; public MockClientDoAckAction(SipServletRequest theAck, SIPCallImpl theCall) { _ack = theAck; _call = theCall; } @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { _call.doAck(_ack); } catch (Exception e) { e.printStackTrace(); } } }); th.start(); return null; } } // mock jsr309 send back SdpPortManagerEvent. class MockMediaServerSdpPortManagerEventAction implements Action { SdpPortManagerEvent _event; SIPCallImpl _sipCall; public MockMediaServerSdpPortManagerEventAction(SIPCallImpl sipCall, SdpPortManagerEvent theEvent) { _event = theEvent; _sipCall = sipCall; } @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { _sipCall.onEvent(_event); } }); th.start(); return null; } } // mock jsr289 client send back response class MockClientDoResponseAction implements Action { SipServletResponse _resp; Map<String, String> _headers; SIPCallImpl _sipCall; public MockClientDoResponseAction(SIPCallImpl sipCall, SipServletResponse theResp, Map<String, String> theHeaders) { _sipCall = sipCall; _resp = theResp; _headers = theHeaders; } @Override public void describeTo(Description description) { } @Override public Object invoke(Invocation invocation) throws Throwable { Thread th = new Thread(new Runnable() { @Override public void run() { try { _sipCall.doResponse(_resp, _headers); } catch (Exception e) { e.printStackTrace(); } } }); th.start(); return null; } } }