From 215e8a72dc81e8a86dd5b3a8ca40fd2c7c6a0b9c Mon Sep 17 00:00:00 2001 From: christian linke Date: Thu, 6 Dec 2012 13:31:52 +0100 Subject: fix [OSS BUG 23] - connection removed if routing returns !=E_OK. added test case to test this as well Signed-off-by: christian linke --- AudioManagerDaemon/include/CAmRoutingSender.h | 1 + AudioManagerDaemon/src/CAmRoutingReceiver.cpp | 17 ++++++ AudioManagerDaemon/src/CAmRoutingSender.cpp | 1 - .../CAmControlInterfaceTest.cpp | 63 ++++++++++++++++++++++ .../CAmRoutingInterfaceTest.cpp | 1 + 5 files changed, 82 insertions(+), 1 deletion(-) diff --git a/AudioManagerDaemon/include/CAmRoutingSender.h b/AudioManagerDaemon/include/CAmRoutingSender.h index 499d196..5f58689 100644 --- a/AudioManagerDaemon/include/CAmRoutingSender.h +++ b/AudioManagerDaemon/include/CAmRoutingSender.h @@ -52,6 +52,7 @@ public: am_Error_e removeSourceLookup(const am_sourceID_t sourceID); am_Error_e removeSinkLookup(const am_sinkID_t sinkID); am_Error_e removeCrossfaderLookup(const am_crossfaderID_t crossfaderID); + am_Error_e removeConnectionLookup(const am_connectionID_t connectionID); am_Error_e startupInterfaces(CAmRoutingReceiver* iRoutingReceiver); void setRoutingReady(); diff --git a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp index 7e14e33..f0821a9 100644 --- a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp +++ b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp @@ -92,6 +92,10 @@ void CAmRoutingReceiver::ackDisconnect(const am_Handle_s handle, const am_connec if (error == E_OK) { mpDatabaseHandler->removeConnection(connectionID); + if (mpRoutingSender->removeConnectionLookup(connectionID)!=E_OK) + { + logError("CAmRoutingReceiver::ackDisconnect could not remove connectionId from lookup"); + } } mpControlSender->cbAckDisconnect(handle, error); } @@ -378,4 +382,17 @@ void am::CAmRoutingReceiver::waitOnRundown(bool rundown) { mWaitRundown = rundown; } + +am_Error_e CAmRoutingSender::removeConnectionLookup(const am_connectionID_t connectionID) +{ + ConnectionInterfaceMap::iterator iter = mMapConnectionInterface.begin(); + iter = mMapConnectionInterface.find(connectionID); + if (iter != mMapConnectionInterface.end()) + { + mMapConnectionInterface.erase(iter); + return (E_OK); + } + return (E_UNKNOWN); +} + } diff --git a/AudioManagerDaemon/src/CAmRoutingSender.cpp b/AudioManagerDaemon/src/CAmRoutingSender.cpp index 05078a9..f45f918 100644 --- a/AudioManagerDaemon/src/CAmRoutingSender.cpp +++ b/AudioManagerDaemon/src/CAmRoutingSender.cpp @@ -214,7 +214,6 @@ am_Error_e CAmRoutingSender::asyncDisconnect(am_Handle_s& handle, const am_conne handle = createHandle(handleData, H_DISCONNECT); mMapHandleInterface.insert(std::make_pair(+ handle.handle, iter->second)); am_Error_e returnVal = iter->second->asyncDisconnect(handle, connectionID); - mMapConnectionInterface.erase(iter); return (returnVal); } diff --git a/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp b/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp index f056819..c4f71e1 100644 --- a/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp +++ b/AudioManagerDaemon/test/AmControlInterfaceTest/CAmControlInterfaceTest.cpp @@ -28,6 +28,8 @@ using namespace am; using namespace testing; +DLT_DECLARE_CONTEXT(AudioManager) + CAmControlInterfaceTest::CAmControlInterfaceTest() : pSocketHandler(), // pDBusWrapper((CAmDbusWrapper*) 1), // @@ -47,6 +49,9 @@ CAmControlInterfaceTest::CAmControlInterfaceTest() : pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender, &pSocketHandler, &pRouter), // pRoutingReceiver(&pDatabaseHandler, &pRoutingSender, &pControlSender, &pSocketHandler, pDBusWrapper) { + CAmDltWrapper::instance(0)->registerApp("AudioManagerDeamon", "AudioManagerDeamon"); + CAmDltWrapper::instance()->registerContext(AudioManager, "Main", "Main Context"); + logInfo("The Audiomanager is started"); pDatabaseHandler.registerObserver(&pDatabaseObserver); pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface); pRoutingInterfaceBackdoor.injectInterface(&pRoutingSender, &pMockRoutingInterface, "mock"); @@ -259,6 +264,64 @@ TEST_F(CAmControlInterfaceTest,ackDisconnect) ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.disconnect(handle,2)); } +TEST_F(CAmControlInterfaceTest,ackDisconnectFailAndRetry) +{ + logInfo("ackDisconnectFailAndRetry test started"); + am_connectionID_t connectionID; + am_Sink_s sink; + am_sinkID_t sinkID; + am_Domain_s domain; + am_domainID_t domainID; + std::vector connectionList; + std::vector handlesList; + am_Handle_s handle; + pCF.createSink(sink); + pCF.createDomain(domain); + domain.name = "mock"; + domain.busname = "mock"; + sink.sinkID = 2; + sink.domainID = 1; + + //prepare the stage + ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID)); + ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID)); + + //now we first need to connect, we expect a call on the routing interface + EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_GENIVI_STEREO)).WillOnce(Return(E_OK)); + ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_GENIVI_STEREO,2,2)); + + //answer with an ack to insert the connection in the database + EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1); + pRoutingReceiver.ackConnect(handle, connectionID, E_OK); + + //now we can start to disconnect and expect a call on the routing interface + EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK)); + ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1)); + + //during the disconnection, the connection is still in the list! + ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList)); + ASSERT_TRUE(!connectionList.empty()); + + //then we fire the ack and expect a call on the controlInterface + EXPECT_CALL(pMockControlInterface,cbAckDisconnect(_,E_NON_EXISTENT)).Times(1); + pRoutingReceiver.ackDisconnect(handle, connectionID, E_NON_EXISTENT); + + //make sure the handle is gone + ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList)); + ASSERT_TRUE(handlesList.empty()); + + //make sure the connection is still there + ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList)); + ASSERT_FALSE(connectionList.empty()); + + ASSERT_TRUE(pDatabaseHandler.existConnectionID(1)); + + //Now let's try to disconnect now + EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK)); + ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1)); + logInfo("ackDisconnectFailAndRetry test finished"); +} + TEST_F(CAmControlInterfaceTest,setSourceState) { diff --git a/AudioManagerDaemon/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp b/AudioManagerDaemon/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp index fe3694b..47181b3 100644 --- a/AudioManagerDaemon/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp +++ b/AudioManagerDaemon/test/AmRoutingInterfaceTest/CAmRoutingInterfaceTest.cpp @@ -399,6 +399,7 @@ TEST_F(CAmRoutingInterfaceTest,disconnect) ASSERT_TRUE(listHandles[1].handleType==handle.handleType); } + TEST_F(CAmRoutingInterfaceTest,nothingTodisconnect) { am_Handle_s handle; -- cgit v1.2.1