gtest_decorator.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2018-2019 Davide Faconti, Eurecat - All Rights Reserved
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
4 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
5 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
10 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include <gtest/gtest.h>
14 #include "action_test_node.h"
16 #include "test_helper.hpp"
17 
18 using BT::NodeStatus;
19 using std::chrono::milliseconds;
20 
21 struct DeadlineTest : testing::Test
22 {
25 
26  DeadlineTest() : root("deadline", 300), action("action", milliseconds(500))
27  {
29  }
30  ~DeadlineTest() override = default;
31 };
32 
33 struct RepeatTest : testing::Test
34 {
37 
38  RepeatTest() : root("repeat", 3), action("action")
39  {
41  }
42  ~RepeatTest() override = default;
43 };
44 
45 struct RepeatTestAsync : testing::Test
46 {
49 
50  RepeatTestAsync() : root("repeat", 3), action("action", milliseconds(100))
51  {
53  }
54  ~RepeatTestAsync() override = default;
55 };
56 
57 struct RetryTest : testing::Test
58 {
61 
62  RetryTest() : root("retry", 3), action("action")
63  {
65  }
66  ~RetryTest() override = default;
67 };
68 
69 struct TimeoutAndRetry : testing::Test
70 {
74 
75  TimeoutAndRetry() : timeout_root("deadline", 9), retry("retry", 1000), action("action")
76  {
79  }
80 };
81 
82 /****************TESTS START HERE***************************/
83 
84 TEST_F(DeadlineTest, DeadlineTriggeredTest)
85 {
86  BT::NodeStatus state = root.executeTick();
87  // deadline in 300 ms, action requires 500 ms
88 
89  ASSERT_EQ(NodeStatus::RUNNING, action.status());
90  ASSERT_EQ(NodeStatus::RUNNING, state);
91 
92  std::this_thread::sleep_for(std::chrono::milliseconds(400));
93  state = root.executeTick();
94  ASSERT_EQ(NodeStatus::FAILURE, state);
95  ASSERT_EQ(NodeStatus::IDLE, action.status());
96 }
97 
98 TEST_F(DeadlineTest, DeadlineNotTriggeredTest)
99 {
100  action.setTime(milliseconds(200));
101  // deadline in 300 ms
102 
103  BT::NodeStatus state = root.executeTick();
104 
105  ASSERT_EQ(NodeStatus::RUNNING, action.status());
106  ASSERT_EQ(NodeStatus::RUNNING, state);
107 
108  std::this_thread::sleep_for(std::chrono::milliseconds(400));
109  state = root.executeTick();
110  ASSERT_EQ(NodeStatus::IDLE, action.status());
111  ASSERT_EQ(NodeStatus::SUCCESS, state);
112 }
113 
114 TEST_F(RetryTest, RetryTestA)
115 {
116  action.setExpectedResult(NodeStatus::FAILURE);
117 
118  root.executeTick();
119  ASSERT_EQ(NodeStatus::FAILURE, root.status());
120  ASSERT_EQ(3, action.tickCount());
121 
122  action.setExpectedResult(NodeStatus::SUCCESS);
123  action.resetTicks();
124 
125  root.executeTick();
126  ASSERT_EQ(NodeStatus::SUCCESS, root.status());
127  ASSERT_EQ(1, action.tickCount());
128 }
129 
131 {
132  action.setExpectedResult(NodeStatus::SUCCESS);
133 
134  auto res = root.executeTick();
135 
136  while(res == NodeStatus::RUNNING)
137  {
138  std::this_thread::sleep_for(std::chrono::milliseconds(20));
139  res = root.executeTick();
140  }
141 
142  ASSERT_EQ(NodeStatus::SUCCESS, root.status());
143  ASSERT_EQ(3, action.successCount());
144  ASSERT_EQ(0, action.failureCount());
145 
146  //-------------------
147  action.setExpectedResult(NodeStatus::FAILURE);
148  action.resetCounters();
149 
150  res = root.executeTick();
151  while(res == NodeStatus::RUNNING)
152  {
153  std::this_thread::sleep_for(std::chrono::milliseconds(20));
154  res = root.executeTick();
155  }
156 
157  ASSERT_EQ(NodeStatus::FAILURE, root.status());
158  ASSERT_EQ(0, action.successCount());
159  ASSERT_EQ(1, action.failureCount());
160 }
161 
162 TEST_F(RepeatTest, RepeatTestA)
163 {
164  action.setExpectedResult(NodeStatus::FAILURE);
165 
166  root.executeTick();
167  ASSERT_EQ(NodeStatus::FAILURE, root.status());
168  ASSERT_EQ(1, action.tickCount());
169 
170  //-------------------
171  action.resetTicks();
172  action.setExpectedResult(NodeStatus::SUCCESS);
173 
174  root.executeTick();
175  ASSERT_EQ(NodeStatus::SUCCESS, root.status());
176  ASSERT_EQ(3, action.tickCount());
177 }
178 
179 // https://github.com/BehaviorTree/BehaviorTree.CPP/issues/57
181 {
182  action.setExpectedResult(NodeStatus::FAILURE);
183 
184  auto t1 = std::chrono::high_resolution_clock::now();
185 
186  while(std::chrono::high_resolution_clock::now() < t1 + std::chrono::seconds(2))
187  {
188  ASSERT_NE(timeout_root.executeTick(), BT::NodeStatus::IDLE);
189  std::this_thread::sleep_for(std::chrono::microseconds(50));
190  }
191 }
192 
193 TEST(Decorator, RunOnce)
194 {
195  BT::BehaviorTreeFactory factory;
196  std::array<int, 2> counters;
197  RegisterTestTick(factory, "Test", counters);
198 
199  const std::string xml_text = R"(
200  <root BTCPP_format="4" >
201  <BehaviorTree>
202  <Sequence>
203  <RunOnce> <TestA/> </RunOnce>
204  <TestB/>
205  </Sequence>
206  </BehaviorTree>
207  </root>)";
208 
209  auto tree = factory.createTreeFromText(xml_text);
210 
211  for(int i = 0; i < 5; i++)
212  {
213  NodeStatus status = tree.tickWhileRunning();
214  ASSERT_EQ(status, NodeStatus::SUCCESS);
215  }
216  // counters[0] contains the number ot times TestA was ticked
217  ASSERT_EQ(counters[0], 1);
218  // counters[1] contains the number ot times TestB was ticked
219  ASSERT_EQ(counters[1], 5);
220 }
TimeoutAndRetry
Definition: gtest_decorator.cpp:69
DeadlineTest::DeadlineTest
DeadlineTest()
Definition: gtest_decorator.cpp:26
TimeoutAndRetry::TimeoutAndRetry
TimeoutAndRetry()
Definition: gtest_decorator.cpp:75
RetryTest::root
BT::RetryNode root
Definition: gtest_decorator.cpp:59
RepeatTestAsync::~RepeatTestAsync
~RepeatTestAsync() override=default
RepeatTest
Definition: gtest_decorator.cpp:33
RegisterTestTick
void RegisterTestTick(BT::BehaviorTreeFactory &factory, const std::string &name_prefix, std::array< int, N > &tick_counters)
Definition: test_helper.hpp:15
RepeatTest::~RepeatTest
~RepeatTest() override=default
TEST_F
TEST_F(DeadlineTest, DeadlineTriggeredTest)
Definition: gtest_decorator.cpp:84
RepeatTestAsync::action
BT::AsyncActionTest action
Definition: gtest_decorator.cpp:48
TimeoutAndRetry::action
BT::SyncActionTest action
Definition: gtest_decorator.cpp:73
bt_factory.h
BT::AsyncActionTest
Definition: action_test_node.h:32
RetryTest::RetryTest
RetryTest()
Definition: gtest_decorator.cpp:62
BT::SyncActionTest
Definition: action_test_node.h:8
RepeatTest::root
BT::RepeatNode root
Definition: gtest_decorator.cpp:35
test_helper.hpp
RepeatTestAsync::root
BT::RepeatNode root
Definition: gtest_decorator.cpp:47
BT::RetryNode
The RetryNode is used to execute a child several times if it fails.
Definition: retry_node.h:39
BT::BehaviorTreeFactory::createTreeFromText
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
createTreeFromText will parse the XML directly from string. The XML needs to contain either a single ...
Definition: bt_factory.cpp:395
RepeatTest::RepeatTest
RepeatTest()
Definition: gtest_decorator.cpp:38
TimeoutAndRetry::retry
BT::RetryNode retry
Definition: gtest_decorator.cpp:72
DeadlineTest
Definition: gtest_decorator.cpp:21
BT::BehaviorTreeFactory
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:205
TEST
TEST(Decorator, RunOnce)
Definition: gtest_decorator.cpp:193
RepeatTest::action
BT::SyncActionTest action
Definition: gtest_decorator.cpp:36
DeadlineTest::~DeadlineTest
~DeadlineTest() override=default
RetryTest::~RetryTest
~RetryTest() override=default
action_test_node.h
RetryTest
Definition: gtest_decorator.cpp:57
BT::DecoratorNode::setChild
void setChild(TreeNode *child)
Definition: decorator_node.cpp:22
BT::NodeStatus::IDLE
@ IDLE
RetryTest::action
BT::SyncActionTest action
Definition: gtest_decorator.cpp:60
RepeatTestAsync
Definition: gtest_decorator.cpp:45
DeadlineTest::root
BT::TimeoutNode root
Definition: gtest_decorator.cpp:23
DeadlineTest::action
BT::AsyncActionTest action
Definition: gtest_decorator.cpp:24
BT::TimeoutNode
The TimeoutNode will halt() a running child if the latter has been RUNNING longer than a given time....
Definition: timeout_node.h:35
RepeatTestAsync::RepeatTestAsync
RepeatTestAsync()
Definition: gtest_decorator.cpp:50
TimeoutAndRetry::timeout_root
BT::TimeoutNode timeout_root
Definition: gtest_decorator.cpp:71
BT::RepeatNode
The RepeatNode is used to execute a child several times, as long as it succeed.
Definition: repeat_node.h:35
xml_text
static const char * xml_text
Definition: ex01_wrap_legacy.cpp:52
BT::NodeStatus
NodeStatus
Definition: basic_types.h:33


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:07