Add timeout mechanism for time-limited function calls 01/33501/5
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Mon, 12 Jan 2015 10:16:34 +0000 (11:16 +0100)
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Thu, 15 Jan 2015 18:48:59 +0000 (19:48 +0100)
Timeout mechanism:
1) launches given function in new thread;
2) waits given time period;
3) cancels called function using custom user CancelFunction;
4) checks if function has finished in expected way;
5) returns function answer (value or exception).

Change-Id: Ia65d271095712e6afaaac96932f8d14d61b1702a

tests/common/timeout.h [new file with mode: 0644]

diff --git a/tests/common/timeout.h b/tests/common/timeout.h
new file mode 100644 (file)
index 0000000..7e985ab
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        timeout.h
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @brief       Definition of time limited execution of synchronous functions
+ */
+
+#ifndef TIMEOUT_H
+#define TIMEOUT_H
+
+#include <chrono>
+#include <functional>
+#include <future>
+#include <utility>
+
+#include <tests_common.h>
+
+namespace Timeout {
+
+template <class Rep, class Period>
+using Timeout = std::chrono::duration<Rep, Period>;
+
+template <class Ret, class... Args>
+using Function = std::function<Ret(Args...)>;
+
+typedef std::function<void(void)> CancelFunction;
+
+enum ExpectMode {
+    FINISHED,
+    TIMEOUT,
+    IGNORE,
+};
+
+std::ostream& operator<<(std::ostream& os, const std::future_status &status)
+{
+    switch (status) {
+        case std::future_status::ready:
+            os << "<READY>";
+            break;
+        case std::future_status::timeout:
+            os << "<TIMEOUT>";
+            break;
+        case std::future_status::deferred:
+            os << "<DEFERRED>";
+            break;
+    }
+    os << " [" << static_cast<int>(status) << "]";
+    return os;
+}
+
+template <class Rep, class Period, class Ret, class... Args>
+Ret callAndWait(const Timeout<Rep, Period> &timeout,
+                 ExpectMode expect,
+                 CancelFunction cancelFunction,
+                 Function<Ret, Args...> function,
+                 Args... args) {
+    RUNNER_ASSERT_MSG(function,
+                         "not empty function must be passed to callAndWait");
+
+    std::future<Ret> fut = std::async(std::launch::async, function, std::forward<Args>(args)...);
+    std::future_status status = fut.wait_for(timeout);
+
+    if (status == std::future_status::timeout && cancelFunction)
+        cancelFunction();
+
+    switch (expect) {
+        case FINISHED:
+            RUNNER_ASSERT_MSG(status == std::future_status::ready,
+                                 "expected future status is " << std::future_status::ready
+                                     << " received future status is " << status);
+            break;
+        case TIMEOUT:
+            RUNNER_ASSERT_MSG(status == std::future_status::timeout,
+                                 "expected future status is " << std::future_status::timeout
+                                     << " received future status is " << status);
+            break;
+        case IGNORE:
+            break;
+    }
+
+    return fut.get();
+}
+
+} // namespace Timeout
+
+#endif // TIMEOUT_H