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/shared_ptr.h>
31 #include <dpl/waitable_event.h>
32 #include <dpl/assert.h>
33 #include <dpl/mutex.h>
34 #include <dpl/type_list.h>
36 RUNNER_TEST_GROUP_INIT(DPL)
38 const int IntVal = 123;
39 const std::string StringVal = "someString";
41 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
42 typedef DPL::Event::ICDelegate<int> GetIntDlgType;
43 typedef DPL::Event::ICDelegate<int, std::string> GetIntAndStringDlgType;
44 DECLARE_GENERIC_EVENT_1(GetNothingEvent, GetNothingDlpType)
45 DECLARE_GENERIC_EVENT_1(GetIntEvent, GetIntDlgType)
46 DECLARE_GENERIC_EVENT_1(GetIntAndStringEvent, GetIntAndStringDlgType)
48 class ICTestController
49 : public DPL::Event::Controller<DPL::TypeListDecl<GetNothingEvent,
51 GetIntAndStringEvent>::Type>
54 ICTestController() { }
57 virtual void OnEventReceived(const GetNothingEvent& event)
59 event.GetArg0()(); //calling intercontext delegate
61 virtual void OnEventReceived(const GetIntEvent& event)
63 event.GetArg0()(IntVal); //calling intercontext delegate
66 virtual void OnEventReceived(const GetIntAndStringEvent& event)
68 event.GetArg0()(IntVal, StringVal); //calling intercontext delegate
75 m_correctThread0(false),
76 m_correctThread1(false),
77 m_correctThread2(false),
84 void TestEventsPassed()
86 RUNNER_ASSERT(m_correctThread0);
87 RUNNER_ASSERT(m_correctThread1);
88 RUNNER_ASSERT(m_int == IntVal);
89 RUNNER_ASSERT(m_correctThread2);
90 RUNNER_ASSERT(m_int2 == IntVal);
91 RUNNER_ASSERT(m_string == StringVal);
94 void TestEventsDidNotPass()
96 RUNNER_ASSERT(!m_correctThread0);
97 RUNNER_ASSERT(!m_correctThread1);
98 RUNNER_ASSERT(m_int == -1);
99 RUNNER_ASSERT(!m_correctThread2);
100 RUNNER_ASSERT(m_int2 == -1);
101 RUNNER_ASSERT(m_string == "");
104 bool m_correctThread0;
105 bool m_correctThread1;
106 bool m_correctThread2;
109 std::string m_string;
112 class TestContextFreeClass :
113 protected DPL::Thread,
114 public DPL::Event::ICDelegateSupport<TestContextFreeClass>
117 TestContextFreeClass(ICTestController* controller, TestResult* result) :
119 m_testResult(result),
120 m_controller(controller)
122 LogDebug("Context thread id = " << this);
127 LogDebug("Running Context Free thread");
133 LogDebug("Exiting Context Free thread");
140 LogDebug("Waiting for thread");
141 DPL::WaitForSingleHandle(m_waitable.GetHandle());
147 LogDebug("Received nothing in thread = " << GetCurrentThread());
148 m_testResult->m_correctThread0 = (GetCurrentThread() == this);
151 void OnIntReceive(int val)
153 LogDebug("Received int in thread = " << GetCurrentThread());
154 m_testResult->m_correctThread1 = (GetCurrentThread() == this);
155 m_testResult->m_int = val;
158 void OnIntAndStringReceive(int val, std::string stringval)
160 LogDebug("Received int and string in thread = " << GetCurrentThread());
161 m_testResult->m_correctThread2 = (GetCurrentThread() == this);
162 m_testResult->m_int2 = val;
163 m_testResult->m_string = stringval;
167 virtual int ThreadEntry()
169 GetNothingEvent getNothingEvent(
171 &TestContextFreeClass::OnNothing));
172 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::PostEvent(
175 GetIntEvent getIntEvent(
177 &TestContextFreeClass::OnIntReceive));
178 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::PostEvent(
181 GetIntAndStringEvent getIntAndStringEvent(
183 &TestContextFreeClass::OnIntAndStringReceive));
184 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>::PostEvent(
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;
250 const int ControllersPerThread = 40;
251 const int ContextFreePerThread = 180;
252 const int TestsPerController = 110;
253 const int TestThreads = 23;
254 const int TestsPerThread = 100;
255 const int NumberOfEvents = 230;
257 typedef DPL::SharedPtr<ICTestController> ICTestControllerPtr;
258 typedef DPL::SharedPtr<TestContextFree> TestContextFreePtr;
259 typedef DPL::SharedPtr<TestRunnerInThread> TestRunnerInThreadPtr;
260 typedef DPL::SharedPtr<DPL::Thread> ThreadPtr;
263 std::list<TestContextFreePtr> frees;
264 std::list<ICTestControllerPtr> ctrls;
265 std::list<TestRunnerInThreadPtr> frees_threads;
266 std::list<ThreadPtr> ctrls_threads;
270 class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
273 TestContextFree(ICTestController* controller,
275 m_controller(controller),
276 m_eventsCount(eventsCount)
282 LogDebug("Waiting for thread");
283 DPL::WaitForSingleHandle(m_waitable.GetHandle());
291 if (m_eventsCount > 0) {
292 LogDebug("posting next event");
293 GetIntAndStringEvent getIntAndStringEvent(
295 &TestContextFree::OnIntAndStringReceive));
296 LogDebug("posting next event ...");
297 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>::PostEvent(
298 getIntAndStringEvent);
299 LogDebug("posting next event done");
301 LogDebug("test finished");
306 void OnIntReceive(int)
310 if (m_eventsCount > 0) {
311 LogDebug("posting next event");
312 GetNothingEvent getNothingEvent(
314 &TestContextFree::OnNothing));
315 LogDebug("posting next event ...");
316 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::PostEvent(
318 LogDebug("posting next event done");
320 LogDebug("test finished");
325 void OnIntAndStringReceive(int, std::string)
329 if (m_eventsCount > 0) {
330 LogDebug("posting next event");
332 GetIntEvent getIntEvent(
334 &TestContextFree::OnIntReceive));
335 LogDebug("posting next event ...");
336 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::PostEvent(
338 LogDebug("posting next event done");
340 LogDebug("test finished");
345 void StartTestOnNothing()
347 GetNothingEvent getNothingEvent(
349 &TestContextFree::OnNothing));
350 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::PostEvent(
354 void StartTestOnInt()
356 GetIntEvent getIntEvent(
358 &TestContextFree::OnIntReceive));
359 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::PostEvent(
363 void StartTestOnIntAndString()
365 GetIntAndStringEvent getIntAndStringEvent(
367 &TestContextFree::OnIntAndStringReceive));
368 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>::PostEvent(
369 getIntAndStringEvent);
374 LogDebug("Checking test result");
375 return m_eventsCount == 0;
379 ICTestController* m_controller;
381 DPL::WaitableEvent m_waitable;
384 class TestRunnerInThread : public DPL::Thread
387 TestRunnerInThread(int events, int tests) :
388 m_eventsCount(events),
393 LogDebug("Waiting for thread");
394 DPL::WaitForSingleHandle(m_init.GetHandle());
398 virtual int ThreadEntry()
400 LogDebug("Thread starts");
402 DPL::Mutex::ScopedLock lock(&mutex);
403 for (int i = 0; i < m_tests; ++i)
405 if (i % TestsPerController == 0) {
406 if (ctrls.size() % ControllersPerThread == 0) {
407 ThreadPtr thread(new DPL::Thread());
409 ctrls_threads.push_back(thread);
411 ICTestControllerPtr ptr(new ICTestController());
413 ptr->SwitchToThread(ctrls_threads.back().Get());
414 ctrls.push_back(ptr);
416 TestContextFreePtr t(new TestContextFree(ctrls.back().Get(),
418 t->StartTestOnNothing();
425 LogDebug("Thread starts loop");
426 return DPL::Thread::ThreadEntry();
430 DPL::WaitableEvent m_init;
435 RUNNER_TEST(ICDelegate_2)
437 LogDebug("Creating test threads");
438 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() { m_reuseCount = 0; }
492 virtual void OnEventReceived(const ReuseCountEvent& event)
494 event.GetArg0()(); //calling intercontext delegate
495 if(++m_reuseCount < ReuseCount){
496 LogInfo("[Send] Reuse: " << m_reuseCount);
497 DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(event);
504 class ReuseTestContextFreeClass :
505 protected DPL::Thread,
506 public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
509 ReuseTestContextFreeClass(ICReuseTestController* controller) :
511 m_controller(controller),
515 void Run() { Thread::Run(); }
516 void Quit() { Thread::Quit(); }
517 void Wait() { DPL::WaitForSingleHandle(m_waitable.GetHandle()); }
520 void OnReuseReceive()
522 LogDebug("[Received] : " << ++m_reuseCount);
523 if(m_reuseCount == ReuseCount)
527 virtual int ThreadEntry()
529 ReuseCountEvent reuseEvent(
531 &ReuseTestContextFreeClass::OnReuseReceive,
532 DPL::Event::ICD::Reuse::Yes));
533 m_controller->DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(
536 return Thread::ThreadEntry();
540 DPL::WaitableEvent m_waitable;
541 ICReuseTestController* m_controller;
545 RUNNER_TEST(ICDelegate_3)
549 LogDebug("Controller thread id = " << &thread);
551 ICReuseTestController testController;
552 testController.Touch();
553 testController.SwitchToThread(&thread);
555 ReuseTestContextFreeClass* contextFree =
556 new ReuseTestContextFreeClass(&testController);
568 } //namespace ReuseCheck