* wrapping DLT calls in a new Class because of performance, codesize and lazyness...
[profile/ivi/audiomanager.git] / AudioManagerDaemon / test / controlInterface / controlInterfaceTest.cpp
1 /**
2  * Copyright (C) 2011, BMW AG
3  *
4  * GeniviAudioMananger AudioManagerDaemon
5  *
6  * \file controlInterfaceTest.cpp
7  *
8  * \date 20-Oct-2011 3:42:04 PM
9  * \author Christian Mueller (christian.ei.mueller@bmw.de)
10  *
11  * \section License
12  * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
13  * Copyright (C) 2011, BMW AG Christian Mueller  Christian.ei.mueller@bmw.de
14  *
15  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
16  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License, version 2.1, for more details.
17  * You should have received a copy of the GNU Lesser General Public License, version 2.1, along with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
18  * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may also be applicable to programs even in cases in which the program is not a library in the technical sense.
19  * Linking AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. You may license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to license your linked modules under the GNU Lesser General Public License, version 2.1, you may use the program under the following exception.
20  * As a special exception, the copyright holders of AudioManager give you permission to combine AudioManager with software programs or libraries that are released under any license unless such a combination is not permitted by the license of such a software program or library. You may copy and distribute such a system following the terms of the GNU Lesser General Public License, version 2.1, including this special exception, for AudioManager and the licenses of the other code concerned.
21  * Note that people who make modified versions of AudioManager are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, version 2.1, gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
22  *
23  */
24
25 #include "controlInterfaceTest.h"
26 #include <algorithm>
27 #include <string>
28 #include <vector>
29 #include <set>
30 #include "DLTWrapper.h"
31
32 using namespace am;
33 using namespace testing;
34
35 controlInterfaceTest::controlInterfaceTest() :
36         pDBusWrapper((DBusWrapper*) 1), //
37         plistCommandPluginDirs(), //
38         plistRoutingPluginDirs(), //
39         pDatabaseHandler(std::string(":memory:")), //
40         pRoutingSender(plistRoutingPluginDirs), //
41         pCommandSender(plistCommandPluginDirs), //
42         pMockControlInterface(), //
43         pMockRoutingInterface(), //
44         pRoutingInterfaceBackdoor(), //
45         pCommandInterfaceBackdoor(), //
46         pControlInterfaceBackdoor(), //
47         pControlSender(std::string("")), //
48         pRouter(&pDatabaseHandler,&pControlSender), //
49         pDatabaseObserver(&pCommandSender, &pRoutingSender), //
50         pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender,&pRouter), //
51         pRoutingReceiver(&pDatabaseHandler, &pRoutingSender, &pControlSender, pDBusWrapper)
52 {
53     pDatabaseHandler.registerObserver(&pDatabaseObserver);
54     pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface);
55     pRoutingInterfaceBackdoor.injectInterface(&pRoutingSender, &pMockRoutingInterface, "mock");
56
57 }
58
59 controlInterfaceTest::~controlInterfaceTest()
60 {
61 }
62
63 void controlInterfaceTest::SetUp()
64 {
65     logInfo("RoutingSendInterface Test started");
66 }
67
68 void controlInterfaceTest::TearDown()
69 {
70 }
71
72 TEST_F(controlInterfaceTest,registerDomain)
73 {
74
75     am_Domain_s domain;
76     am_domainID_t domainID;
77     pCF.createDomain(domain);
78
79     //When we run this test, we expect the call on the control interface
80     EXPECT_CALL(pMockControlInterface,hookSystemRegisterDomain(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
81     ASSERT_EQ(E_OK, pRoutingReceiver.registerDomain(domain,domainID));
82     ASSERT_EQ(domainID, 2);
83 }
84
85 TEST_F(controlInterfaceTest,deregisterDomain)
86 {
87     am_domainID_t domainID = 34;
88
89     //When we run this test, we expect the call on the control interface
90     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterDomain(34)).WillRepeatedly(Return(E_OK));
91     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterDomain(domainID));
92 }
93
94 TEST_F(controlInterfaceTest,registerSink)
95 {
96     am_Sink_s sink;
97     am_sinkID_t sinkID;
98     pCF.createSink(sink);
99
100     //When we run this test, we expect the call on the control interface
101     EXPECT_CALL(pMockControlInterface,hookSystemRegisterSink(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
102     ASSERT_EQ(E_OK, pRoutingReceiver.registerSink(sink,sinkID));
103     ASSERT_EQ(sinkID, 2);
104 }
105
106 TEST_F(controlInterfaceTest,deregisterSink)
107 {
108     am_sinkID_t sinkID = 12;
109
110     //When we run this test, we expect the call on the control interface
111     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterSink(12)).WillRepeatedly(Return(E_OK));
112     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterSink(sinkID));
113 }
114
115 TEST_F(controlInterfaceTest,registerSource)
116 {
117     am_Source_s source;
118     am_sourceID_t sourceID;
119     pCF.createSource(source);
120
121     //When we run this test, we expect the call on the control interface
122     EXPECT_CALL(pMockControlInterface,hookSystemRegisterSource(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
123     ASSERT_EQ(E_OK, pRoutingReceiver.registerSource(source,sourceID));
124     ASSERT_EQ(sourceID, 2);
125 }
126
127 TEST_F(controlInterfaceTest,deregisterSource)
128 {
129     am_sourceID_t sourceID = 12;
130
131     //When we run this test, we expect the call on the control interface
132     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterSource(12)).WillRepeatedly(Return(E_OK));
133     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterSource(sourceID));
134 }
135
136 TEST_F(controlInterfaceTest,registerGateway)
137 {
138     am_Gateway_s gateway;
139     am_gatewayID_t gatewayID;
140     pCF.createGateway(gateway);
141
142     //When we run this test, we expect the call on the control interface
143     EXPECT_CALL(pMockControlInterface,hookSystemRegisterGateway(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
144     ASSERT_EQ(E_OK, pRoutingReceiver.registerGateway(gateway,gatewayID));
145     ASSERT_EQ(gatewayID, 2);
146 }
147
148 TEST_F(controlInterfaceTest,deregisterGateway)
149 {
150     am_gatewayID_t gatewayID = 12;
151
152     //When we run this test, we expect the call on the control interface
153     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterGateway(12)).WillRepeatedly(Return(E_OK));
154     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterGateway(gatewayID));
155 }
156
157 TEST_F(controlInterfaceTest,ackConnect)
158 {
159     am_connectionID_t connectionID;
160     am_Sink_s sink;
161     am_sinkID_t sinkID;
162     am_Domain_s domain;
163     am_domainID_t domainID;
164     std::vector<am_Connection_s> connectionList;
165     std::vector<am_Handle_s> handlesList;
166     am_Handle_s handle;
167     pCF.createSink(sink);
168     pCF.createDomain(domain);
169     domain.name = "mock";
170     domain.busname = "mock";
171     sink.sinkID = 2;
172     sink.domainID = 1;
173
174     //prepare the stage
175     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
176     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
177
178     //when asyncConnect is called, we expect a call on the routingInterface
179     EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_STEREO)).WillOnce(Return(E_OK));
180     ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_STEREO,2,2));
181
182     //The handle should have the correct type
183     ASSERT_EQ(handle.handleType, H_CONNECT);
184     ASSERT_EQ(handle.handle, 1);
185     ASSERT_EQ(connectionID, 1);
186
187     //The list of handles shall have the handle inside
188     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
189     ASSERT_EQ(handlesList[0].handle, handle.handle);
190     ASSERT_EQ(handlesList[0].handleType, handle.handleType);
191
192     //we check the list of connections - but it must be empty because the ack did not arrive yet
193     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
194     ASSERT_TRUE(connectionList.empty());
195
196     //finally we answer via the RoutingInterface and expect a call on the controlInterface
197     EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
198     pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
199
200     //the list of handles must be empty now
201     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
202     ASSERT_TRUE(handlesList.empty());
203
204     //but the connection must be in the connectionlist
205     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
206     ASSERT_TRUE(!connectionList.empty());
207
208     //no we try the same, but do expect a no_change answer directly and no call because connection already exists
209     ASSERT_EQ(E_ALREADY_EXISTS, pControlReceiver.connect(handle,connectionID,CF_STEREO,2,2));
210 }
211
212 TEST_F(controlInterfaceTest,ackDisconnect)
213 {
214     am_connectionID_t connectionID;
215     am_Sink_s sink;
216     am_sinkID_t sinkID;
217     am_Domain_s domain;
218     am_domainID_t domainID;
219     std::vector<am_Connection_s> connectionList;
220     std::vector<am_Handle_s> handlesList;
221     am_Handle_s handle;
222     pCF.createSink(sink);
223     pCF.createDomain(domain);
224     domain.name = "mock";
225     domain.busname = "mock";
226     sink.sinkID = 2;
227     sink.domainID = 1;
228
229     //prepare the stage
230     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
231     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
232
233     //now we first need to connect, we expect a call on the routing interface
234     EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_STEREO)).WillOnce(Return(E_OK));
235     ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_STEREO,2,2));
236
237     //answer with an ack to insert the connection in the database
238     EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
239     pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
240
241     //now we can start to disconnect and expect a call on the routing interface
242     EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK));
243     ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1));
244
245     //during the disconnection, the connection is still in the list!
246     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
247     ASSERT_TRUE(!connectionList.empty());
248
249     //then we fire the ack and expect a call on the controlInterface
250     EXPECT_CALL(pMockControlInterface,cbAckDisconnect(_,E_OK)).Times(1);
251     pRoutingReceiver.ackDisconnect(handle, connectionID, E_OK);
252
253     //make sure the handle is gone
254     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
255     ASSERT_TRUE(handlesList.empty());
256
257     //make sure the connection is gone
258     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
259     ASSERT_TRUE(connectionList.empty());
260
261     //Now let's try to disconnect what is not existing...
262     ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.disconnect(handle,2));
263 }
264
265 TEST_F(controlInterfaceTest,setSourceState)
266 {
267
268     am_Source_s source;
269     am_sourceID_t sourceID;
270     am_Domain_s domain;
271     am_domainID_t domainID;
272     std::vector<am_Handle_s> handlesList;
273     am_Handle_s handle;
274     am_SourceState_e state;
275     pCF.createSource(source);
276     pCF.createDomain(domain);
277     domain.name = "mock";
278     domain.busname = "mock";
279     source.sourceID = 2;
280     source.domainID = 1;
281
282     //prepare the stage
283     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
284     ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
285
286     //we set the sourcestate and expect a call on the routingInterface
287     EXPECT_CALL(pMockRoutingInterface,asyncSetSourceState(_,2,SS_PAUSED)).WillOnce(Return(E_OK));
288     ASSERT_EQ(E_OK, pControlReceiver.setSourceState(handle,source.sourceID,SS_PAUSED));
289
290     //we want our handle in the list and let the type be the right one
291     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
292     ASSERT_EQ(handlesList[0].handle, handle.handle);
293     ASSERT_EQ(handlesList[0].handleType, H_SETSOURCESTATE);
294
295     //the state must be unchanged because did not get the ack
296     ASSERT_EQ(E_OK, pDatabaseHandler.getSoureState(source.sourceID,state));
297     ASSERT_EQ(state, SS_ON);
298
299     //now we sent out the ack and expect a call on the controlInterface
300     EXPECT_CALL(pMockControlInterface,cbAckSetSourceState(_,E_OK)).Times(1);
301     pRoutingReceiver.ackSetSourceState(handle, E_OK);
302
303     //finally we need the sourcestate to be changed
304     ASSERT_EQ(E_OK, pDatabaseHandler.getSoureState(source.sourceID,state));
305     ASSERT_EQ(state, SS_PAUSED);
306
307     //make sure the handle is gone
308     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
309     ASSERT_TRUE(handlesList.empty());
310
311     //we try again but expect a no change error
312     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceState(handle,source.sourceID,SS_PAUSED));
313 }
314
315 TEST_F(controlInterfaceTest,SetSinkVolumeChange)
316 {
317     am_Sink_s sink;
318     am_sinkID_t sinkID;
319     am_Domain_s domain;
320     am_domainID_t domainID;
321     am_volume_t volume;
322     std::vector<am_Handle_s> handlesList;
323     am_Handle_s handle;
324     pCF.createSink(sink);
325     pCF.createDomain(domain);
326     domain.name = "mock";
327     domain.busname = "mock";
328     sink.sinkID = 2;
329     sink.domainID = 1;
330     sink.volume = 10;
331
332     //setup environment, we need a domain and a sink
333     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
334     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
335
336     //set the volume and expect a call on the routing interface
337     EXPECT_CALL(pMockRoutingInterface,asyncSetSinkVolume(_,2,11,RAMP_DIRECT,23)).WillOnce(Return(E_OK));
338     ASSERT_EQ(E_OK, pControlReceiver.setSinkVolume(handle,sinkID,11,RAMP_DIRECT,23));
339
340     //check the list of handles. The handle must be in there and have the right type
341     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
342     ASSERT_EQ(handlesList[0].handle, handle.handle);
343     ASSERT_EQ(handlesList[0].handleType, H_SETSINKVOLUME);
344
345     //now we read out the volume, but we expect no change because the ack did not arrive yet
346     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkVolume(sinkID,volume));
347     ASSERT_EQ(sink.volume, volume);
348
349     //lets send the answer and expect a call on the controlInterface
350     EXPECT_CALL(pMockControlInterface,cbAckSetSinkVolumeChange(_,11,E_OK)).Times(1);
351     pRoutingReceiver.ackSetSinkVolumeChange(handle, 11, E_OK);
352
353     //finally, the new value must be in the database
354     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkVolume(sinkID,volume));
355     ASSERT_EQ(11, volume);
356
357     //and the handle must be destroyed
358     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
359     ASSERT_TRUE(handlesList.empty());
360
361     //Now we try again, but the value is unchanged
362     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkVolume(handle,sinkID,11,RAMP_DIRECT,23));
363 }
364
365 TEST_F(controlInterfaceTest,ackSetSourceVolumeChange)
366 {
367     am_Source_s source;
368     am_sourceID_t sourceID;
369     am_Domain_s domain;
370     am_domainID_t domainID;
371     am_volume_t volume;
372     std::vector<am_Handle_s> handlesList;
373     am_Handle_s handle;
374     pCF.createSource(source);
375     pCF.createDomain(domain);
376     domain.name = "mock";
377     domain.busname = "mock";
378     source.sourceID = 2;
379     source.domainID = 1;
380     source.volume = 12;
381
382     //prepare the scene
383     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
384     ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
385
386     //change the sinkVolume, expect a call on the routingInterface
387     EXPECT_CALL(pMockRoutingInterface,asyncSetSourceVolume(_,2,11,RAMP_DIRECT,23)).WillOnce(Return(E_OK));
388     ASSERT_EQ(E_OK, pControlReceiver.setSourceVolume(handle,source.sourceID,11,RAMP_DIRECT,23));
389
390     //check the list of handles. The handle must be in there and have the right type
391     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
392     ASSERT_EQ(handlesList[0].handle, handle.handle);
393     ASSERT_EQ(handlesList[0].handleType, H_SETSOURCEVOLUME);
394
395     //now we read out the volume, but we expect no change because the ack did not arrive yet
396     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceVolume(sourceID,volume));
397     ASSERT_EQ(source.volume, volume);
398
399     //lets send the answer and expect a call on the controlInterface
400     EXPECT_CALL(pMockControlInterface,cbAckSetSourceVolumeChange(_,11,E_OK)).Times(1);
401     pRoutingReceiver.ackSetSourceVolumeChange(handle, 11, E_OK);
402
403     //finally, the new value must be in the database
404     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceVolume(sourceID,volume));
405     ASSERT_EQ(11, volume);
406
407     //and the handle must be destroyed
408     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
409     ASSERT_TRUE(handlesList.empty());
410
411     //Now we try again, but the value is unchanged
412     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceVolume(handle,source.sourceID,11,RAMP_DIRECT,23));
413 }
414
415 TEST_F(controlInterfaceTest,ackSetSinkSoundProperty)
416 {
417     am_Sink_s sink;
418     am_sinkID_t sinkID;
419     am_Domain_s domain;
420     am_domainID_t domainID;
421     std::vector<am_Handle_s> handlesList;
422     am_Handle_s handle;
423     am_SoundProperty_s soundProperty;
424     uint16_t oldvalue;
425     pCF.createSink(sink);
426     pCF.createDomain(domain);
427     domain.name = "mock";
428     domain.busname = "mock";
429     sink.sinkID = 2;
430     sink.domainID = 1;
431     soundProperty.type = SP_BASS;
432     soundProperty.value = 244;
433
434     //setup environment, we need a domain and a sink
435     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
436     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
437
438     //change the soundproperty, expect a call on the routinginterface
439     EXPECT_CALL(pMockRoutingInterface,asyncSetSinkSoundProperty(_,2,_)).WillOnce(Return(E_OK));
440     ASSERT_EQ(E_OK, pControlReceiver.setSinkSoundProperty(handle,sink.sinkID,soundProperty));
441
442     //check the list of handles. The handle must be in there and have the right type
443     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
444     ASSERT_EQ(handlesList[0].handle, handle.handle);
445     ASSERT_EQ(handlesList[0].handleType, H_SETSINKSOUNDPROPERTY);
446
447     //read out this property. There is no change, because the ack did not arrive yet.
448     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(2,SP_BASS,oldvalue));
449     ASSERT_EQ(sink.listSoundProperties[0].value, oldvalue);
450
451     //lets send the answer and expect a call on the controlInterface
452     EXPECT_CALL(pMockControlInterface,cbAckSetSinkSoundProperty(_,E_OK)).Times(1);
453     pRoutingReceiver.ackSetSinkSoundProperty(handle, E_OK);
454
455     //finally, the new value must be in the database
456     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(sinkID,SP_BASS,oldvalue));
457     ASSERT_EQ(soundProperty.value, oldvalue);
458
459     //and the handle must be destroyed
460     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
461     ASSERT_TRUE(handlesList.empty());
462
463     //Now we try again, but the value is unchanged
464     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkSoundProperty(handle,sink.sinkID,soundProperty));
465 }
466
467 TEST_F(controlInterfaceTest,ackSetSourceSoundProperty)
468 {
469     am_Source_s source;
470     am_sourceID_t sourceID;
471     am_Domain_s domain;
472     am_domainID_t domainID;
473     std::vector<am_Handle_s> handlesList;
474     am_Handle_s handle;
475     am_SoundProperty_s soundProperty;
476     uint16_t oldvalue;
477     pCF.createSource(source);
478     pCF.createDomain(domain);
479     domain.name = "mock";
480     domain.busname = "mock";
481     source.sourceID = 2;
482     source.domainID = 1;
483     soundProperty.type = SP_BASS;
484     soundProperty.value = 244;
485
486     //prepare the scene
487     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
488     ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
489
490     //we trigger the change and wait for a call on the routinginterface
491     EXPECT_CALL(pMockRoutingInterface,asyncSetSourceSoundProperty(_,2,_)).WillOnce(Return(E_OK));
492     ASSERT_EQ(E_OK, pControlReceiver.setSourceSoundProperty(handle,source.sourceID,soundProperty));
493
494     //check the list of handles. The handle must be in there and have the right type
495     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
496     ASSERT_EQ(handlesList[0].handle, handle.handle);
497     ASSERT_EQ(handlesList[0].handleType, H_SETSOURCESOUNDPROPERTY);
498
499     //read out this property. There is no change, because the ack did not arrive yet.
500     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(2,SP_BASS,oldvalue));
501     ASSERT_EQ(source.listSoundProperties[0].value, oldvalue);
502
503     //lets send the answer and expect a call on the controlInterface
504     EXPECT_CALL(pMockControlInterface,cbAckSetSourceSoundProperty(_,E_OK)).Times(1);
505     pRoutingReceiver.ackSetSourceSoundProperty(handle, E_OK);
506
507     //finally, the new value must be in the database
508     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(sourceID,SP_BASS,oldvalue));
509     ASSERT_EQ(soundProperty.value, oldvalue);
510
511     //and the handle must be destroyed
512     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
513     ASSERT_TRUE(handlesList.empty());
514
515     //Now we try again, but the value is unchanged
516     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceSoundProperty(handle,source.sourceID,soundProperty));
517 }
518
519 TEST_F(controlInterfaceTest,crossFading)
520 {
521     //todo: implement crossfading test
522 }
523
524 int main(int argc, char **argv)
525 {
526     ::testing::InitGoogleTest(&argc, argv);
527     return RUN_ALL_TESTS();
528 }
529