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/event/inter_context_delegate.h>
28 #include <dpl/thread.h>
29 #include <dpl/waitable_event.h>
30 #include <dpl/assert.h>
31 #include <dpl/mutex.h>
32 #include <dpl/type_list.h>
34 RUNNER_TEST_GROUP_INIT(DPL)
36 const int IntVal = 123;
37 const std::string StringVal = "someString";
39 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
40 typedef DPL::Event::ICDelegate<int> GetIntDlgType;
41 typedef DPL::Event::ICDelegate<int, std::string> GetIntAndStringDlgType;
42 DECLARE_GENERIC_EVENT_1(GetNothingEvent, GetNothingDlpType)
43 DECLARE_GENERIC_EVENT_1(GetIntEvent, GetIntDlgType)
44 DECLARE_GENERIC_EVENT_1(GetIntAndStringEvent, GetIntAndStringDlgType)
46 class ICTestController :
47 public DPL::Event::Controller<DPL::TypeListDecl<GetNothingEvent,
49 GetIntAndStringEvent>::Type>
52 ICTestController() { }
55 virtual void OnEventReceived(const GetNothingEvent& event)
57 event.GetArg0() (); //calling intercontext delegate
59 virtual void OnEventReceived(const GetIntEvent& event)
61 event.GetArg0() (IntVal); //calling intercontext delegate
64 virtual void OnEventReceived(const GetIntAndStringEvent& event)
66 event.GetArg0() (IntVal, StringVal); //calling intercontext delegate
73 m_correctThread0(false),
74 m_correctThread1(false),
75 m_correctThread2(false),
81 void TestEventsPassed()
83 RUNNER_ASSERT(m_correctThread0);
84 RUNNER_ASSERT(m_correctThread1);
85 RUNNER_ASSERT(m_int == IntVal);
86 RUNNER_ASSERT(m_correctThread2);
87 RUNNER_ASSERT(m_int2 == IntVal);
88 RUNNER_ASSERT(m_string == StringVal);
91 void TestEventsDidNotPass()
93 RUNNER_ASSERT(!m_correctThread0);
94 RUNNER_ASSERT(!m_correctThread1);
95 RUNNER_ASSERT(m_int == -1);
96 RUNNER_ASSERT(!m_correctThread2);
97 RUNNER_ASSERT(m_int2 == -1);
98 RUNNER_ASSERT(m_string == "");
101 bool m_correctThread0;
102 bool m_correctThread1;
103 bool m_correctThread2;
106 std::string m_string;
109 class TestContextFreeClass :
110 protected DPL::Thread,
111 public DPL::Event::ICDelegateSupport<TestContextFreeClass>
114 TestContextFreeClass(ICTestController* controller, TestResult* result) :
116 m_testResult(result),
117 m_controller(controller)
119 LogDebug("Context thread id = " << this);
124 LogDebug("Running Context Free thread");
130 LogDebug("Exiting Context Free thread");
136 LogDebug("Waiting for thread");
137 DPL::WaitForSingleHandle(m_waitable.GetHandle());
143 LogDebug("Received nothing in thread = " << GetCurrentThread());
144 m_testResult->m_correctThread0 = (GetCurrentThread() == this);
147 void OnIntReceive(int val)
149 LogDebug("Received int in thread = " << GetCurrentThread());
150 m_testResult->m_correctThread1 = (GetCurrentThread() == this);
151 m_testResult->m_int = val;
154 void OnIntAndStringReceive(int val, std::string stringval)
156 LogDebug("Received int and string in thread = " << GetCurrentThread());
157 m_testResult->m_correctThread2 = (GetCurrentThread() == this);
158 m_testResult->m_int2 = val;
159 m_testResult->m_string = stringval;
163 virtual int ThreadEntry()
165 GetNothingEvent getNothingEvent(
167 &TestContextFreeClass::OnNothing));
168 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
172 GetIntEvent getIntEvent(
174 &TestContextFreeClass::OnIntReceive));
175 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
179 GetIntAndStringEvent getIntAndStringEvent(
181 &TestContextFreeClass::OnIntAndStringReceive));
182 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
184 getIntAndStringEvent);
186 return Thread::ThreadEntry();
190 TestResult* m_testResult;
191 DPL::WaitableEvent m_waitable;
192 ICTestController* m_controller;
197 Description: checks if delegetes are correctly called
198 Expected: delegates should be called from right context
200 RUNNER_TEST(ICDelegate_0)
204 LogDebug("Controller thread id = " << &thread);
206 ICTestController testController;
207 testController.Touch();
208 testController.SwitchToThread(&thread);
211 TestContextFreeClass* contextFree =
212 new TestContextFreeClass(&testController, &result);
213 result.TestEventsDidNotPass();
223 result.TestEventsPassed();
228 Description: checks if delegetes are correctly called
229 Expected: delegates should be called from right context
231 RUNNER_TEST(ICDelegate_1)
234 LogDebug("Controller thread id = " << &thread);
236 ICTestController testController;
237 testController.Touch();
238 testController.SwitchToThread(&thread);
241 TestContextFreeClass* contextFree =
242 new TestContextFreeClass(&testController, &result);
243 result.TestEventsDidNotPass();
247 delete contextFree; //deleting Delegates before actual Events are worked out
251 result.TestEventsDidNotPass();
254 class TestContextFree;
255 class TestRunnerInThread;
258 const int ControllersPerThread = 40;
259 const int ContextFreePerThread = 180;
260 const int TestsPerController = 110;
261 const int TestThreads = 23;
262 const int TestsPerThread = 100;
263 const int NumberOfEvents = 230;
265 typedef std::shared_ptr<ICTestController> ICTestControllerPtr;
266 typedef std::shared_ptr<TestContextFree> TestContextFreePtr;
267 typedef std::shared_ptr<TestRunnerInThread> TestRunnerInThreadPtr;
268 typedef std::shared_ptr<DPL::Thread> ThreadPtr;
271 std::list<TestContextFreePtr> frees;
272 std::list<ICTestControllerPtr> ctrls;
273 std::list<TestRunnerInThreadPtr> frees_threads;
274 std::list<ThreadPtr> ctrls_threads;
277 class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
280 TestContextFree(ICTestController* controller,
282 m_controller(controller),
283 m_eventsCount(eventsCount)
288 LogDebug("Waiting for thread");
289 DPL::WaitForSingleHandle(m_waitable.GetHandle());
296 if (m_eventsCount > 0) {
297 LogDebug("posting next event");
298 GetIntAndStringEvent getIntAndStringEvent(
300 &TestContextFree::OnIntAndStringReceive));
301 LogDebug("posting next event ...");
302 m_controller->DPL::Event::ControllerEventHandler<
303 GetIntAndStringEvent>::PostEvent(
304 getIntAndStringEvent);
305 LogDebug("posting next event done");
307 LogDebug("test finished");
312 void OnIntReceive(int)
316 if (m_eventsCount > 0) {
317 LogDebug("posting next event");
318 GetNothingEvent getNothingEvent(
320 &TestContextFree::OnNothing));
321 LogDebug("posting next event ...");
322 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
325 LogDebug("posting next event done");
327 LogDebug("test finished");
332 void OnIntAndStringReceive(int, std::string)
336 if (m_eventsCount > 0) {
337 LogDebug("posting next event");
339 GetIntEvent getIntEvent(
341 &TestContextFree::OnIntReceive));
342 LogDebug("posting next event ...");
343 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
346 LogDebug("posting next event done");
348 LogDebug("test finished");
353 void StartTestOnNothing()
355 GetNothingEvent getNothingEvent(
357 &TestContextFree::OnNothing));
358 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
363 void StartTestOnInt()
365 GetIntEvent getIntEvent(
367 &TestContextFree::OnIntReceive));
368 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
373 void StartTestOnIntAndString()
375 GetIntAndStringEvent getIntAndStringEvent(
377 &TestContextFree::OnIntAndStringReceive));
378 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
380 getIntAndStringEvent);
385 LogDebug("Checking test result");
386 return m_eventsCount == 0;
390 ICTestController* m_controller;
392 DPL::WaitableEvent m_waitable;
395 class TestRunnerInThread : public DPL::Thread
398 TestRunnerInThread(int events, int tests) :
399 m_eventsCount(events),
404 LogDebug("Waiting for thread");
405 DPL::WaitForSingleHandle(m_init.GetHandle());
409 virtual int ThreadEntry()
411 LogDebug("Thread starts");
413 DPL::Mutex::ScopedLock lock(&mutex);
414 for (int i = 0; i < m_tests; ++i) {
415 if (i % TestsPerController == 0) {
416 if (ctrls.size() % ControllersPerThread == 0) {
417 ThreadPtr thread(new DPL::Thread());
419 ctrls_threads.push_back(thread);
421 ICTestControllerPtr ptr(new ICTestController());
423 ptr->SwitchToThread(ctrls_threads.back().get());
424 ctrls.push_back(ptr);
426 TestContextFreePtr t(new TestContextFree(ctrls.back().get(),
428 t->StartTestOnNothing();
435 LogDebug("Thread starts loop");
436 return DPL::Thread::ThreadEntry();
440 DPL::WaitableEvent m_init;
447 Description: checks if delegetes are correctly called
448 Expected: delegates should be called from right context
450 RUNNER_TEST(ICDelegate_2)
452 LogDebug("Creating test threads");
453 for (int i = 0; i < TestThreads; ++i) {
454 TestRunnerInThreadPtr ptr(
455 new TestRunnerInThread(NumberOfEvents, TestsPerThread));
456 frees_threads.push_back(ptr);
457 frees_threads.back()->Run();
460 FOREACH(it, frees_threads) {
461 (*it)->WaitForInit();
463 LogDebug("Creating test threads done");
471 RUNNER_ASSERT((*it)->CheckTest());
476 FOREACH(it, frees_threads) {
480 frees_threads.clear();
483 (*it)->SwitchToThread(NULL);
486 FOREACH(it, ctrls_threads) {
491 ctrls_threads.clear();
494 namespace ReuseCheck {
495 const int ReuseCount = 5;
496 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
497 DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType)
499 class ICReuseTestController :
500 public DPL::Event::Controller<DPL::TypeListDecl<ReuseCountEvent>::Type>
503 ICReuseTestController()
509 virtual void OnEventReceived(const ReuseCountEvent& event)
511 event.GetArg0() (); //calling intercontext delegate
512 if (++m_reuseCount < ReuseCount) {
513 LogDebug("[Send] Reuse: " << m_reuseCount);
514 DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(
522 class ReuseTestContextFreeClass :
523 protected DPL::Thread,
524 public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
527 ReuseTestContextFreeClass(ICReuseTestController* controller) :
529 m_controller(controller),
543 DPL::WaitForSingleHandle(m_waitable.GetHandle());
547 void OnReuseReceive()
549 LogDebug("[Received] : " << ++m_reuseCount);
550 if (m_reuseCount == ReuseCount) {
555 virtual int ThreadEntry()
557 ReuseCountEvent reuseEvent(
559 &ReuseTestContextFreeClass::OnReuseReceive,
560 DPL::Event::ICD::Reuse::Yes));
561 m_controller->DPL::Event::ControllerEventHandler<ReuseCountEvent>::
565 return Thread::ThreadEntry();
569 DPL::WaitableEvent m_waitable;
570 ICReuseTestController* m_controller;
576 Description: checks if delegetes are correctly called
577 Expected: delegates should be called from right context
579 RUNNER_TEST(ICDelegate_3)
583 LogDebug("Controller thread id = " << &thread);
585 ICReuseTestController testController;
586 testController.Touch();
587 testController.SwitchToThread(&thread);
589 ReuseTestContextFreeClass* contextFree =
590 new ReuseTestContextFreeClass(&testController);
602 } //namespace ReuseCheck