Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / inference_engine_tests / cpp_interfaces / task_common_tests.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <gtest/gtest.h>
6 #include <gmock/gmock-spec-builders.h>
7 #include <thread>
8
9 #include <ie_common.h>
10 #include <details/ie_exception.hpp>
11 #include <cpp_interfaces/ie_task.hpp>
12 #include <cpp_interfaces/ie_task_executor.hpp>
13 #include <cpp_interfaces/ie_task_with_stages.hpp>
14 #include <cpp_interfaces/ie_task_synchronizer.hpp>
15 #include "task_tests_utils.hpp"
16
17
18 using namespace ::testing;
19 using namespace std;
20 using namespace InferenceEngine;
21 using namespace InferenceEngine::details;
22
23 enum TaskFlavor {
24     BASE_TASK,
25     STAGED_TASK,
26     BASE_WITH_CALLBACK,
27     STAGED_WITH_CALLBACK
28 };
29
30 class TaskCommonTests : public ::testing::Test, public testing::WithParamInterface<TaskFlavor> {
31 protected:
32     Task::Ptr _task;
33
34     Task::Ptr createTask(std::function<void()> function = nullptr, bool forceNull = false) {
35         TaskFlavor flavor = GetParam();
36         bool condition = function || forceNull;
37         Task::Ptr baseTask = condition ? make_shared<Task>(function) : make_shared<Task>();
38         Task::Ptr stagedTask = condition ? make_shared<StagedTask>(function, 1) : make_shared<StagedTask>();
39         auto executor = make_shared<TaskExecutor>();
40         switch (flavor) {
41             case BASE_TASK:
42                 return baseTask;
43             case STAGED_TASK:
44                 return stagedTask;
45             default:
46                 throw logic_error("Specified non-existent flavor of task");
47         }
48     }
49 };
50
51 TEST_P(TaskCommonTests, canCreateTask) {
52     ASSERT_NO_THROW(_task = createTask());
53     ASSERT_EQ(_task->getStatus(), Task::TS_INITIAL);
54 }
55
56 TEST_P(TaskCommonTests, canSetBusyStatus) {
57     ASSERT_NO_THROW(_task = createTask());
58     ASSERT_NO_THROW(_task->occupy());
59     ASSERT_EQ(_task->getStatus(), Task::TS_BUSY);
60 }
61
62 TEST_P(TaskCommonTests, firstOccupyReturnTrueSecondFalse) {
63     ASSERT_NO_THROW(_task = createTask());
64     ASSERT_TRUE(_task->occupy());
65     ASSERT_FALSE(_task->occupy());
66 }
67
68 TEST_P(TaskCommonTests, canRunDefaultTask) {
69     _task = createTask();
70     ASSERT_NO_THROW(_task->runNoThrowNoBusyCheck());
71     ASSERT_EQ(_task->getStatus(), Task::TS_DONE);
72 }
73
74 TEST_P(TaskCommonTests, throwIfFunctionNull) {
75     ASSERT_THROW(_task = createTask(nullptr, true), InferenceEngineException);
76 }
77
78 TEST_P(TaskCommonTests, canWaitWithoutRun) {
79     _task = createTask();
80     ASSERT_NO_THROW(_task->wait(-1));
81     ASSERT_EQ(_task->getStatus(), Task::TS_INITIAL);
82     ASSERT_NO_THROW(_task->wait(1));
83     ASSERT_EQ(_task->getStatus(), Task::TS_INITIAL);
84 }
85
86 TEST_P(TaskCommonTests, canRunTaskFromThread) {
87     _task = createTask();
88
89     MetaThread metaThread([=]() {
90         _task->runNoThrowNoBusyCheck();
91     });
92
93     metaThread.join();
94     ASSERT_EQ(Task::Status::TS_DONE, _task->getStatus());
95 }
96
97
98 TEST_P(TaskCommonTests, canRunTaskFromThreadWithoutWait) {
99     _task = createTask([]() {
100         std::this_thread::sleep_for(std::chrono::milliseconds(500));
101     });
102     std::thread thread([this]() { _task->runNoThrowNoBusyCheck(); });
103     if (thread.joinable()) thread.join();
104 }
105
106 TEST_P(TaskCommonTests, waitReturnNotStartedIfTaskWasNotRun) {
107     _task = createTask();
108     Task::Status status = _task->wait(1);
109     ASSERT_EQ(status, Task::Status::TS_INITIAL);
110 }
111
112 TEST_P(TaskCommonTests, canCatchIEException) {
113     _task = createTask([]() { THROW_IE_EXCEPTION; });
114     ASSERT_NO_THROW(_task->runNoThrowNoBusyCheck());
115     Task::Status status = _task->getStatus();
116     ASSERT_EQ(status, Task::Status::TS_ERROR);
117     EXPECT_THROW(_task->checkException(), InferenceEngineException);
118 }
119
120 TEST_P(TaskCommonTests, waitReturnErrorIfException) {
121     _task = createTask([]() { THROW_IE_EXCEPTION; });
122     ASSERT_NO_THROW(_task->occupy());
123     ASSERT_NO_THROW(_task->runNoThrowNoBusyCheck());
124     Task::Status status = _task->wait(-1);
125     ASSERT_EQ(status, Task::Status::TS_ERROR);
126     EXPECT_THROW(_task->checkException(), InferenceEngineException);
127 }
128
129 TEST_P(TaskCommonTests, canCatchStdException) {
130     _task = createTask([]() { throw std::bad_alloc(); });
131     ASSERT_NO_THROW(_task->runNoThrowNoBusyCheck());
132     Task::Status status = _task->getStatus();
133     ASSERT_EQ(status, Task::Status::TS_ERROR);
134     EXPECT_THROW(_task->checkException(), std::bad_alloc);
135 }
136
137 TEST_P(TaskCommonTests, canCleanExceptionPtr) {
138     bool throwException = true;
139     _task = createTask([&throwException]() { if (throwException) throw std::bad_alloc(); else return; });
140     ASSERT_NO_THROW(_task->runNoThrowNoBusyCheck());
141     EXPECT_THROW(_task->checkException(), std::bad_alloc);
142     throwException = false;
143     ASSERT_NO_THROW(_task->runNoThrowNoBusyCheck());
144     EXPECT_NO_THROW(_task->checkException());
145 }
146
147 std::string getTestCaseName(testing::TestParamInfo<TaskFlavor> obj) {
148 #define CASE(x) case x: return #x;
149     switch (obj.param) {
150         CASE(BASE_TASK);
151         CASE(STAGED_TASK);
152         CASE(BASE_WITH_CALLBACK);
153         CASE(STAGED_WITH_CALLBACK);
154         default :
155             return "EMPTY";
156 #undef CASE
157     }
158 }
159
160 INSTANTIATE_TEST_CASE_P(Task, TaskCommonTests,
161                         ::testing::ValuesIn(std::vector<TaskFlavor>{BASE_TASK, STAGED_TASK}), getTestCaseName);