blob: 3e4b6ab995378ecafeeccfce4d2380618c6aeadb [file] [log] [blame]
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymof6cbe322014-11-10 19:55:35 -08005#include "buffet/commands/command_queue.h"
6
Alex Vakulenko515b42b2014-08-07 15:46:31 -07007#include <set>
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -07008#include <string>
Alex Vakulenko515b42b2014-08-07 15:46:31 -07009#include <vector>
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070010
Alex Vakulenkoa8b95bc2014-08-27 11:00:57 -070011#include <chromeos/strings/string_utils.h>
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070012#include <gtest/gtest.h>
13
Anton Muhincfde8692014-11-25 03:36:59 +040014#include "buffet/commands/command_definition.h"
Alex Vakulenko515b42b2014-08-07 15:46:31 -070015#include "buffet/commands/command_dispatch_interface.h"
Anton Muhincfde8692014-11-25 03:36:59 +040016#include "buffet/commands/object_schema.h"
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070017
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070018namespace buffet {
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070019
Alex Vakulenko5ef75792015-03-19 15:50:44 -070020class CommandQueueTest : public testing::Test {
21 public:
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070022 std::unique_ptr<CommandInstance> CreateDummyCommandInstance(
23 const std::string& name,
24 const std::string& id) {
25 std::unique_ptr<CommandInstance> cmd{
26 new CommandInstance{name, &command_definition_, {}}};
Alex Vakulenko5ef75792015-03-19 15:50:44 -070027 cmd->SetID(id);
28 return cmd;
29 }
30
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070031 bool Remove(const std::string& id) { return queue_.Remove(id); }
32
33 void Cleanup(const base::TimeDelta& interval) {
34 queue_.SetNowForTest(base::Time::Now() + interval);
35 return queue_.Cleanup();
36 }
37
38 CommandQueue queue_;
39
Alex Vakulenko5ef75792015-03-19 15:50:44 -070040 private:
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070041 CommandDefinition command_definition_{"powerd",
42 ObjectSchema::Create(),
43 ObjectSchema::Create()};
Alex Vakulenko5ef75792015-03-19 15:50:44 -070044};
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070045
Alex Vakulenko515b42b2014-08-07 15:46:31 -070046// Fake implementation of CommandDispachInterface.
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070047// Just keeps track of commands being added to and removed from the queue_.
Alex Vakulenko515b42b2014-08-07 15:46:31 -070048// Aborts if duplicate commands are added or non-existent commands are removed.
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070049class FakeDispatchInterface : public CommandDispachInterface {
Alex Vakulenko515b42b2014-08-07 15:46:31 -070050 public:
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070051 void OnCommandAdded(CommandInstance* command_instance) override {
Alex Vakulenkofedc4872014-08-20 12:38:43 -070052 CHECK(ids_.insert(command_instance->GetID()).second)
53 << "Command ID already exists: " << command_instance->GetID();
Alex Vakulenko515b42b2014-08-07 15:46:31 -070054 CHECK(commands_.insert(command_instance).second)
55 << "Command instance already exists";
56 }
57
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070058 void OnCommandRemoved(CommandInstance* command_instance) override {
Alex Vakulenkofedc4872014-08-20 12:38:43 -070059 CHECK_EQ(1, ids_.erase(command_instance->GetID()))
60 << "Command ID not found: " << command_instance->GetID();
Alex Vakulenko515b42b2014-08-07 15:46:31 -070061 CHECK_EQ(1, commands_.erase(command_instance))
62 << "Command instance not found";
63 }
64
65 // Get the comma-separated list of command IDs currently accumulated in the
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070066 // command queue_.
Alex Vakulenko515b42b2014-08-07 15:46:31 -070067 std::string GetIDs() const {
Alex Vakulenkob8fc1df2014-08-20 15:38:07 -070068 using chromeos::string_utils::Join;
Vitaly Bukadb770e72015-03-10 19:33:33 -070069 return Join(",", std::vector<std::string>(ids_.begin(), ids_.end()));
Alex Vakulenko515b42b2014-08-07 15:46:31 -070070 }
71
72 private:
73 std::set<std::string> ids_;
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070074 std::set<CommandInstance*> commands_;
Alex Vakulenko515b42b2014-08-07 15:46:31 -070075};
76
Alex Vakulenko5ef75792015-03-19 15:50:44 -070077TEST_F(CommandQueueTest, Empty) {
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070078 EXPECT_TRUE(queue_.IsEmpty());
79 EXPECT_EQ(0, queue_.GetCount());
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070080}
81
Alex Vakulenko5ef75792015-03-19 15:50:44 -070082TEST_F(CommandQueueTest, Add) {
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070083 queue_.Add(CreateDummyCommandInstance("base.reboot", "id1"));
84 queue_.Add(CreateDummyCommandInstance("base.reboot", "id2"));
85 queue_.Add(CreateDummyCommandInstance("base.reboot", "id3"));
86 EXPECT_EQ(3, queue_.GetCount());
87 EXPECT_FALSE(queue_.IsEmpty());
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070088}
89
Alex Vakulenko5ef75792015-03-19 15:50:44 -070090TEST_F(CommandQueueTest, Remove) {
Anton Muhin5191e812014-10-30 17:49:48 +040091 const std::string id1 = "id1";
92 const std::string id2 = "id2";
Vitaly Buka2a9b30f2015-04-01 10:51:59 -070093 queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
94 queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
95 EXPECT_FALSE(queue_.IsEmpty());
96 EXPECT_FALSE(Remove("dummy"));
97 EXPECT_EQ(2, queue_.GetCount());
98 EXPECT_TRUE(Remove(id1));
99 EXPECT_EQ(1, queue_.GetCount());
100 EXPECT_FALSE(Remove(id1));
101 EXPECT_EQ(1, queue_.GetCount());
102 EXPECT_TRUE(Remove(id2));
103 EXPECT_EQ(0, queue_.GetCount());
104 EXPECT_FALSE(Remove(id2));
105 EXPECT_EQ(0, queue_.GetCount());
106 EXPECT_TRUE(queue_.IsEmpty());
107}
108
109TEST_F(CommandQueueTest, DelayedRemove) {
110 const std::string id1 = "id1";
111 queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
112 EXPECT_EQ(1, queue_.GetCount());
113
114 queue_.DelayedRemove(id1);
115 EXPECT_EQ(1, queue_.GetCount());
116
117 Cleanup(base::TimeDelta::FromMinutes(1));
118 EXPECT_EQ(1, queue_.GetCount());
119
120 Cleanup(base::TimeDelta::FromMinutes(15));
121 EXPECT_EQ(0, queue_.GetCount());
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700122}
123
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700124TEST_F(CommandQueueTest, Dispatch) {
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700125 FakeDispatchInterface dispatch;
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700126 queue_.SetCommandDispachInterface(&dispatch);
Anton Muhin5191e812014-10-30 17:49:48 +0400127 const std::string id1 = "id1";
128 const std::string id2 = "id2";
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700129 queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
130 queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700131 std::set<std::string> ids{id1, id2}; // Make sure they are sorted properly.
Alex Vakulenkob8fc1df2014-08-20 15:38:07 -0700132 std::string expected_set = chromeos::string_utils::Join(
Vitaly Bukadb770e72015-03-10 19:33:33 -0700133 ",", std::vector<std::string>(ids.begin(), ids.end()));
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700134 EXPECT_EQ(expected_set, dispatch.GetIDs());
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700135 Remove(id1);
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700136 EXPECT_EQ(id2, dispatch.GetIDs());
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700137 Remove(id2);
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700138 EXPECT_EQ("", dispatch.GetIDs());
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700139 queue_.SetCommandDispachInterface(nullptr);
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700140}
141
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700142TEST_F(CommandQueueTest, Find) {
Anton Muhin5191e812014-10-30 17:49:48 +0400143 const std::string id1 = "id1";
144 const std::string id2 = "id2";
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700145 queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
146 queue_.Add(CreateDummyCommandInstance("base.shutdown", id2));
147 EXPECT_EQ(nullptr, queue_.Find("dummy"));
148 auto cmd1 = queue_.Find(id1);
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700149 EXPECT_NE(nullptr, cmd1);
150 EXPECT_EQ("base.reboot", cmd1->GetName());
Alex Vakulenkofedc4872014-08-20 12:38:43 -0700151 EXPECT_EQ(id1, cmd1->GetID());
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700152 auto cmd2 = queue_.Find(id2);
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700153 EXPECT_NE(nullptr, cmd2);
154 EXPECT_EQ("base.shutdown", cmd2->GetName());
Alex Vakulenkofedc4872014-08-20 12:38:43 -0700155 EXPECT_EQ(id2, cmd2->GetID());
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700156}
Vitaly Buka2a9b30f2015-04-01 10:51:59 -0700157
158} // namespace buffet