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;
196 RUNNER_TEST(ICDelegate_0)
200 LogDebug("Controller thread id = " << &thread);
202 ICTestController testController;
203 testController.Touch();
204 testController.SwitchToThread(&thread);
207 TestContextFreeClass* contextFree =
208 new TestContextFreeClass(&testController, &result);
209 result.TestEventsDidNotPass();
219 result.TestEventsPassed();
222 RUNNER_TEST(ICDelegate_1)
225 LogDebug("Controller thread id = " << &thread);
227 ICTestController testController;
228 testController.Touch();
229 testController.SwitchToThread(&thread);
232 TestContextFreeClass* contextFree =
233 new TestContextFreeClass(&testController, &result);
234 result.TestEventsDidNotPass();
238 delete contextFree; //deleting Delegates before actual Events are worked out
242 result.TestEventsDidNotPass();
245 class TestContextFree;
246 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;
268 class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
271 TestContextFree(ICTestController* controller,
273 m_controller(controller),
274 m_eventsCount(eventsCount)
279 LogDebug("Waiting for thread");
280 DPL::WaitForSingleHandle(m_waitable.GetHandle());
287 if (m_eventsCount > 0) {
288 LogDebug("posting next event");
289 GetIntAndStringEvent getIntAndStringEvent(
291 &TestContextFree::OnIntAndStringReceive));
292 LogDebug("posting next event ...");
293 m_controller->DPL::Event::ControllerEventHandler<
294 GetIntAndStringEvent>::PostEvent(
295 getIntAndStringEvent);
296 LogDebug("posting next event done");
298 LogDebug("test finished");
303 void OnIntReceive(int)
307 if (m_eventsCount > 0) {
308 LogDebug("posting next event");
309 GetNothingEvent getNothingEvent(
311 &TestContextFree::OnNothing));
312 LogDebug("posting next event ...");
313 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
316 LogDebug("posting next event done");
318 LogDebug("test finished");
323 void OnIntAndStringReceive(int, std::string)
327 if (m_eventsCount > 0) {
328 LogDebug("posting next event");
330 GetIntEvent getIntEvent(
332 &TestContextFree::OnIntReceive));
333 LogDebug("posting next event ...");
334 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
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>::
354 void StartTestOnInt()
356 GetIntEvent getIntEvent(
358 &TestContextFree::OnIntReceive));
359 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
364 void StartTestOnIntAndString()
366 GetIntAndStringEvent getIntAndStringEvent(
368 &TestContextFree::OnIntAndStringReceive));
369 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
371 getIntAndStringEvent);
376 LogDebug("Checking test result");
377 return m_eventsCount == 0;
381 ICTestController* m_controller;
383 DPL::WaitableEvent m_waitable;
386 class TestRunnerInThread : public DPL::Thread
389 TestRunnerInThread(int events, int tests) :
390 m_eventsCount(events),
395 LogDebug("Waiting for thread");
396 DPL::WaitForSingleHandle(m_init.GetHandle());
400 virtual int ThreadEntry()
402 LogDebug("Thread starts");
404 DPL::Mutex::ScopedLock lock(&mutex);
405 for (int i = 0; i < m_tests; ++i) {
406 if (i % TestsPerController == 0) {
407 if (ctrls.size() % ControllersPerThread == 0) {
408 ThreadPtr thread(new DPL::Thread());
410 ctrls_threads.push_back(thread);
412 ICTestControllerPtr ptr(new ICTestController());
414 ptr->SwitchToThread(ctrls_threads.back().get());
415 ctrls.push_back(ptr);
417 TestContextFreePtr t(new TestContextFree(ctrls.back().get(),
419 t->StartTestOnNothing();
426 LogDebug("Thread starts loop");
427 return DPL::Thread::ThreadEntry();
431 DPL::WaitableEvent m_init;
436 RUNNER_TEST(ICDelegate_2)
438 LogDebug("Creating test threads");
439 for (int i = 0; i < TestThreads; ++i) {
440 TestRunnerInThreadPtr ptr(
441 new TestRunnerInThread(NumberOfEvents, TestsPerThread));
442 frees_threads.push_back(ptr);
443 frees_threads.back()->Run();
446 FOREACH(it, frees_threads) {
447 (*it)->WaitForInit();
449 LogDebug("Creating test threads done");
457 RUNNER_ASSERT((*it)->CheckTest());
462 FOREACH(it, frees_threads) {
466 frees_threads.clear();
469 (*it)->SwitchToThread(NULL);
472 FOREACH(it, ctrls_threads) {
477 ctrls_threads.clear();
480 namespace ReuseCheck {
481 const int ReuseCount = 5;
482 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
483 DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType)
485 class ICReuseTestController :
486 public DPL::Event::Controller<DPL::TypeListDecl<ReuseCountEvent>::Type>
489 ICReuseTestController()
495 virtual void OnEventReceived(const ReuseCountEvent& event)
497 event.GetArg0() (); //calling intercontext delegate
498 if (++m_reuseCount < ReuseCount) {
499 LogInfo("[Send] Reuse: " << m_reuseCount);
500 DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(
508 class ReuseTestContextFreeClass :
509 protected DPL::Thread,
510 public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
513 ReuseTestContextFreeClass(ICReuseTestController* controller) :
515 m_controller(controller),
529 DPL::WaitForSingleHandle(m_waitable.GetHandle());
533 void OnReuseReceive()
535 LogDebug("[Received] : " << ++m_reuseCount);
536 if (m_reuseCount == ReuseCount) {
541 virtual int ThreadEntry()
543 ReuseCountEvent reuseEvent(
545 &ReuseTestContextFreeClass::OnReuseReceive,
546 DPL::Event::ICD::Reuse::Yes));
547 m_controller->DPL::Event::ControllerEventHandler<ReuseCountEvent>::
551 return Thread::ThreadEntry();
555 DPL::WaitableEvent m_waitable;
556 ICReuseTestController* m_controller;
560 RUNNER_TEST(ICDelegate_3)
564 LogDebug("Controller thread id = " << &thread);
566 ICReuseTestController testController;
567 testController.Touch();
568 testController.SwitchToThread(&thread);
570 ReuseTestContextFreeClass* contextFree =
571 new ReuseTestContextFreeClass(&testController);
583 } //namespace ReuseCheck