2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file test_ic_delegate.cpp
18 * @author Pawel Sikorski (p.sikorski@samsung.com)
19 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
21 * @brief This file is the implementation file of fast delegate tests.
23 #include <dpl/test/test_runner.h>
24 #include <dpl/application.h>
25 #include <dpl/event/controller.h>
26 #include <dpl/log/log.h>
27 #include <dpl/fast_delegate.h>
28 #include <dpl/event/inter_context_delegate.h>
29 #include <dpl/thread.h>
30 #include <dpl/waitable_event.h>
31 #include <dpl/assert.h>
32 #include <dpl/mutex.h>
33 #include <dpl/type_list.h>
35 RUNNER_TEST_GROUP_INIT(DPL)
37 const int IntVal = 123;
38 const std::string StringVal = "someString";
40 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
41 typedef DPL::Event::ICDelegate<int> GetIntDlgType;
42 typedef DPL::Event::ICDelegate<int, std::string> GetIntAndStringDlgType;
43 DECLARE_GENERIC_EVENT_1(GetNothingEvent, GetNothingDlpType)
44 DECLARE_GENERIC_EVENT_1(GetIntEvent, GetIntDlgType)
45 DECLARE_GENERIC_EVENT_1(GetIntAndStringEvent, GetIntAndStringDlgType)
47 class ICTestController :
48 public DPL::Event::Controller<DPL::TypeListDecl<GetNothingEvent,
50 GetIntAndStringEvent>::Type>
53 ICTestController() { }
56 virtual void OnEventReceived(const GetNothingEvent& event)
58 event.GetArg0() (); //calling intercontext delegate
60 virtual void OnEventReceived(const GetIntEvent& event)
62 event.GetArg0() (IntVal); //calling intercontext delegate
65 virtual void OnEventReceived(const GetIntAndStringEvent& event)
67 event.GetArg0() (IntVal, StringVal); //calling intercontext delegate
74 m_correctThread0(false),
75 m_correctThread1(false),
76 m_correctThread2(false),
82 void TestEventsPassed()
84 RUNNER_ASSERT(m_correctThread0);
85 RUNNER_ASSERT(m_correctThread1);
86 RUNNER_ASSERT(m_int == IntVal);
87 RUNNER_ASSERT(m_correctThread2);
88 RUNNER_ASSERT(m_int2 == IntVal);
89 RUNNER_ASSERT(m_string == StringVal);
92 void TestEventsDidNotPass()
94 RUNNER_ASSERT(!m_correctThread0);
95 RUNNER_ASSERT(!m_correctThread1);
96 RUNNER_ASSERT(m_int == -1);
97 RUNNER_ASSERT(!m_correctThread2);
98 RUNNER_ASSERT(m_int2 == -1);
99 RUNNER_ASSERT(m_string == "");
102 bool m_correctThread0;
103 bool m_correctThread1;
104 bool m_correctThread2;
107 std::string m_string;
110 class TestContextFreeClass :
111 protected DPL::Thread,
112 public DPL::Event::ICDelegateSupport<TestContextFreeClass>
115 TestContextFreeClass(ICTestController* controller, TestResult* result) :
117 m_testResult(result),
118 m_controller(controller)
120 LogDebug("Context thread id = " << this);
125 LogDebug("Running Context Free thread");
131 LogDebug("Exiting Context Free thread");
137 LogDebug("Waiting for thread");
138 DPL::WaitForSingleHandle(m_waitable.GetHandle());
144 LogDebug("Received nothing in thread = " << GetCurrentThread());
145 m_testResult->m_correctThread0 = (GetCurrentThread() == this);
148 void OnIntReceive(int val)
150 LogDebug("Received int in thread = " << GetCurrentThread());
151 m_testResult->m_correctThread1 = (GetCurrentThread() == this);
152 m_testResult->m_int = val;
155 void OnIntAndStringReceive(int val, std::string stringval)
157 LogDebug("Received int and string in thread = " << GetCurrentThread());
158 m_testResult->m_correctThread2 = (GetCurrentThread() == this);
159 m_testResult->m_int2 = val;
160 m_testResult->m_string = stringval;
164 virtual int ThreadEntry()
166 GetNothingEvent getNothingEvent(
168 &TestContextFreeClass::OnNothing));
169 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
173 GetIntEvent getIntEvent(
175 &TestContextFreeClass::OnIntReceive));
176 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
180 GetIntAndStringEvent getIntAndStringEvent(
182 &TestContextFreeClass::OnIntAndStringReceive));
183 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
185 getIntAndStringEvent);
187 return Thread::ThreadEntry();
191 TestResult* m_testResult;
192 DPL::WaitableEvent m_waitable;
193 ICTestController* m_controller;
198 Description: checks if delegetes are correctly called
199 Expected: delegates should be called from right context
201 RUNNER_TEST(ICDelegate_0)
205 LogDebug("Controller thread id = " << &thread);
207 ICTestController testController;
208 testController.Touch();
209 testController.SwitchToThread(&thread);
212 TestContextFreeClass* contextFree =
213 new TestContextFreeClass(&testController, &result);
214 result.TestEventsDidNotPass();
224 result.TestEventsPassed();
229 Description: checks if delegetes are correctly called
230 Expected: delegates should be called from right context
232 RUNNER_TEST(ICDelegate_1)
235 LogDebug("Controller thread id = " << &thread);
237 ICTestController testController;
238 testController.Touch();
239 testController.SwitchToThread(&thread);
242 TestContextFreeClass* contextFree =
243 new TestContextFreeClass(&testController, &result);
244 result.TestEventsDidNotPass();
248 delete contextFree; //deleting Delegates before actual Events are worked out
252 result.TestEventsDidNotPass();
255 class TestContextFree;
256 class TestRunnerInThread;
259 const int ControllersPerThread = 40;
260 const int ContextFreePerThread = 180;
261 const int TestsPerController = 110;
262 const int TestThreads = 23;
263 const int TestsPerThread = 100;
264 const int NumberOfEvents = 230;
266 typedef std::shared_ptr<ICTestController> ICTestControllerPtr;
267 typedef std::shared_ptr<TestContextFree> TestContextFreePtr;
268 typedef std::shared_ptr<TestRunnerInThread> TestRunnerInThreadPtr;
269 typedef std::shared_ptr<DPL::Thread> ThreadPtr;
272 std::list<TestContextFreePtr> frees;
273 std::list<ICTestControllerPtr> ctrls;
274 std::list<TestRunnerInThreadPtr> frees_threads;
275 std::list<ThreadPtr> ctrls_threads;
278 class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
281 TestContextFree(ICTestController* controller,
283 m_controller(controller),
284 m_eventsCount(eventsCount)
289 LogDebug("Waiting for thread");
290 DPL::WaitForSingleHandle(m_waitable.GetHandle());
297 if (m_eventsCount > 0) {
298 LogDebug("posting next event");
299 GetIntAndStringEvent getIntAndStringEvent(
301 &TestContextFree::OnIntAndStringReceive));
302 LogDebug("posting next event ...");
303 m_controller->DPL::Event::ControllerEventHandler<
304 GetIntAndStringEvent>::PostEvent(
305 getIntAndStringEvent);
306 LogDebug("posting next event done");
308 LogDebug("test finished");
313 void OnIntReceive(int)
317 if (m_eventsCount > 0) {
318 LogDebug("posting next event");
319 GetNothingEvent getNothingEvent(
321 &TestContextFree::OnNothing));
322 LogDebug("posting next event ...");
323 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
326 LogDebug("posting next event done");
328 LogDebug("test finished");
333 void OnIntAndStringReceive(int, std::string)
337 if (m_eventsCount > 0) {
338 LogDebug("posting next event");
340 GetIntEvent getIntEvent(
342 &TestContextFree::OnIntReceive));
343 LogDebug("posting next event ...");
344 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
347 LogDebug("posting next event done");
349 LogDebug("test finished");
354 void StartTestOnNothing()
356 GetNothingEvent getNothingEvent(
358 &TestContextFree::OnNothing));
359 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
364 void StartTestOnInt()
366 GetIntEvent getIntEvent(
368 &TestContextFree::OnIntReceive));
369 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
374 void StartTestOnIntAndString()
376 GetIntAndStringEvent getIntAndStringEvent(
378 &TestContextFree::OnIntAndStringReceive));
379 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
381 getIntAndStringEvent);
386 LogDebug("Checking test result");
387 return m_eventsCount == 0;
391 ICTestController* m_controller;
393 DPL::WaitableEvent m_waitable;
396 class TestRunnerInThread : public DPL::Thread
399 TestRunnerInThread(int events, int tests) :
400 m_eventsCount(events),
405 LogDebug("Waiting for thread");
406 DPL::WaitForSingleHandle(m_init.GetHandle());
410 virtual int ThreadEntry()
412 LogDebug("Thread starts");
414 DPL::Mutex::ScopedLock lock(&mutex);
415 for (int i = 0; i < m_tests; ++i) {
416 if (i % TestsPerController == 0) {
417 if (ctrls.size() % ControllersPerThread == 0) {
418 ThreadPtr thread(new DPL::Thread());
420 ctrls_threads.push_back(thread);
422 ICTestControllerPtr ptr(new ICTestController());
424 ptr->SwitchToThread(ctrls_threads.back().get());
425 ctrls.push_back(ptr);
427 TestContextFreePtr t(new TestContextFree(ctrls.back().get(),
429 t->StartTestOnNothing();
436 LogDebug("Thread starts loop");
437 return DPL::Thread::ThreadEntry();
441 DPL::WaitableEvent m_init;
448 Description: checks if delegetes are correctly called
449 Expected: delegates should be called from right context
451 RUNNER_TEST(ICDelegate_2)
453 LogDebug("Creating test threads");
454 for (int i = 0; i < TestThreads; ++i) {
455 TestRunnerInThreadPtr ptr(
456 new TestRunnerInThread(NumberOfEvents, TestsPerThread));
457 frees_threads.push_back(ptr);
458 frees_threads.back()->Run();
461 FOREACH(it, frees_threads) {
462 (*it)->WaitForInit();
464 LogDebug("Creating test threads done");
472 RUNNER_ASSERT((*it)->CheckTest());
477 FOREACH(it, frees_threads) {
481 frees_threads.clear();
484 (*it)->SwitchToThread(NULL);
487 FOREACH(it, ctrls_threads) {
492 ctrls_threads.clear();
495 namespace ReuseCheck {
496 const int ReuseCount = 5;
497 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
498 DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType)
500 class ICReuseTestController :
501 public DPL::Event::Controller<DPL::TypeListDecl<ReuseCountEvent>::Type>
504 ICReuseTestController()
510 virtual void OnEventReceived(const ReuseCountEvent& event)
512 event.GetArg0() (); //calling intercontext delegate
513 if (++m_reuseCount < ReuseCount) {
514 LogInfo("[Send] Reuse: " << m_reuseCount);
515 DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(
523 class ReuseTestContextFreeClass :
524 protected DPL::Thread,
525 public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
528 ReuseTestContextFreeClass(ICReuseTestController* controller) :
530 m_controller(controller),
544 DPL::WaitForSingleHandle(m_waitable.GetHandle());
548 void OnReuseReceive()
550 LogDebug("[Received] : " << ++m_reuseCount);
551 if (m_reuseCount == ReuseCount) {
556 virtual int ThreadEntry()
558 ReuseCountEvent reuseEvent(
560 &ReuseTestContextFreeClass::OnReuseReceive,
561 DPL::Event::ICD::Reuse::Yes));
562 m_controller->DPL::Event::ControllerEventHandler<ReuseCountEvent>::
566 return Thread::ThreadEntry();
570 DPL::WaitableEvent m_waitable;
571 ICReuseTestController* m_controller;
577 Description: checks if delegetes are correctly called
578 Expected: delegates should be called from right context
580 RUNNER_TEST(ICDelegate_3)
584 LogDebug("Controller thread id = " << &thread);
586 ICReuseTestController testController;
587 testController.Touch();
588 testController.SwitchToThread(&thread);
590 ReuseTestContextFreeClass* contextFree =
591 new ReuseTestContextFreeClass(&testController);
603 } //namespace ReuseCheck