blob: 178b2b01ed07188f2ac9c8f7b59bd6f3075206bd [file] [log] [blame]
Ben Fredricksond69f38b2015-01-28 20:06:15 -08001#include <unistd.h>
2
3#include <memory>
Brian Silvermana2ae62d2015-03-15 15:55:22 -07004#include <thread>
Austin Schuhf2a50ba2016-12-24 16:16:26 -08005#include <chrono>
Ben Fredricksond69f38b2015-01-28 20:06:15 -08006
7#include "gtest/gtest.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -05008
John Park33858a32018-09-28 23:05:48 -07009#include "aos/actions/actions.h"
10#include "aos/actions/actions.q.h"
Austin Schuh1bf8a212019-05-26 22:13:14 -070011#include "aos/actions/actor.h"
John Park33858a32018-09-28 23:05:48 -070012#include "aos/actions/test_action.q.h"
Austin Schuh1bf8a212019-05-26 22:13:14 -070013#include "aos/events/simulated-event-loop.h"
14#include "aos/queue.h"
15#include "aos/testing/test_logging.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050016#include "aos/testing/test_shm.h"
Ben Fredricksond69f38b2015-01-28 20:06:15 -080017
Ben Fredricksond69f38b2015-01-28 20:06:15 -080018namespace aos {
19namespace common {
20namespace actions {
21namespace testing {
22
Austin Schuhf2a50ba2016-12-24 16:16:26 -080023
24namespace chrono = ::std::chrono;
25
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080026class TestActorIndex
27 : public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
28 public:
Austin Schuh1bf8a212019-05-26 22:13:14 -070029 typedef TypedActionFactory<actions::TestActionQueueGroup> Factory;
30
31 explicit TestActorIndex(::aos::EventLoop *event_loop)
32 : aos::common::actions::ActorBase<actions::TestActionQueueGroup>(
33 event_loop, ".aos.common.actions.test_action") {}
34
35 static Factory MakeFactory(::aos::EventLoop *event_loop) {
36 return Factory(event_loop, ".aos.common.actions.test_action");
37 }
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080038
39 bool RunAction(const uint32_t &new_index) override {
40 index = new_index;
41 return true;
42 }
43
44 uint32_t index = 0;
45};
46
Ben Fredricksond69f38b2015-01-28 20:06:15 -080047class TestActorNOP
48 : public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
49 public:
Austin Schuh1bf8a212019-05-26 22:13:14 -070050 typedef TypedActionFactory<actions::TestActionQueueGroup> Factory;
51
52 explicit TestActorNOP(::aos::EventLoop *event_loop)
53 : actions::ActorBase<actions::TestActionQueueGroup>(
54 event_loop, ".aos.common.actions.test_action") {}
55
56 static Factory MakeFactory(::aos::EventLoop *event_loop) {
57 return Factory(event_loop, ".aos.common.actions.test_action");
58 }
Ben Fredricksond69f38b2015-01-28 20:06:15 -080059
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080060 bool RunAction(const uint32_t &) override { return true; }
Ben Fredricksond69f38b2015-01-28 20:06:15 -080061};
62
Ben Fredricksond69f38b2015-01-28 20:06:15 -080063class TestActorShouldCancel
64 : public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
65 public:
Austin Schuh1bf8a212019-05-26 22:13:14 -070066 typedef TypedActionFactory<actions::TestActionQueueGroup> Factory;
67
68 explicit TestActorShouldCancel(::aos::EventLoop *event_loop)
69 : aos::common::actions::ActorBase<actions::TestActionQueueGroup>(
70 event_loop, ".aos.common.actions.test_action") {}
71
72 static Factory MakeFactory(::aos::EventLoop *event_loop) {
73 return Factory(event_loop, ".aos.common.actions.test_action");
74 }
Ben Fredricksond69f38b2015-01-28 20:06:15 -080075
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080076 bool RunAction(const uint32_t &) override {
Ben Fredricksond69f38b2015-01-28 20:06:15 -080077 while (!ShouldCancel()) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070078 AOS_LOG(FATAL, "NOT CANCELED!!\n");
Ben Fredricksond69f38b2015-01-28 20:06:15 -080079 }
Daniel Petti3b1e48f2015-02-15 15:57:53 -080080 return true;
Ben Fredricksond69f38b2015-01-28 20:06:15 -080081 }
82};
83
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080084class TestActor2Nop
85 : public aos::common::actions::ActorBase<actions::TestAction2QueueGroup> {
86 public:
Austin Schuh1bf8a212019-05-26 22:13:14 -070087 typedef TypedActionFactory<actions::TestAction2QueueGroup> Factory;
88
89 explicit TestActor2Nop(::aos::EventLoop *event_loop)
90 : actions::ActorBase<actions::TestAction2QueueGroup>(
91 event_loop, ".aos.common.actions.test_action2") {}
92
93 static Factory MakeFactory(::aos::EventLoop *event_loop) {
94 return Factory(event_loop, ".aos.common.actions.test_action2");
95 }
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -080096
97 bool RunAction(const actions::MyParams &) { return true; }
98};
99
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800100class ActionTest : public ::testing::Test {
101 protected:
Austin Schuh1bf8a212019-05-26 22:13:14 -0700102 ActionTest()
103 : actor1_event_loop_(event_loop_factory_.MakeEventLoop()),
104 actor2_event_loop_(event_loop_factory_.MakeEventLoop()),
105 test_event_loop_(event_loop_factory_.MakeEventLoop()) {
106 ::aos::testing::EnableTestLogging();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800107 }
108
109 // Bring up and down Core.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700110 ::aos::SimulatedEventLoopFactory event_loop_factory_;
111
112 ::std::unique_ptr<::aos::EventLoop> actor1_event_loop_;
113 ::std::unique_ptr<::aos::EventLoop> actor2_event_loop_;
114 ::std::unique_ptr<::aos::EventLoop> test_event_loop_;
115
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800116};
117
118// Tests that the the actions exist in a safe state at startup.
119TEST_F(ActionTest, DoesNothing) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700120 ActionQueue action_queue;
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800121 // Tick an empty queue and make sure it was not running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700122 EXPECT_FALSE(action_queue.Running());
123 action_queue.Tick();
124 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800125}
126
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700127// Tests that starting with an old run message in the goal queue actually works.
128// This used to result in the client hanging, waiting for a response to its
129// cancel message.
130TEST_F(ActionTest, StartWithOldGoal) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700131 ::std::unique_ptr<::aos::EventLoop> test2_event_loop =
132 event_loop_factory_.MakeEventLoop();
133 ::aos::Sender<TestActionQueueGroup::Goal> goal_sender =
134 test2_event_loop->MakeSender<TestActionQueueGroup::Goal>(
135 ".aos.common.actions.test_action.goal");
136 ::aos::Fetcher<Status> status_fetcher = test2_event_loop->MakeFetcher<Status>(
137 ".aos.common.actions.test_action.status");
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700138
Austin Schuh1bf8a212019-05-26 22:13:14 -0700139 TestActorIndex::Factory nop_actor_factory =
140 TestActorNOP::MakeFactory(test_event_loop_.get());
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700141
Austin Schuh1bf8a212019-05-26 22:13:14 -0700142 ActionQueue action_queue;
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700143
Austin Schuh1bf8a212019-05-26 22:13:14 -0700144 {
145 auto goal_message = goal_sender.MakeMessage();
146 goal_message->run = 971;
147 ASSERT_TRUE(goal_message.Send());
148 }
149
150 TestActorNOP nop_act(actor1_event_loop_.get());
151
152 ASSERT_FALSE(status_fetcher.Fetch());
153
154 event_loop_factory_.RunFor(chrono::seconds(1));
155
156 ASSERT_TRUE(status_fetcher.Fetch());
157 EXPECT_EQ(0u, status_fetcher->running);
158 EXPECT_EQ(0u, status_fetcher->last_running);
159
160 action_queue.EnqueueAction(nop_actor_factory.Make(0));
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700161
162 // We started an action and it should be running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700163 EXPECT_TRUE(action_queue.Running());
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700164
Austin Schuh1bf8a212019-05-26 22:13:14 -0700165 action_queue.CancelAllActions();
166 action_queue.Tick();
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700167
Austin Schuh1bf8a212019-05-26 22:13:14 -0700168 EXPECT_TRUE(action_queue.Running());
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700169
170 // Run the action so it can signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700171 event_loop_factory_.RunFor(chrono::seconds(1));
172 action_queue.Tick();
Brian Silvermana2ae62d2015-03-15 15:55:22 -0700173
174 // Make sure it stopped.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700175 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800176}
177
178// Tests that an action starts and stops.
179TEST_F(ActionTest, ActionQueueWasRunning) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700180 TestActorNOP nop_act(actor1_event_loop_.get());
181
182 TestActorIndex::Factory nop_actor_factory =
183 TestActorNOP::MakeFactory(test_event_loop_.get());
184
185 ActionQueue action_queue;
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800186
187 // Tick an empty queue and make sure it was not running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700188 event_loop_factory_.RunFor(chrono::seconds(1));
189 action_queue.Tick();
190 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800191
Austin Schuh1bf8a212019-05-26 22:13:14 -0700192 action_queue.EnqueueAction(nop_actor_factory.Make(0));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800193
194 // We started an action and it should be running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700195 EXPECT_TRUE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800196
197 // Tick it and make sure it is still running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700198 action_queue.Tick();
199 EXPECT_TRUE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800200
201 // Run the action so it can signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700202 event_loop_factory_.RunFor(chrono::seconds(1));
203 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800204
205 // Make sure it stopped.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700206 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800207}
208
209// Tests that we can cancel two actions and have them both stop.
210TEST_F(ActionTest, ActionQueueCancelAll) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700211 TestActorNOP nop_act(actor1_event_loop_.get());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800212
Austin Schuh1bf8a212019-05-26 22:13:14 -0700213 TestActorIndex::Factory nop_actor_factory =
214 TestActorNOP::MakeFactory(test_event_loop_.get());
215
216 ActionQueue action_queue;
217
218 // Let the actor and action queue start up and confirm nothing is running.
219 event_loop_factory_.RunFor(chrono::seconds(1));
220 action_queue.Tick();
221
222 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800223
224 // Enqueue two actions to test both cancel. We can have an action and a next
225 // action so we want to test that.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700226 action_queue.EnqueueAction(nop_actor_factory.Make(0));
227 action_queue.EnqueueAction(nop_actor_factory.Make(0));
228
229 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800230
231 // Check that current and next exist.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700232 EXPECT_TRUE(action_queue.GetCurrentActionState(nullptr, nullptr, nullptr,
233 nullptr, nullptr, nullptr));
234 EXPECT_TRUE(action_queue.GetNextActionState(nullptr, nullptr, nullptr,
235 nullptr, nullptr, nullptr));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800236
Austin Schuh1bf8a212019-05-26 22:13:14 -0700237 action_queue.CancelAllActions();
238 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800239
240 // It should still be running as the actor could not have signaled.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700241 EXPECT_TRUE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800242
243 bool sent_started, sent_cancel, interrupted;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700244 EXPECT_TRUE(action_queue.GetCurrentActionState(
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800245 nullptr, &sent_started, &sent_cancel, &interrupted, nullptr, nullptr));
246 EXPECT_TRUE(sent_started);
247 EXPECT_TRUE(sent_cancel);
248 EXPECT_FALSE(interrupted);
249
Austin Schuh1bf8a212019-05-26 22:13:14 -0700250 EXPECT_FALSE(action_queue.GetNextActionState(nullptr, nullptr, nullptr,
251 nullptr, nullptr, nullptr));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800252
253 // Run the action so it can signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700254 event_loop_factory_.RunFor(chrono::seconds(1));
255
256 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800257
258 // Make sure it stopped.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700259 EXPECT_FALSE(action_queue.Running());
260 EXPECT_EQ(1, nop_act.running_count());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800261}
262
263// Tests that an action that would block forever stops when canceled.
264TEST_F(ActionTest, ActionQueueCancelOne) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700265 TestActorShouldCancel cancel_act(actor1_event_loop_.get());
266
267 TestActorShouldCancel::Factory cancel_action_factory =
268 TestActorShouldCancel::MakeFactory(test_event_loop_.get());
269
270 ActionQueue action_queue;
271
272 // Let the actor and action queue start up.
273 event_loop_factory_.RunFor(chrono::seconds(1));
274 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800275
276 // Enqueue blocking action.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700277 action_queue.EnqueueAction(cancel_action_factory.Make(0));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800278
Austin Schuh1bf8a212019-05-26 22:13:14 -0700279 action_queue.Tick();
280 EXPECT_TRUE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800281
282 // Tell action to cancel.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700283 action_queue.CancelCurrentAction();
284 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800285
286 // This will block forever on failure.
287 // TODO(ben): prolly a bad way to fail
Austin Schuh1bf8a212019-05-26 22:13:14 -0700288 event_loop_factory_.RunFor(chrono::seconds(1));
289 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800290
291 // It should still be running as the actor could not have signalled.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700292 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800293}
294
Austin Schuh1bf8a212019-05-26 22:13:14 -0700295// Tests that 2 actions in a row causes the second one to cancel the first one.
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800296TEST_F(ActionTest, ActionQueueTwoActions) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700297 TestActorNOP nop_actor(actor1_event_loop_.get());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800298
Austin Schuh1bf8a212019-05-26 22:13:14 -0700299 TestActorIndex::Factory nop_actor_factory =
300 TestActorNOP::MakeFactory(test_event_loop_.get());
301
302 ActionQueue action_queue;
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800303 // Tick an empty queue and make sure it was not running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700304 event_loop_factory_.RunFor(chrono::seconds(1));
305 action_queue.Tick();
306 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800307
308 // Enqueue action to be canceled.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700309 action_queue.EnqueueAction(nop_actor_factory.Make(0));
310 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800311
312 // Should still be running as the actor could not have signalled.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700313 EXPECT_TRUE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800314
315 // id for the first time run.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700316 uint32_t nop_actor_id = 0;
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800317 // Check the internal state and write down id for later use.
318 bool sent_started, sent_cancel, interrupted;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700319 EXPECT_TRUE(action_queue.GetCurrentActionState(nullptr, &sent_started,
320 &sent_cancel, &interrupted,
321 &nop_actor_id, nullptr));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800322 EXPECT_TRUE(sent_started);
323 EXPECT_FALSE(sent_cancel);
324 EXPECT_FALSE(interrupted);
Austin Schuh1bf8a212019-05-26 22:13:14 -0700325 ASSERT_NE(0u, nop_actor_id);
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800326
327 // Add the next action which should ensure the first stopped.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700328 action_queue.EnqueueAction(nop_actor_factory.Make(0));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800329
330 // id for the second run.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700331 uint32_t nop_actor2_id = 0;
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800332 // Check the internal state and write down id for later use.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700333 EXPECT_TRUE(action_queue.GetNextActionState(nullptr, &sent_started,
334 &sent_cancel, &interrupted,
335 &nop_actor2_id, nullptr));
336 EXPECT_NE(nop_actor_id, nop_actor2_id);
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800337 EXPECT_FALSE(sent_started);
338 EXPECT_FALSE(sent_cancel);
339 EXPECT_FALSE(interrupted);
Austin Schuh1bf8a212019-05-26 22:13:14 -0700340 ASSERT_NE(0u, nop_actor2_id);
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800341
Austin Schuh1bf8a212019-05-26 22:13:14 -0700342 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800343
344 // Run the action so it can signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700345 event_loop_factory_.RunFor(chrono::seconds(1));
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800346
Austin Schuh1bf8a212019-05-26 22:13:14 -0700347 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800348
349 // Check the new action is the right one.
350 uint32_t test_id = 0;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700351 EXPECT_TRUE(action_queue.GetCurrentActionState(
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800352 nullptr, &sent_started, &sent_cancel, &interrupted, &test_id, nullptr));
353 EXPECT_TRUE(sent_started);
354 EXPECT_FALSE(sent_cancel);
355 EXPECT_FALSE(interrupted);
Austin Schuh1bf8a212019-05-26 22:13:14 -0700356 EXPECT_EQ(nop_actor2_id, test_id);
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800357
358 // Make sure it is still going.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700359 EXPECT_TRUE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800360
Austin Schuh1bf8a212019-05-26 22:13:14 -0700361 // Now let everything finish.
362 event_loop_factory_.RunFor(chrono::seconds(1));
363 action_queue.Tick();
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800364
365 // Make sure it stopped.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700366 EXPECT_FALSE(action_queue.Running());
Ben Fredricksond69f38b2015-01-28 20:06:15 -0800367}
368
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800369// Tests that we do get an index with our goal
370TEST_F(ActionTest, ActionIndex) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700371 TestActorIndex idx_actor(actor1_event_loop_.get());
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800372
Austin Schuh1bf8a212019-05-26 22:13:14 -0700373 TestActorIndex::Factory test_actor_index_factory =
374 TestActorIndex::MakeFactory(test_event_loop_.get());
375
376 ActionQueue action_queue;
377 // Tick an empty queue and make sure it was not running. Also tick the
378 // factory to allow it to send out the initial cancel message.
379 event_loop_factory_.RunFor(chrono::seconds(1));
380 action_queue.Tick();
381
382 EXPECT_FALSE(action_queue.Running());
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800383
384 // Enqueue action to post index.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700385 action_queue.EnqueueAction(test_actor_index_factory.Make(5));
386 ::aos::Fetcher<actions::TestActionQueueGroup::Goal> goal_fetcher_ =
387 test_event_loop_->MakeFetcher<actions::TestActionQueueGroup::Goal>(
388 ".aos.common.actions.test_action.goal");
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800389
Austin Schuh1bf8a212019-05-26 22:13:14 -0700390 ASSERT_TRUE(goal_fetcher_.Fetch());
391 EXPECT_EQ(5u, goal_fetcher_->params);
392 EXPECT_EQ(0u, idx_actor.index);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800393
Austin Schuh1bf8a212019-05-26 22:13:14 -0700394 action_queue.Tick();
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800395
396 // Run the next action so it can accomplish signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700397 event_loop_factory_.RunFor(chrono::seconds(1));
398
399 action_queue.Tick();
400 EXPECT_EQ(5u, idx_actor.index);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800401
402 // Enqueue action to post index.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700403 action_queue.EnqueueAction(test_actor_index_factory.Make(3));
404 ASSERT_TRUE(goal_fetcher_.Fetch());
405 EXPECT_EQ(3u, goal_fetcher_->params);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800406
407 // Run the next action so it can accomplish signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700408 event_loop_factory_.RunFor(chrono::seconds(1));
409
410 action_queue.Tick();
411 EXPECT_EQ(3u, idx_actor.index);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800412}
413
414// Tests that an action with a structure params works.
415TEST_F(ActionTest, StructParamType) {
Austin Schuh1bf8a212019-05-26 22:13:14 -0700416 TestActor2Nop nop_actor(actor2_event_loop_.get());
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800417
Austin Schuh1bf8a212019-05-26 22:13:14 -0700418 TestActor2Nop::Factory test_action_2_nop_factory =
419 TestActor2Nop::MakeFactory(test_event_loop_.get());
420
421 ActionQueue action_queue;
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800422 // Tick an empty queue and make sure it was not running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700423 action_queue.Tick();
424 EXPECT_FALSE(action_queue.Running());
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800425
426 actions::MyParams p;
427 p.param1 = 5.0;
428 p.param2 = 7;
429
Austin Schuh1bf8a212019-05-26 22:13:14 -0700430 action_queue.EnqueueAction(test_action_2_nop_factory.Make(p));
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800431
432 // We started an action and it should be running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700433 EXPECT_TRUE(action_queue.Running());
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800434
435 // Tick it and make sure it is still running.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700436 action_queue.Tick();
437 EXPECT_TRUE(action_queue.Running());
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800438
439 // Run the action so it can signal completion.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700440 // The actor takes no time, but running for a second is the best way to get it
441 // to go.
442 event_loop_factory_.RunFor(chrono::seconds(1));
443
444 action_queue.Tick();
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800445
446 // Make sure it stopped.
Austin Schuh1bf8a212019-05-26 22:13:14 -0700447 EXPECT_FALSE(action_queue.Running());
Brian Silverman237a5542015-03-29 17:59:29 -0400448}
449
450} // namespace testing
451} // namespace actions
452} // namespace common
453} // namespace aos