Skip to content

Commit 55e30e2

Browse files
committed
split off pruning tests
yes, most pruning happen along children of a serial container, but children for many tests comprise a lot of other containers as well. - migrated pruning tests from Connect to ConnectMockup (as the concrete implementation is not relevant for them) - added missing header to stage_mockups.h
1 parent 9428c83 commit 55e30e2

File tree

5 files changed

+147
-134
lines changed

5 files changed

+147
-134
lines changed

core/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ if (CATKIN_ENABLE_TESTING)
2525
mtc_add_gtest(test_stage.cpp)
2626
mtc_add_gtest(test_container.cpp)
2727
mtc_add_gtest(test_serial.cpp)
28+
mtc_add_gtest(test_pruning.cpp)
2829
mtc_add_gtest(test_properties.cpp)
2930
mtc_add_gtest(test_cost_terms.cpp)
3031

core/test/stage_mockups.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <moveit/task_constructor/task.h>
4+
#include <moveit/task_constructor/cost_terms.h>
45

56
#include <moveit/planning_scene/planning_scene.h>
67

@@ -31,6 +32,8 @@ struct PredefinedCosts : CostTerm
3132
double operator()(const WrappedSolution& /*s*/, std::string& /*comment*/) const override { return cost(); }
3233
};
3334

35+
constexpr double INF{ std::numeric_limits<double>::infinity() };
36+
3437
struct GeneratorMockup : public Generator
3538
{
3639
planning_scene::PlanningScenePtr ps_;

core/test/test_fallback.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
using namespace moveit::task_constructor;
1717

18-
constexpr double INF = std::numeric_limits<double>::infinity();
19-
2018
using FallbacksFixtureGenerator = TaskTestBase;
2119

2220
TEST_F(FallbacksFixtureGenerator, DISABLED_stayWithFirstSuccessful) {

core/test/test_pruning.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#include <moveit/task_constructor/task.h>
2+
3+
#include "stage_mockups.h"
4+
#include "models.h"
5+
6+
#include <list>
7+
#include <memory>
8+
9+
#include <gtest/gtest.h>
10+
11+
using namespace moveit::task_constructor;
12+
13+
using Pruning = TaskTestBase;
14+
15+
TEST_F(Pruning, PropagatorFailure) {
16+
auto back = add(t, new BackwardMockup());
17+
add(t, new GeneratorMockup({ 0 }));
18+
add(t, new ForwardMockup({ INF }));
19+
20+
EXPECT_FALSE(t.plan());
21+
ASSERT_EQ(t.solutions().size(), 0u);
22+
// ForwardMockup fails, so the backward stage should never compute
23+
EXPECT_EQ(back->runs_, 0u);
24+
}
25+
26+
TEST_F(Pruning, PruningMultiForward) {
27+
add(t, new BackwardMockup());
28+
add(t, new BackwardMockup());
29+
add(t, new GeneratorMockup());
30+
// spawn two solutions for the only incoming state
31+
add(t, new ForwardMockup(PredefinedCosts{ { 0.0, 0.0 } }, 2));
32+
// fail to extend the second solution
33+
add(t, new ForwardMockup({ 0, INF }));
34+
35+
EXPECT_TRUE(t.plan());
36+
37+
// the second (infeasible) solution in the last stage must not disable
38+
// the earlier partial solution just because they share stage solutions
39+
ASSERT_EQ(t.solutions().size(), 1u);
40+
EXPECT_EQ((*t.solutions().begin())->cost(), 0u);
41+
}
42+
43+
TEST_F(Pruning, ConnectConnectForward) {
44+
add(t, new GeneratorMockup());
45+
auto c1 = add(t, new ConnectMockup({ INF, 0, 0 })); // 1st attempt is a failue
46+
add(t, new GeneratorMockup({ 0, 10, 20 }));
47+
add(t, new ForwardMockup());
48+
auto c2 = add(t, new ConnectMockup());
49+
add(t, new GeneratorMockup({ 1, 2, 3 }));
50+
51+
t.plan();
52+
53+
ASSERT_EQ(t.solutions().size(), 3u * 2u);
54+
std::vector<double> expected_costs = { 11, 12, 13, 21, 22, 23 };
55+
auto expected_cost = expected_costs.begin();
56+
for (const auto& s : t.solutions()) {
57+
EXPECT_EQ(s->cost(), *expected_cost);
58+
++expected_cost;
59+
}
60+
EXPECT_EQ(c1->runs_, 3u);
61+
EXPECT_EQ(c2->runs_, 6u); // expect 6 instead of 9 calls
62+
}
63+
64+
TEST_F(Pruning, ConnectConnectBackward) {
65+
add(t, new GeneratorMockup({ 1, 2, 3 }));
66+
auto c1 = add(t, new ConnectMockup());
67+
add(t, new BackwardMockup());
68+
add(t, new GeneratorMockup({ 0, INF, 10, 20 })); // 2nd is a dummy to postpone creation of 3rd
69+
auto c2 = add(t, new ConnectMockup({ INF, 0, 0, 0 })); // 1st attempt is a failure
70+
add(t, new GeneratorMockup());
71+
72+
t.plan();
73+
74+
ASSERT_EQ(t.solutions().size(), 3u * 2u);
75+
std::vector<double> expected_costs = { 11, 12, 13, 21, 22, 23 };
76+
auto expected_cost = expected_costs.begin();
77+
for (const auto& s : t.solutions()) {
78+
EXPECT_EQ(s->cost(), *expected_cost);
79+
++expected_cost;
80+
}
81+
EXPECT_EQ(c1->runs_, 6u); // expect 6 instead of 9 calls
82+
EXPECT_EQ(c2->runs_, 3u);
83+
}
84+
85+
TEST_F(Pruning, PropagateIntoContainer) {
86+
add(t, new BackwardMockup({ INF }));
87+
add(t, new GeneratorMockup({ 0 }));
88+
89+
auto inner = add(t, new SerialContainer());
90+
auto con = add(*inner, new ConnectMockup());
91+
add(*inner, new GeneratorMockup({ 0 }));
92+
93+
EXPECT_FALSE(t.plan());
94+
95+
// the failure in the backward stage (outside the container)
96+
// should prune the expected computation of con inside the container
97+
EXPECT_EQ(con->runs_, 0u);
98+
}
99+
100+
TEST_F(Pruning, PropagateFromContainerPull) {
101+
auto back = add(t, new BackwardMockup());
102+
add(t, new BackwardMockup());
103+
add(t, new GeneratorMockup({ 0 }));
104+
105+
auto inner = add(t, new SerialContainer());
106+
add(*inner, new ForwardMockup());
107+
add(*inner, new ForwardMockup({ INF }));
108+
109+
EXPECT_FALSE(t.plan());
110+
111+
// the failure inside the container should prune computing of back
112+
EXPECT_EQ(back->runs_, 0u);
113+
}
114+
115+
TEST_F(Pruning, PropagateFromContainerPush) {
116+
auto inner = add(t, new SerialContainer());
117+
add(*inner, new BackwardMockup({ INF }));
118+
119+
add(t, new GeneratorMockup({ 0 }));
120+
auto con = add(t, new ConnectMockup());
121+
add(t, new GeneratorMockup({ 0 }));
122+
123+
EXPECT_FALSE(t.plan());
124+
125+
// the failure inside container should prune computing of con
126+
EXPECT_EQ(con->runs_, 0u);
127+
}
128+
129+
TEST_F(Pruning, PropagateFromParallelContainerMultiplePaths) {
130+
auto back = add(t, new BackwardMockup());
131+
add(t, new GeneratorMockup({ 0 }));
132+
auto inner = add(t, new Alternatives());
133+
134+
add(*inner, new ForwardMockup({ INF }));
135+
auto serial = add(*inner, new SerialContainer());
136+
add(*serial, new ConnectMockup());
137+
add(*serial, new GeneratorMockup({ 0 }));
138+
139+
EXPECT_TRUE(t.plan());
140+
141+
// the failure in one branch of Alternatives must not prune computing back
142+
EXPECT_EQ(back->runs_, 1u);
143+
}

core/test/test_serial.cpp

Lines changed: 0 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ struct Connect : stages::Connect
3939
}
4040
};
4141

