c22f175070e4064ae100c401a68331c70bb9a11c
[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
31 using namespace am;
32 using namespace testing;
33
34 DLT_DECLARE_CONTEXT(DLT_CONTEXT)
35
36 controlInterfaceTest::controlInterfaceTest() :
37         pDBusWrapper((DBusWrapper*) 1), //
38         plistCommandPluginDirs(), //
39         plistRoutingPluginDirs(), //
40         pDatabaseHandler(std::string(":memory:")), //
41         pRoutingSender(plistRoutingPluginDirs), //
42         pCommandSender(plistCommandPluginDirs), //
43         pMockControlInterface(), //
44         pMockRoutingInterface(), //
45         pRoutingInterfaceBackdoor(), //
46         pCommandInterfaceBackdoor(), //
47         pControlInterfaceBackdoor(), //
48         pControlSender(std::string("")), //
49         pRouter(&pDatabaseHandler,&pControlSender), //
50         pDatabaseObserver(&pCommandSender, &pRoutingSender), //
51         pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender,&pRouter), //
52         pRoutingReceiver(&pDatabaseHandler, &pRoutingSender, &pControlSender, pDBusWrapper)
53 {
54     pDatabaseHandler.registerObserver(&pDatabaseObserver);
55     pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface);
56     pRoutingInterfaceBackdoor.injectInterface(&pRoutingSender, &pMockRoutingInterface, "mock");
57
58 }
59
60 controlInterfaceTest::~controlInterfaceTest()
61 {
62 }
63
64 void controlInterfaceTest::SetUp()
65 {
66     DLT_REGISTER_APP("Rtest", "RoutingInterfacetest");
67     DLT_REGISTER_CONTEXT(DLT_CONTEXT, "Main", "Main Context");
68     DLT_LOG(DLT_CONTEXT, DLT_LOG_INFO, DLT_STRING("RoutingSendInterface Test started "));
69
70 }
71
72 void controlInterfaceTest::TearDown()
73 {
74     DLT_UNREGISTER_CONTEXT(DLT_CONTEXT);
75 }
76
77 TEST_F(controlInterfaceTest,registerDomain)
78 {
79
80     am_Domain_s domain;
81     am_domainID_t domainID;
82     pCF.createDomain(domain);
83
84     //When we run this test, we expect the call on the control interface
85     EXPECT_CALL(pMockControlInterface,hookSystemRegisterDomain(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
86     ASSERT_EQ(E_OK, pRoutingReceiver.registerDomain(domain,domainID));
87     ASSERT_EQ(domainID, 2);
88 }
89
90 TEST_F(controlInterfaceTest,deregisterDomain)
91 {
92     am_domainID_t domainID = 34;
93
94     //When we run this test, we expect the call on the control interface
95     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterDomain(34)).WillRepeatedly(Return(E_OK));
96     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterDomain(domainID));
97 }
98
99 TEST_F(controlInterfaceTest,registerSink)
100 {
101     am_Sink_s sink;
102     am_sinkID_t sinkID;
103     pCF.createSink(sink);
104
105     //When we run this test, we expect the call on the control interface
106     EXPECT_CALL(pMockControlInterface,hookSystemRegisterSink(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
107     ASSERT_EQ(E_OK, pRoutingReceiver.registerSink(sink,sinkID));
108     ASSERT_EQ(sinkID, 2);
109 }
110
111 TEST_F(controlInterfaceTest,deregisterSink)
112 {
113     am_sinkID_t sinkID = 12;
114
115     //When we run this test, we expect the call on the control interface
116     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterSink(12)).WillRepeatedly(Return(E_OK));
117     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterSink(sinkID));
118 }
119
120 TEST_F(controlInterfaceTest,registerSource)
121 {
122     am_Source_s source;
123     am_sourceID_t sourceID;
124     pCF.createSource(source);
125
126     //When we run this test, we expect the call on the control interface
127     EXPECT_CALL(pMockControlInterface,hookSystemRegisterSource(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
128     ASSERT_EQ(E_OK, pRoutingReceiver.registerSource(source,sourceID));
129     ASSERT_EQ(sourceID, 2);
130 }
131
132 TEST_F(controlInterfaceTest,deregisterSource)
133 {
134     am_sourceID_t sourceID = 12;
135
136     //When we run this test, we expect the call on the control interface
137     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterSource(12)).WillRepeatedly(Return(E_OK));
138     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterSource(sourceID));
139 }
140
141 TEST_F(controlInterfaceTest,registerGateway)
142 {
143     am_Gateway_s gateway;
144     am_gatewayID_t gatewayID;
145     pCF.createGateway(gateway);
146
147     //When we run this test, we expect the call on the control interface
148     EXPECT_CALL(pMockControlInterface,hookSystemRegisterGateway(_,_)).WillRepeatedly(DoAll(SetArgReferee<1>(2), Return(E_OK)));
149     ASSERT_EQ(E_OK, pRoutingReceiver.registerGateway(gateway,gatewayID));
150     ASSERT_EQ(gatewayID, 2);
151 }
152
153 TEST_F(controlInterfaceTest,deregisterGateway)
154 {
155     am_gatewayID_t gatewayID = 12;
156
157     //When we run this test, we expect the call on the control interface
158     EXPECT_CALL(pMockControlInterface,hookSystemDeregisterGateway(12)).WillRepeatedly(Return(E_OK));
159     ASSERT_EQ(E_OK, pRoutingReceiver.deregisterGateway(gatewayID));
160 }
161
162 TEST_F(controlInterfaceTest,ackConnect)
163 {
164     am_connectionID_t connectionID;
165     am_Sink_s sink;
166     am_sinkID_t sinkID;
167     am_Domain_s domain;
168     am_domainID_t domainID;
169     std::vector<am_Connection_s> connectionList;
170     std::vector<am_Handle_s> handlesList;
171     am_Handle_s handle;
172     pCF.createSink(sink);
173     pCF.createDomain(domain);
174     domain.name = "mock";
175     domain.busname = "mock";
176     sink.sinkID = 2;
177     sink.domainID = 1;
178
179     //prepare the stage
180     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
181     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
182
183     //when asyncConnect is called, we expect a call on the routingInterface
184     EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_STEREO)).WillOnce(Return(E_OK));
185     ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_STEREO,2,2));
186
187     //The handle should have the correct type
188     ASSERT_EQ(handle.handleType, H_CONNECT);
189     ASSERT_EQ(handle.handle, 1);
190     ASSERT_EQ(connectionID, 1);
191
192     //The list of handles shall have the handle inside
193     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
194     ASSERT_EQ(handlesList[0].handle, handle.handle);
195     ASSERT_EQ(handlesList[0].handleType, handle.handleType);
196
197     //we check the list of connections - but it must be empty because the ack did not arrive yet
198     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
199     ASSERT_TRUE(connectionList.empty());
200
201     //finally we answer via the RoutingInterface and expect a call on the controlInterface
202     EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
203     pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
204
205     //the list of handles must be empty now
206     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
207     ASSERT_TRUE(handlesList.empty());
208
209     //but the connection must be in the connectionlist
210     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
211     ASSERT_TRUE(!connectionList.empty());
212
213     //no we try the same, but do expect a no_change answer directly and no call because connection already exists
214     ASSERT_EQ(E_ALREADY_EXISTS, pControlReceiver.connect(handle,connectionID,CF_STEREO,2,2));
215 }
216
217 TEST_F(controlInterfaceTest,ackDisconnect)
218 {
219     am_connectionID_t connectionID;
220     am_Sink_s sink;
221     am_sinkID_t sinkID;
222     am_Domain_s domain;
223     am_domainID_t domainID;
224     std::vector<am_Connection_s> connectionList;
225     std::vector<am_Handle_s> handlesList;
226     am_Handle_s handle;
227     pCF.createSink(sink);
228     pCF.createDomain(domain);
229     domain.name = "mock";
230     domain.busname = "mock";
231     sink.sinkID = 2;
232     sink.domainID = 1;
233
234     //prepare the stage
235     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
236     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
237
238     //now we first need to connect, we expect a call on the routing interface
239     EXPECT_CALL(pMockRoutingInterface,asyncConnect(_,1,2,2,CF_STEREO)).WillOnce(Return(E_OK));
240     ASSERT_EQ(E_OK, pControlReceiver.connect(handle,connectionID,CF_STEREO,2,2));
241
242     //answer with an ack to insert the connection in the database
243     EXPECT_CALL(pMockControlInterface,cbAckConnect(_,E_OK)).Times(1);
244     pRoutingReceiver.ackConnect(handle, connectionID, E_OK);
245
246     //now we can start to disconnect and expect a call on the routing interface
247     EXPECT_CALL(pMockRoutingInterface,asyncDisconnect(_,1)).WillOnce(Return(E_OK));
248     ASSERT_EQ(E_OK, pControlReceiver.disconnect(handle,1));
249
250     //during the disconnection, the connection is still in the list!
251     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
252     ASSERT_TRUE(!connectionList.empty());
253
254     //then we fire the ack and expect a call on the controlInterface
255     EXPECT_CALL(pMockControlInterface,cbAckDisconnect(_,E_OK)).Times(1);
256     pRoutingReceiver.ackDisconnect(handle, connectionID, E_OK);
257
258     //make sure the handle is gone
259     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
260     ASSERT_TRUE(handlesList.empty());
261
262     //make sure the connection is gone
263     ASSERT_EQ(E_OK, pDatabaseHandler.getListConnections(connectionList));
264     ASSERT_TRUE(connectionList.empty());
265
266     //Now let's try to disconnect what is not existing...
267     ASSERT_EQ(E_NON_EXISTENT, pControlReceiver.disconnect(handle,2));
268 }
269
270 TEST_F(controlInterfaceTest,setSourceState)
271 {
272
273     am_Source_s source;
274     am_sourceID_t sourceID;
275     am_Domain_s domain;
276     am_domainID_t domainID;
277     std::vector<am_Handle_s> handlesList;
278     am_Handle_s handle;
279     am_SourceState_e state;
280     pCF.createSource(source);
281     pCF.createDomain(domain);
282     domain.name = "mock";
283     domain.busname = "mock";
284     source.sourceID = 2;
285     source.domainID = 1;
286
287     //prepare the stage
288     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
289     ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
290
291     //we set the sourcestate and expect a call on the routingInterface
292     EXPECT_CALL(pMockRoutingInterface,asyncSetSourceState(_,2,SS_PAUSED)).WillOnce(Return(E_OK));
293     ASSERT_EQ(E_OK, pControlReceiver.setSourceState(handle,source.sourceID,SS_PAUSED));
294
295     //we want our handle in the list and let the type be the right one
296     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
297     ASSERT_EQ(handlesList[0].handle, handle.handle);
298     ASSERT_EQ(handlesList[0].handleType, H_SETSOURCESTATE);
299
300     //the state must be unchanged because did not get the ack
301     ASSERT_EQ(E_OK, pDatabaseHandler.getSoureState(source.sourceID,state));
302     ASSERT_EQ(state, SS_ON);
303
304     //now we sent out the ack and expect a call on the controlInterface
305     EXPECT_CALL(pMockControlInterface,cbAckSetSourceState(_,E_OK)).Times(1);
306     pRoutingReceiver.ackSetSourceState(handle, E_OK);
307
308     //finally we need the sourcestate to be changed
309     ASSERT_EQ(E_OK, pDatabaseHandler.getSoureState(source.sourceID,state));
310     ASSERT_EQ(state, SS_PAUSED);
311
312     //make sure the handle is gone
313     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
314     ASSERT_TRUE(handlesList.empty());
315
316     //we try again but expect a no change error
317     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceState(handle,source.sourceID,SS_PAUSED));
318 }
319
320 TEST_F(controlInterfaceTest,SetSinkVolumeChange)
321 {
322     am_Sink_s sink;
323     am_sinkID_t sinkID;
324     am_Domain_s domain;
325     am_domainID_t domainID;
326     am_volume_t volume;
327     std::vector<am_Handle_s> handlesList;
328     am_Handle_s handle;
329     pCF.createSink(sink);
330     pCF.createDomain(domain);
331     domain.name = "mock";
332     domain.busname = "mock";
333     sink.sinkID = 2;
334     sink.domainID = 1;
335     sink.volume = 10;
336
337     //setup environment, we need a domain and a sink
338     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
339     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
340
341     //set the volume and expect a call on the routing interface
342     EXPECT_CALL(pMockRoutingInterface,asyncSetSinkVolume(_,2,11,RAMP_DIRECT,23)).WillOnce(Return(E_OK));
343     ASSERT_EQ(E_OK, pControlReceiver.setSinkVolume(handle,sinkID,11,RAMP_DIRECT,23));
344
345     //check the list of handles. The handle must be in there and have the right type
346     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
347     ASSERT_EQ(handlesList[0].handle, handle.handle);
348     ASSERT_EQ(handlesList[0].handleType, H_SETSINKVOLUME);
349
350     //now we read out the volume, but we expect no change because the ack did not arrive yet
351     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkVolume(sinkID,volume));
352     ASSERT_EQ(sink.volume, volume);
353
354     //lets send the answer and expect a call on the controlInterface
355     EXPECT_CALL(pMockControlInterface,cbAckSetSinkVolumeChange(_,11,E_OK)).Times(1);
356     pRoutingReceiver.ackSetSinkVolumeChange(handle, 11, E_OK);
357
358     //finally, the new value must be in the database
359     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkVolume(sinkID,volume));
360     ASSERT_EQ(11, volume);
361
362     //and the handle must be destroyed
363     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
364     ASSERT_TRUE(handlesList.empty());
365
366     //Now we try again, but the value is unchanged
367     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkVolume(handle,sinkID,11,RAMP_DIRECT,23));
368 }
369
370 TEST_F(controlInterfaceTest,ackSetSourceVolumeChange)
371 {
372     am_Source_s source;
373     am_sourceID_t sourceID;
374     am_Domain_s domain;
375     am_domainID_t domainID;
376     am_volume_t volume;
377     std::vector<am_Handle_s> handlesList;
378     am_Handle_s handle;
379     pCF.createSource(source);
380     pCF.createDomain(domain);
381     domain.name = "mock";
382     domain.busname = "mock";
383     source.sourceID = 2;
384     source.domainID = 1;
385     source.volume = 12;
386
387     //prepare the scene
388     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
389     ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
390
391     //change the sinkVolume, expect a call on the routingInterface
392     EXPECT_CALL(pMockRoutingInterface,asyncSetSourceVolume(_,2,11,RAMP_DIRECT,23)).WillOnce(Return(E_OK));
393     ASSERT_EQ(E_OK, pControlReceiver.setSourceVolume(handle,source.sourceID,11,RAMP_DIRECT,23));
394
395     //check the list of handles. The handle must be in there and have the right type
396     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
397     ASSERT_EQ(handlesList[0].handle, handle.handle);
398     ASSERT_EQ(handlesList[0].handleType, H_SETSOURCEVOLUME);
399
400     //now we read out the volume, but we expect no change because the ack did not arrive yet
401     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceVolume(sourceID,volume));
402     ASSERT_EQ(source.volume, volume);
403
404     //lets send the answer and expect a call on the controlInterface
405     EXPECT_CALL(pMockControlInterface,cbAckSetSourceVolumeChange(_,11,E_OK)).Times(1);
406     pRoutingReceiver.ackSetSourceVolumeChange(handle, 11, E_OK);
407
408     //finally, the new value must be in the database
409     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceVolume(sourceID,volume));
410     ASSERT_EQ(11, volume);
411
412     //and the handle must be destroyed
413     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
414     ASSERT_TRUE(handlesList.empty());
415
416     //Now we try again, but the value is unchanged
417     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceVolume(handle,source.sourceID,11,RAMP_DIRECT,23));
418 }
419
420 TEST_F(controlInterfaceTest,ackSetSinkSoundProperty)
421 {
422     am_Sink_s sink;
423     am_sinkID_t sinkID;
424     am_Domain_s domain;
425     am_domainID_t domainID;
426     std::vector<am_Handle_s> handlesList;
427     am_Handle_s handle;
428     am_SoundProperty_s soundProperty;
429     uint16_t oldvalue;
430     pCF.createSink(sink);
431     pCF.createDomain(domain);
432     domain.name = "mock";
433     domain.busname = "mock";
434     sink.sinkID = 2;
435     sink.domainID = 1;
436     soundProperty.type = SP_BASS;
437     soundProperty.value = 244;
438
439     //setup environment, we need a domain and a sink
440     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
441     ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
442
443     //change the soundproperty, expect a call on the routinginterface
444     EXPECT_CALL(pMockRoutingInterface,asyncSetSinkSoundProperty(_,2,_)).WillOnce(Return(E_OK));
445     ASSERT_EQ(E_OK, pControlReceiver.setSinkSoundProperty(handle,sink.sinkID,soundProperty));
446
447     //check the list of handles. The handle must be in there and have the right type
448     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
449     ASSERT_EQ(handlesList[0].handle, handle.handle);
450     ASSERT_EQ(handlesList[0].handleType, H_SETSINKSOUNDPROPERTY);
451
452     //read out this property. There is no change, because the ack did not arrive yet.
453     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(2,SP_BASS,oldvalue));
454     ASSERT_EQ(sink.listSoundProperties[0].value, oldvalue);
455
456     //lets send the answer and expect a call on the controlInterface
457     EXPECT_CALL(pMockControlInterface,cbAckSetSinkSoundProperty(_,E_OK)).Times(1);
458     pRoutingReceiver.ackSetSinkSoundProperty(handle, E_OK);
459
460     //finally, the new value must be in the database
461     ASSERT_EQ(E_OK, pDatabaseHandler.getSinkSoundPropertyValue(sinkID,SP_BASS,oldvalue));
462     ASSERT_EQ(soundProperty.value, oldvalue);
463
464     //and the handle must be destroyed
465     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
466     ASSERT_TRUE(handlesList.empty());
467
468     //Now we try again, but the value is unchanged
469     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSinkSoundProperty(handle,sink.sinkID,soundProperty));
470 }
471
472 TEST_F(controlInterfaceTest,ackSetSourceSoundProperty)
473 {
474     am_Source_s source;
475     am_sourceID_t sourceID;
476     am_Domain_s domain;
477     am_domainID_t domainID;
478     std::vector<am_Handle_s> handlesList;
479     am_Handle_s handle;
480     am_SoundProperty_s soundProperty;
481     uint16_t oldvalue;
482     pCF.createSource(source);
483     pCF.createDomain(domain);
484     domain.name = "mock";
485     domain.busname = "mock";
486     source.sourceID = 2;
487     source.domainID = 1;
488     soundProperty.type = SP_BASS;
489     soundProperty.value = 244;
490
491     //prepare the scene
492     ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain,domainID));
493     ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
494
495     //we trigger the change and wait for a call on the routinginterface
496     EXPECT_CALL(pMockRoutingInterface,asyncSetSourceSoundProperty(_,2,_)).WillOnce(Return(E_OK));
497     ASSERT_EQ(E_OK, pControlReceiver.setSourceSoundProperty(handle,source.sourceID,soundProperty));
498
499     //check the list of handles. The handle must be in there and have the right type
500     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
501     ASSERT_EQ(handlesList[0].handle, handle.handle);
502     ASSERT_EQ(handlesList[0].handleType, H_SETSOURCESOUNDPROPERTY);
503
504     //read out this property. There is no change, because the ack did not arrive yet.
505     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(2,SP_BASS,oldvalue));
506     ASSERT_EQ(source.listSoundProperties[0].value, oldvalue);
507
508     //lets send the answer and expect a call on the controlInterface
509     EXPECT_CALL(pMockControlInterface,cbAckSetSourceSoundProperty(_,E_OK)).Times(1);
510     pRoutingReceiver.ackSetSourceSoundProperty(handle, E_OK);
511
512     //finally, the new value must be in the database
513     ASSERT_EQ(E_OK, pDatabaseHandler.getSourceSoundPropertyValue(sourceID,SP_BASS,oldvalue));
514     ASSERT_EQ(soundProperty.value, oldvalue);
515
516     //and the handle must be destroyed
517     ASSERT_EQ(E_OK, pControlReceiver.getListHandles(handlesList));
518     ASSERT_TRUE(handlesList.empty());
519
520     //Now we try again, but the value is unchanged
521     ASSERT_EQ(E_NO_CHANGE, pControlReceiver.setSourceSoundProperty(handle,source.sourceID,soundProperty));
522 }
523
524 TEST_F(controlInterfaceTest,crossFading)
525 {
526     //todo: implement crossfading test
527 }
528
529 int main(int argc, char **argv)
530 {
531     ::testing::InitGoogleTest(&argc, argv);
532     return RUN_ALL_TESTS();
533 }
534