blob: 97431b8bfefe533e0d765fba5d41bddf5370fbe9 [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
18namespace {
19
Alex Vakulenkofedc4872014-08-20 12:38:43 -070020std::unique_ptr<buffet::CommandInstance> CreateDummyCommandInstance(
Anton Muhin5191e812014-10-30 17:49:48 +040021 const std::string& name, const std::string& id) {
Anton Muhincfde8692014-11-25 03:36:59 +040022 auto command_definition = std::make_shared<const buffet::CommandDefinition>(
23 "powerd",
24 std::make_shared<const buffet::ObjectSchema>(),
25 std::make_shared<const buffet::ObjectSchema>());
Anton Muhin5191e812014-10-30 17:49:48 +040026 auto cmd = std::unique_ptr<buffet::CommandInstance>(
Anton Muhincfde8692014-11-25 03:36:59 +040027 new buffet::CommandInstance(name, command_definition, {}));
Anton Muhin5191e812014-10-30 17:49:48 +040028 cmd->SetID(id);
29 return cmd;
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070030}
31
Alex Vakulenko515b42b2014-08-07 15:46:31 -070032// Fake implementation of CommandDispachInterface.
33// Just keeps track of commands being added to and removed from the queue.
34// Aborts if duplicate commands are added or non-existent commands are removed.
35class FakeDispatchInterface : public buffet::CommandDispachInterface {
36 public:
Alex Vakulenkofedc4872014-08-20 12:38:43 -070037 void OnCommandAdded(buffet::CommandInstance* command_instance) override {
38 CHECK(ids_.insert(command_instance->GetID()).second)
39 << "Command ID already exists: " << command_instance->GetID();
Alex Vakulenko515b42b2014-08-07 15:46:31 -070040 CHECK(commands_.insert(command_instance).second)
41 << "Command instance already exists";
42 }
43
Alex Vakulenkofedc4872014-08-20 12:38:43 -070044 void OnCommandRemoved(buffet::CommandInstance* command_instance) override {
45 CHECK_EQ(1, ids_.erase(command_instance->GetID()))
46 << "Command ID not found: " << command_instance->GetID();
Alex Vakulenko515b42b2014-08-07 15:46:31 -070047 CHECK_EQ(1, commands_.erase(command_instance))
48 << "Command instance not found";
49 }
50
51 // Get the comma-separated list of command IDs currently accumulated in the
52 // command queue.
53 std::string GetIDs() const {
Alex Vakulenkob8fc1df2014-08-20 15:38:07 -070054 using chromeos::string_utils::Join;
Alex Vakulenko515b42b2014-08-07 15:46:31 -070055 return Join(',', std::vector<std::string>(ids_.begin(), ids_.end()));
56 }
57
58 private:
59 std::set<std::string> ids_;
Alex Vakulenkofedc4872014-08-20 12:38:43 -070060 std::set<buffet::CommandInstance*> commands_;
Alex Vakulenko515b42b2014-08-07 15:46:31 -070061};
62
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070063} // anonymous namespace
64
65TEST(CommandQueue, Empty) {
66 buffet::CommandQueue queue;
67 EXPECT_TRUE(queue.IsEmpty());
68 EXPECT_EQ(0, queue.GetCount());
69}
70
71TEST(CommandQueue, Add) {
72 buffet::CommandQueue queue;
Anton Muhin5191e812014-10-30 17:49:48 +040073 queue.Add(CreateDummyCommandInstance("base.reboot", "id1"));
74 queue.Add(CreateDummyCommandInstance("base.reboot", "id2"));
75 queue.Add(CreateDummyCommandInstance("base.reboot", "id3"));
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070076 EXPECT_EQ(3, queue.GetCount());
77 EXPECT_FALSE(queue.IsEmpty());
78}
79
80TEST(CommandQueue, Remove) {
81 buffet::CommandQueue queue;
Anton Muhin5191e812014-10-30 17:49:48 +040082 const std::string id1 = "id1";
83 const std::string id2 = "id2";
84 queue.Add(CreateDummyCommandInstance("base.reboot", id1));
85 queue.Add(CreateDummyCommandInstance("base.reboot", id2));
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070086 EXPECT_FALSE(queue.IsEmpty());
87 EXPECT_EQ(nullptr, queue.Remove("dummy").get());
88 EXPECT_EQ(2, queue.GetCount());
89 EXPECT_NE(nullptr, queue.Remove(id1).get());
90 EXPECT_EQ(1, queue.GetCount());
91 EXPECT_EQ(nullptr, queue.Remove(id1).get());
92 EXPECT_EQ(1, queue.GetCount());
93 EXPECT_NE(nullptr, queue.Remove(id2).get());
94 EXPECT_EQ(0, queue.GetCount());
95 EXPECT_EQ(nullptr, queue.Remove(id2).get());
96 EXPECT_EQ(0, queue.GetCount());
97 EXPECT_TRUE(queue.IsEmpty());
98}
99
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700100TEST(CommandQueue, Dispatch) {
101 FakeDispatchInterface dispatch;
102 buffet::CommandQueue queue;
103 queue.SetCommandDispachInterface(&dispatch);
Anton Muhin5191e812014-10-30 17:49:48 +0400104 const std::string id1 = "id1";
105 const std::string id2 = "id2";
106 queue.Add(CreateDummyCommandInstance("base.reboot", id1));
107 queue.Add(CreateDummyCommandInstance("base.reboot", id2));
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700108 std::set<std::string> ids{id1, id2}; // Make sure they are sorted properly.
Alex Vakulenkob8fc1df2014-08-20 15:38:07 -0700109 std::string expected_set = chromeos::string_utils::Join(
Alex Vakulenko515b42b2014-08-07 15:46:31 -0700110 ',', std::vector<std::string>(ids.begin(), ids.end()));
111 EXPECT_EQ(expected_set, dispatch.GetIDs());
112 queue.Remove(id1);
113 EXPECT_EQ(id2, dispatch.GetIDs());
114 queue.Remove(id2);
115 EXPECT_EQ("", dispatch.GetIDs());
116}
117
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700118TEST(CommandQueue, Find) {
119 buffet::CommandQueue queue;
Anton Muhin5191e812014-10-30 17:49:48 +0400120 const std::string id1 = "id1";
121 const std::string id2 = "id2";
122 queue.Add(CreateDummyCommandInstance("base.reboot", id1));
123 queue.Add(CreateDummyCommandInstance("base.shutdown", id2));
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700124 EXPECT_EQ(nullptr, queue.Find("dummy"));
125 auto cmd1 = queue.Find(id1);
126 EXPECT_NE(nullptr, cmd1);
127 EXPECT_EQ("base.reboot", cmd1->GetName());
Alex Vakulenkofedc4872014-08-20 12:38:43 -0700128 EXPECT_EQ(id1, cmd1->GetID());
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700129 auto cmd2 = queue.Find(id2);
130 EXPECT_NE(nullptr, cmd2);
131 EXPECT_EQ("base.shutdown", cmd2->GetName());
Alex Vakulenkofedc4872014-08-20 12:38:43 -0700132 EXPECT_EQ(id2, cmd2->GetID());
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -0700133}