42-
constexpr double INF = std::numeric_limits<double>::infinity();
4342
unsigned int Connect::id_ = 0;
4443

4544
struct TestBase : public TaskTestBase
@@ -77,134 +76,3 @@ TEST_F(ConnectConnect, FailSucc) {
7776

7877
EXPECT_FALSE(t.plan());
7978
}
80-
81-
using Pruning = TestBase;
82-
TEST_F(Pruning, PropagatorFailure) {
83-
auto back = add(t, new BackwardMockup());
84-
add(t, new GeneratorMockup({ 0 }));
85-
add(t, new ForwardMockup({ INF }));
86-
87-
EXPECT_FALSE(t.plan());
88-
ASSERT_EQ(t.solutions().size(), 0u);
89-
// ForwardMockup fails, so the backward stage should never compute
90-
EXPECT_EQ(back->runs_, 0u);
91-
}
92-
93-
TEST_F(Pruning, PruningMultiForward) {
94-
add(t, new BackwardMockup());
95-
add(t, new BackwardMockup());
96-
add(t, new GeneratorMockup());
97-
// spawn two solutions for the only incoming state
98-
add(t, new ForwardMockup(PredefinedCosts{ { 0.0, 0.0 } }, 2));
99-
// fail to extend the second solution
100-
add(t, new ForwardMockup({ 0, INF }));
101-
102-
EXPECT_TRUE(t.plan());
103-
104-
// the second (infeasible) solution in the last stage must not disable
105-
// the earlier partial solution just because they share stage solutions
106-
ASSERT_EQ(t.solutions().size(), 1u);
107-
EXPECT_EQ((*t.solutions().begin())->cost(), 0u);
108-
}
109-
110-
TEST_F(Pruning, ConnectConnectForward) {
111-
add(t, new GeneratorMockup());
112-
auto c1 = add(t, new Connect({ INF, 0 })); // 1st attempt is a failue
113-
add(t, new GeneratorMockup({ 0, 10, 20 }));
114-
add(t, new ForwardMockup());
115-
auto c2 = add(t, new Connect());
116-
add(t, new GeneratorMockup({ 1, 2, 3 }));
117-
118-
t.plan();
119-
120-
ASSERT_EQ(t.solutions().size(), 3u * 2u);
121-
std::vector<double> expected_costs = { 11, 12, 13, 21, 22, 23 };
122-
auto expected_cost = expected_costs.begin();
123-
for (const auto& s : t.solutions()) {
124-
EXPECT_EQ(s->cost(), *expected_cost);
125-
++expected_cost;
126-
}
127-
EXPECT_EQ(c1->calls_, 3u);
128-
EXPECT_EQ(c2->calls_, 6u); // expect 6 instead of 9 calls
129-
}
130-
131-
TEST_F(Pruning, ConnectConnectBackward) {
132-
add(t, new GeneratorMockup({ 1, 2, 3 }));
133-
auto c1 = add(t, new Connect());
134-
add(t, new BackwardMockup());
135-
add(t, new GeneratorMockup({ 0, INF, 10, 20 })); // 2nd is a dummy to postpone creation of 3rd
136-
auto c2 = add(t, new Connect({ INF, 0 })); // 1st attempt is a failure
137-
add(t, new GeneratorMockup());
138-
139-
t.plan();
140-
141-
ASSERT_EQ(t.solutions().size(), 3u * 2u);
142-
std::vector<double> expected_costs = { 11, 12, 13, 21, 22, 23 };
143-
auto expected_cost = expected_costs.begin();
144-
for (const auto& s : t.solutions()) {
145-
EXPECT_EQ(s->cost(), *expected_cost);
146-
++expected_cost;
147-
}
148-
EXPECT_EQ(c1->calls_, 6u); // expect 6 instead of 9 calls
149-
EXPECT_EQ(c2->calls_, 3u);
150-
}
151-
152-
TEST_F(Pruning, PropagateIntoContainer) {
153-
add(t, new BackwardMockup({ INF }));
154-
add(t, new GeneratorMockup({ 0 }));
155-
156-
auto inner = add(t, new SerialContainer());
157-
auto con = add(*inner, new Connect());
158-
add(*inner, new GeneratorMockup({ 0 }));
159-
160-
EXPECT_FALSE(t.plan());
161-
162-
// the failure in the backward stage (outside the container)
163-
// should prune the expected computation of con inside the container
164-
EXPECT_EQ(con->calls_, 0u);
165-
}
166-
167-
TEST_F(Pruning, PropagateFromContainerPull) {
168-
auto back = add(t, new BackwardMockup());
169-
add(t, new BackwardMockup());
170-
add(t, new GeneratorMockup({ 0 }));
171-
172-
auto inner = add(t, new SerialContainer());
173-
add(*inner, new ForwardMockup());
174-
add(*inner, new ForwardMockup({ INF }));
175-
176-
EXPECT_FALSE(t.plan());
177-
178-
// the failure inside the container should prune computing of back
179-
EXPECT_EQ(back->runs_, 0u);
180-
}
181-
182-
TEST_F(Pruning, PropagateFromContainerPush) {
183-
auto inner = add(t, new SerialContainer());
184-
add(*inner, new BackwardMockup({ INF }));
185-
186-
add(t, new GeneratorMockup({ 0 }));
187-
auto con = add(t, new Connect());
188-
add(t, new GeneratorMockup({ 0 }));
189-
190-
EXPECT_FALSE(t.plan());
191-
192-
// the failure inside container should prune computing of con
193-
EXPECT_EQ(con->calls_, 0u);
194-
}
195-
196-
TEST_F(Pruning, PropagateFromParallelContainerMultiplePaths) {
197-
auto back = add(t, new BackwardMockup());
198-
add(t, new GeneratorMockup({ 0 }));
199-
auto inner = add(t, new Alternatives());
200-
201-
add(*inner, new ForwardMockup({ INF }));
202-
auto serial = add(*inner, new SerialContainer());
203-
add(*serial, new Connect());
204-
add(*serial, new GeneratorMockup({ 0 }));
205-
206-
EXPECT_TRUE(t.plan());
207-
208-
// the failure in one branch of Alternatives must not prune computing back
209-
EXPECT_EQ(back->runs_, 1u);
210-
}

0 commit comments

Comments
 (0)