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/wrt_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/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 WrtLogD("Context thread id = %p", static_cast<void*>(this));
125 WrtLogD("Running Context Free thread");
131 WrtLogD("Exiting Context Free thread");
137 WrtLogD("Waiting for thread");
138 DPL::WaitForSingleHandle(m_waitable.GetHandle());
144 WrtLogD("Received nothing in thread = %p",
145 static_cast<void*>(GetCurrentThread()));
146 m_testResult->m_correctThread0 = (GetCurrentThread() == this);
149 void OnIntReceive(int val)
151 WrtLogD("Received int in thread = %p",
152 static_cast<void*>(GetCurrentThread()));
153 m_testResult->m_correctThread1 = (GetCurrentThread() == this);
154 m_testResult->m_int = val;
157 void OnIntAndStringReceive(int val, std::string stringval)
159 WrtLogD("Received int and string in thread = %p",
160 static_cast<void*>(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>::
176 GetIntEvent getIntEvent(
178 &TestContextFreeClass::OnIntReceive));
179 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
183 GetIntAndStringEvent getIntAndStringEvent(
185 &TestContextFreeClass::OnIntAndStringReceive));
186 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
188 getIntAndStringEvent);
190 return Thread::ThreadEntry();
194 TestResult* m_testResult;
195 DPL::WaitableEvent m_waitable;
196 ICTestController* m_controller;
201 Description: checks if delegetes are correctly called
202 Expected: delegates should be called from right context
204 RUNNER_TEST(ICDelegate_0)
208 WrtLogD("Controller thread id = %p", static_cast<void*>(&thread));
210 ICTestController testController;
211 testController.Touch();
212 testController.SwitchToThread(&thread);
215 TestContextFreeClass* contextFree =
216 new TestContextFreeClass(&testController, &result);
217 result.TestEventsDidNotPass();
227 result.TestEventsPassed();
232 Description: checks if delegetes are correctly called
233 Expected: delegates should be called from right context
235 RUNNER_TEST(ICDelegate_1)
238 WrtLogD("Controller thread id = %p", static_cast<void*>(&thread));
240 ICTestController testController;
241 testController.Touch();
242 testController.SwitchToThread(&thread);
245 TestContextFreeClass* contextFree =
246 new TestContextFreeClass(&testController, &result);
247 result.TestEventsDidNotPass();
251 delete contextFree; //deleting Delegates before actual Events are worked out
255 result.TestEventsDidNotPass();
258 class TestContextFree;
259 class TestRunnerInThread;
262 const int ControllersPerThread = 40;
263 const int ContextFreePerThread = 180;
264 const int TestsPerController = 110;
265 const int TestThreads = 23;
266 const int TestsPerThread = 100;
267 const int NumberOfEvents = 230;
269 typedef std::shared_ptr<ICTestController> ICTestControllerPtr;
270 typedef std::shared_ptr<TestContextFree> TestContextFreePtr;
271 typedef std::shared_ptr<TestRunnerInThread> TestRunnerInThreadPtr;
272 typedef std::shared_ptr<DPL::Thread> ThreadPtr;
275 std::list<TestContextFreePtr> frees;
276 std::list<ICTestControllerPtr> ctrls;
277 std::list<TestRunnerInThreadPtr> frees_threads;
278 std::list<ThreadPtr> ctrls_threads;
281 class TestContextFree : public DPL::Event::ICDelegateSupport<TestContextFree>
284 TestContextFree(ICTestController* controller,
286 m_controller(controller),
287 m_eventsCount(eventsCount)
292 WrtLogD("Waiting for thread");
293 DPL::WaitForSingleHandle(m_waitable.GetHandle());
300 if (m_eventsCount > 0) {
301 WrtLogD("posting next event");
302 GetIntAndStringEvent getIntAndStringEvent(
304 &TestContextFree::OnIntAndStringReceive));
305 WrtLogD("posting next event ...");
306 m_controller->DPL::Event::ControllerEventHandler<
307 GetIntAndStringEvent>::PostEvent(
308 getIntAndStringEvent);
309 WrtLogD("posting next event done");
311 WrtLogD("test finished");
316 void OnIntReceive(int)
320 if (m_eventsCount > 0) {
321 WrtLogD("posting next event");
322 GetNothingEvent getNothingEvent(
324 &TestContextFree::OnNothing));
325 WrtLogD("posting next event ...");
326 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
329 WrtLogD("posting next event done");
331 WrtLogD("test finished");
336 void OnIntAndStringReceive(int, std::string)
340 if (m_eventsCount > 0) {
341 WrtLogD("posting next event");
343 GetIntEvent getIntEvent(
345 &TestContextFree::OnIntReceive));
346 WrtLogD("posting next event ...");
347 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
350 WrtLogD("posting next event done");
352 WrtLogD("test finished");
357 void StartTestOnNothing()
359 GetNothingEvent getNothingEvent(
361 &TestContextFree::OnNothing));
362 m_controller->DPL::Event::ControllerEventHandler<GetNothingEvent>::
367 void StartTestOnInt()
369 GetIntEvent getIntEvent(
371 &TestContextFree::OnIntReceive));
372 m_controller->DPL::Event::ControllerEventHandler<GetIntEvent>::
377 void StartTestOnIntAndString()
379 GetIntAndStringEvent getIntAndStringEvent(
381 &TestContextFree::OnIntAndStringReceive));
382 m_controller->DPL::Event::ControllerEventHandler<GetIntAndStringEvent>
384 getIntAndStringEvent);
389 WrtLogD("Checking test result");
390 return m_eventsCount == 0;
394 ICTestController* m_controller;
396 DPL::WaitableEvent m_waitable;
399 class TestRunnerInThread : public DPL::Thread
402 TestRunnerInThread(int events, int tests) :
403 m_eventsCount(events),
408 WrtLogD("Waiting for thread");
409 DPL::WaitForSingleHandle(m_init.GetHandle());
413 virtual int ThreadEntry()
415 WrtLogD("Thread starts");
417 std::lock_guard<std::mutex> lock(mutex);
418 for (int i = 0; i < m_tests; ++i) {
419 if (i % TestsPerController == 0) {
420 if (ctrls.size() % ControllersPerThread == 0) {
421 ThreadPtr thread(new DPL::Thread());
423 ctrls_threads.push_back(thread);
425 ICTestControllerPtr ptr(new ICTestController());
427 ptr->SwitchToThread(ctrls_threads.back().get());
428 ctrls.push_back(ptr);
430 TestContextFreePtr t(new TestContextFree(ctrls.back().get(),
432 t->StartTestOnNothing();
439 WrtLogD("Thread starts loop");
440 return DPL::Thread::ThreadEntry();
444 DPL::WaitableEvent m_init;
451 Description: checks if delegetes are correctly called
452 Expected: delegates should be called from right context
454 RUNNER_TEST(ICDelegate_2)
456 WrtLogD("Creating test threads");
457 for (int i = 0; i < TestThreads; ++i) {
458 TestRunnerInThreadPtr ptr(
459 new TestRunnerInThread(NumberOfEvents, TestsPerThread));
460 frees_threads.push_back(ptr);
461 frees_threads.back()->Run();
464 FOREACH(it, frees_threads) {
465 (*it)->WaitForInit();
467 WrtLogD("Creating test threads done");
475 RUNNER_ASSERT((*it)->CheckTest());
480 FOREACH(it, frees_threads) {
484 frees_threads.clear();
487 (*it)->SwitchToThread(NULL);
490 FOREACH(it, ctrls_threads) {
495 ctrls_threads.clear();
498 namespace ReuseCheck {
499 const int ReuseCount = 5;
500 typedef DPL::Event::ICDelegate<> GetNothingDlpType;
501 DECLARE_GENERIC_EVENT_1(ReuseCountEvent, GetNothingDlpType)
503 class ICReuseTestController :
504 public DPL::Event::Controller<DPL::TypeListDecl<ReuseCountEvent>::Type>
507 ICReuseTestController()
513 virtual void OnEventReceived(const ReuseCountEvent& event)
515 event.GetArg0() (); //calling intercontext delegate
516 if (++m_reuseCount < ReuseCount) {
517 WrtLogD("[Send] Reuse: %i", m_reuseCount);
518 DPL::Event::ControllerEventHandler<ReuseCountEvent>::PostEvent(
526 class ReuseTestContextFreeClass :
527 protected DPL::Thread,
528 public DPL::Event::ICDelegateSupport<ReuseTestContextFreeClass>
531 ReuseTestContextFreeClass(ICReuseTestController* controller) :
533 m_controller(controller),
547 DPL::WaitForSingleHandle(m_waitable.GetHandle());
551 void OnReuseReceive()
553 WrtLogD("[Received] : %i", ++m_reuseCount);
554 if (m_reuseCount == ReuseCount) {
559 virtual int ThreadEntry()
561 ReuseCountEvent reuseEvent(
563 &ReuseTestContextFreeClass::OnReuseReceive,
564 DPL::Event::ICD::Reuse::Yes));
565 m_controller->DPL::Event::ControllerEventHandler<ReuseCountEvent>::
569 return Thread::ThreadEntry();
573 DPL::WaitableEvent m_waitable;
574 ICReuseTestController* m_controller;
580 Description: checks if delegetes are correctly called
581 Expected: delegates should be called from right context
583 RUNNER_TEST(ICDelegate_3)
587 WrtLogD("Controller thread id = %p", static_cast<void*>(&thread));
589 ICReuseTestController testController;
590 testController.Touch();
591 testController.SwitchToThread(&thread);
593 ReuseTestContextFreeClass* contextFree =
594 new ReuseTestContextFreeClass(&testController);
606 } //namespace ReuseCheck