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),
83 void TestEventsPassed()
85 RUNNER_ASSERT(m_correctThread0);
86 RUNNER_ASSERT(m_correctThread1);
87 RUNNER_ASSERT(m_int == IntVal);
88 RUNNER_ASSERT(m_correctThread2);
89 RUNNER_ASSERT(m_int2 == IntVal);
90 RUNNER_ASSERT(m_string == StringVal);
93 void TestEventsDidNotPass()
95 RUNNER_ASSERT(!m_correctThread0);
96 RUNNER_ASSERT(!m_correctThread1);
97 RUNNER_ASSERT(m_int == -1);
98 RUNNER_ASSERT(!m_correctThread2);
99 RUNNER_ASSERT(m_int2 == -1);
100 RUNNER_ASSERT(m_string == "");
103 bool m_correctThread0;
104 bool m_correctThread1;
105 bool m_correctThread2;
108 std::string m_string;
111 class TestContextFreeClass :
112 protected DPL::Thread,
113 public DPL::Event::ICDelegateSupport<TestContextFreeClass>
116 TestContextFreeClass(ICTestController* controller, TestResult* result) :
118 m_testResult(result),
119 m_controller(controller)
121 LogDebug("Context thread id = " << this);
126 LogDebug("Running Context Free thread");
132 LogDebug("Exiting Context Free thread");
139 LogDebug("Waiting for thread");
140 DPL::WaitForSingleHandle(m_waitable.GetHandle());
146 LogDebug("Received nothing in thread = " << GetCurrentThread());
147 m_testResult->m_correctThread0 = (GetCurrentThread() == this);
150 void OnIntReceive(int val)
152 LogDebug("Received int in thread = " << GetCurrentThread());
153 m_testResult->m_correctThread1 = (GetCurrentThread() == this);
154 m_testResult->m_int = val;
157 void OnIntAndStringReceive(int val, std::string stringval)
159 LogDebug("Received int and string in thread = " << GetCurrentThread());
160 m_testResult->m_correctThread2 = (GetCurrentThread() == this);
161 m_testResult->m_int2 = val;
162 m_testResult->m_string = stringval;
166 virtual int ThreadEntry()
168 GetNothingEvent getNothingEvent(
170 &TestContextFreeClass::OnNothing));
171 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::PostEvent(
174 GetIntEvent getIntEvent(
176 &TestContextFreeClass::OnIntReceive));
177 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::PostEvent(
180 GetIntAndStringEvent getIntAndStringEvent(
182 &TestContextFreeClass::OnIntAndStringReceive));
183 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>::PostEvent(
184 getIntAndStringEvent);
186 return Thread::ThreadEntry();
190 TestResult* m_testResult;
191 DPL::WaitableEvent m_waitable;
192 ICTestController* m_controller;
195 RUNNER_TEST(ICDelegate_0)
199 LogDebug("Controller thread id = " << &thread);
201 ICTestController testController;
202 testController.Touch();
203 testController.SwitchToThread(&thread);
206 TestContextFreeClass* contextFree =
207 new TestContextFreeClass(&testController, &result);
208 result.TestEventsDidNotPass();
218 result.TestEventsPassed();
221 RUNNER_TEST(ICDelegate_1)
224 LogDebug("Controller thread id = " << &thread);
226 ICTestController testController;
227 testController.Touch();
228 testController.SwitchToThread(&thread);
231 TestContextFreeClass* contextFree =
232 new TestContextFreeClass(&testController, &result);
233 result.TestEventsDidNotPass();
237 delete contextFree; //deleting Delegates before actual Events are worked out
241 result.TestEventsDidNotPass();
244 class TestContextFree;
245 class TestRunnerInThread;
249 const int ControllersPerThread = 40;
250 const int ContextFreePerThread = 180;
251 const int TestsPerController = 110;
252 const int TestThreads = 23;
253 const int TestsPerThread = 100;
254 const int NumberOfEvents = 230;
256 typedef std::shared_ptr<ICTestController> ICTestControllerPtr;
257 typedef std::shared_ptr<TestContextFree> TestContextFreePtr;
258 typedef std::shared_ptr<TestRunnerInThread> TestRunnerInThreadPtr;
259 typedef std::shared_ptr<DPL::Thread> ThreadPtr;
262 std::list<TestContextFreePtr> frees;
263 std::list<ICTestControllerPtr> ctrls;
264 std::list<TestRunnerInThreadPtr> frees_threads;
265 std::list<ThreadPtr> ctrls_threads;
269 class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
272 TestContextFree(ICTestController* controller,
274 m_controller(controller),
275 m_eventsCount(eventsCount)
281 LogDebug("Waiting for thread");
282 DPL::WaitForSingleHandle(m_waitable.GetHandle());
290 if (m_eventsCount > 0) {
291 LogDebug("posting next event");
292 GetIntAndStringEvent getIntAndStringEvent(
294 &TestContextFree::OnIntAndStringReceive));
295 LogDebug("posting next event ...");
296 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>::PostEvent(
297 getIntAndStringEvent);
298 LogDebug("posting next event done");
300 LogDebug("test finished");
305 void OnIntReceive(int)
309 if (m_eventsCount > 0) {
310 LogDebug("posting next event");
311 GetNothingEvent getNothingEvent(
313 &TestContextFree::OnNothing));
314 LogDebug("posting next event ...");
315 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::PostEvent(
317 LogDebug("posting next event done");
319 LogDebug("test finished");
324 void OnIntAndStringReceive(int, std::string)
328 if (m_eventsCount > 0) {
329 LogDebug("posting next event");
331 GetIntEvent getIntEvent(
333 &TestContextFree::OnIntReceive));
334 LogDebug("posting next event ...");
335 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::PostEvent(
337 LogDebug("posting next event done");
339 LogDebug("test finished");
344 void StartTestOnNothing()
346 GetNothingEvent getNothingEvent(
348 &TestContextFree::OnNothing));
349 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::PostEvent(
353 void StartTestOnInt()
355 GetIntEvent getIntEvent(
357 &TestContextFree::OnIntReceive));
358 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::PostEvent(
362 void StartTestOnIntAndString()
364 GetIntAndStringEvent getIntAndStringEvent(
366 &TestContextFree::OnIntAndStringReceive));
367 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>::PostEvent(
368 getIntAndStringEvent);
373 LogDebug("Checking test result");
374 return m_eventsCount == 0;
378 ICTestController* m_controller;
380 DPL::WaitableEvent m_waitable;
383 class TestRunnerInThread : public DPL::Thread
386 TestRunnerInThread(int events, int tests) :
387 m_eventsCount(events),
392 LogDebug("Waiting for thread");
393 DPL::WaitForSingleHandle(m_init.GetHandle());
397 virtual int ThreadEntry()
399 LogDebug("Thread starts");
401 DPL::Mutex::ScopedLock lock(&mutex);
402 for (int i = 0; i < m_tests; ++i)
404 if (i % TestsPerController == 0) {
405 if (ctrls.size() % ControllersPerThread == 0) {
406 ThreadPtr thread(new DPL::Thread());
408 ctrls_threads.push_back(thread);
410 ICTestControllerPtr ptr(new ICTestController());
412 ptr->SwitchToThread(ctrls_threads.back().get());
413 ctrls.push_back(ptr);
415 TestContextFreePtr t(new TestContextFree(ctrls.back().get(),
417 t->StartTestOnNothing();
424 LogDebug("Thread starts loop");
425 return DPL::Thread::ThreadEntry();
429 DPL::WaitableEvent m_init;
434 RUNNER_TEST(ICDelegate_2)
436 LogDebug("Creating test threads");
437 for (int i = 0; i < TestThreads; ++i)
439 TestRunnerInThreadPtr ptr(
440 new TestRunnerInThread(NumberOfEvents, TestsPerThread));
441 frees_threads.push_back(ptr);
442 frees_threads.back()->Run();
445 FOREACH(it, frees_threads) {
446 (*it)->WaitForInit();
448 LogDebug("Creating test threads done");
456 RUNNER_ASSERT((*it)->CheckTest());
461 FOREACH(it, frees_threads) {
465 frees_threads.clear();
468 (*it)->SwitchToThread(NULL);
471 FOREACH(it, ctrls_threads) {
476 ctrls_threads.clear();
479 namespace ReuseCheck {
480 const int ReuseCount = 5;
481 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
482 DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType)
484 class ICReuseTestController
485 : public DPL::Event::Controller<DPL::TypeListDecl<ReuseCountEvent>::Type>
488 ICReuseTestController() { m_reuseCount = 0; }
491 virtual void OnEventReceived(const ReuseCountEvent& event)
493 event.GetArg0()(); //calling intercontext delegate
494 if(++m_reuseCount < ReuseCount){
495 LogInfo("[Send] Reuse: " << m_reuseCount);
496 DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(event);
503 class ReuseTestContextFreeClass :
504 protected DPL::Thread,
505 public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
508 ReuseTestContextFreeClass(ICReuseTestController* controller) :
510 m_controller(controller),
514 void Run() { Thread::Run(); }
515 void Quit() { Thread::Quit(); }
516 void Wait() { DPL::WaitForSingleHandle(m_waitable.GetHandle()); }
519 void OnReuseReceive()
521 LogDebug("[Received] : " << ++m_reuseCount);
522 if(m_reuseCount == ReuseCount)
526 virtual int ThreadEntry()
528 ReuseCountEvent reuseEvent(
530 &ReuseTestContextFreeClass::OnReuseReceive,
531 DPL::Event::ICD::Reuse::Yes));
532 m_controller->DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(
535 return Thread::ThreadEntry();
539 DPL::WaitableEvent m_waitable;
540 ICReuseTestController* m_controller;
544 RUNNER_TEST(ICDelegate_3)
548 LogDebug("Controller thread id = " << &thread);
550 ICReuseTestController testController;
551 testController.Touch();
552 testController.SwitchToThread(&thread);
554 ReuseTestContextFreeClass* contextFree =
555 new ReuseTestContextFreeClass(&testController);
567 } //namespace ReuseCheck