Use functor object as main argument of callAndWait
[platform/core/test/security-tests.git] / src / common / timeout.h
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /**
17  * @file        timeout.h
18  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
19  * @brief       Definition of time limited execution of synchronous functions
20  */
21
22 #ifndef TIMEOUT_H
23 #define TIMEOUT_H
24
25 #include <chrono>
26 #include <functional>
27 #include <future>
28 #include <type_traits>
29 #include <utility>
30
31 #include <tests_common.h>
32
33 namespace Timeout {
34
35 template <class Rep, class Period>
36 using Timeout = std::chrono::duration<Rep, Period>;
37
38 typedef std::function<void(void)> CancelFunction;
39
40 enum ExpectMode {
41     FINISHED,
42     TIMEOUT,
43     IGNORE,
44 };
45
46 std::ostream& operator<<(std::ostream& os, const std::future_status &status)
47 {
48     switch (status) {
49         case std::future_status::ready:
50             os << "<READY>";
51             break;
52         case std::future_status::timeout:
53             os << "<TIMEOUT>";
54             break;
55         case std::future_status::deferred:
56             os << "<DEFERRED>";
57             break;
58     }
59     os << " [" << static_cast<int>(status) << "]";
60     return os;
61 }
62
63 template <class Rep, class Period, class F, class... Args>
64     typename std::result_of<F(Args...)>::type
65     callAndWait(const Timeout<Rep, Period> &timeout,
66                  ExpectMode expect,
67                  CancelFunction cancelFunction,
68                  F&& function,
69                  Args&&... args) {
70
71     auto fut = std::async(std::launch::async, function, std::forward<Args>(args)...);
72     std::future_status status = fut.wait_for(timeout);
73
74     if (status == std::future_status::timeout && cancelFunction)
75         cancelFunction();
76
77     switch (expect) {
78         case FINISHED:
79             RUNNER_ASSERT_MSG(status == std::future_status::ready,
80                                  "expected future status is " << std::future_status::ready
81                                      << " received future status is " << status);
82             break;
83         case TIMEOUT:
84             RUNNER_ASSERT_MSG(status == std::future_status::timeout,
85                                  "expected future status is " << std::future_status::timeout
86                                      << " received future status is " << status);
87             break;
88         case IGNORE:
89             break;
90     }
91
92     return fut.get();
93 }
94
95 } // namespace Timeout
96
97 #endif // TIMEOUT_H