Periodicly clean up command queue and remove old processed commands
Do periodic command queue cleanup to reclaim memory from commands
that have been in terminal state for certain period of time (5 mins).
Change-Id: Ief9cdbf023a222412c296644c9e927c4be000024
Reviewed-on: https://weave-review.googlesource.com/2434
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/src/commands/command_queue_unittest.cc b/src/commands/command_queue_unittest.cc
index fdb9e81..1e2e0ac 100644
--- a/src/commands/command_queue_unittest.cc
+++ b/src/commands/command_queue_unittest.cc
@@ -10,12 +10,18 @@
#include <base/bind.h>
#include <base/memory/weak_ptr.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <weave/provider/test/fake_task_runner.h>
+#include "src/bind_lambda.h"
#include "src/string_utils.h"
namespace weave {
+using testing::Return;
+using testing::StrictMock;
+
class CommandQueueTest : public testing::Test {
public:
std::unique_ptr<CommandInstance> CreateDummyCommandInstance(
@@ -30,11 +36,15 @@
bool Remove(const std::string& id) { return queue_.Remove(id); }
void Cleanup(const base::TimeDelta& interval) {
- queue_.SetNowForTest(base::Time::Now() + interval);
- return queue_.Cleanup();
+ return queue_.Cleanup(task_runner_.GetClock()->Now() + interval);
}
- CommandQueue queue_;
+ std::string GetFirstCommandToBeRemoved() const {
+ return queue_.remove_queue_.top().second;
+ }
+
+ StrictMock<provider::test::FakeTaskRunner> task_runner_;
+ CommandQueue queue_{&task_runner_, task_runner_.GetClock()};
};
// Keeps track of commands being added to and removed from the queue_.
@@ -120,6 +130,46 @@
EXPECT_EQ(0u, queue_.GetCount());
}
+TEST_F(CommandQueueTest, RemoveLaterOnCleanupTask) {
+ const std::string id1 = "id1";
+ queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
+ EXPECT_EQ(1u, queue_.GetCount());
+
+ queue_.RemoveLater(id1);
+ EXPECT_EQ(1u, queue_.GetCount());
+ ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
+
+ task_runner_.RunOnce();
+
+ EXPECT_EQ(0u, queue_.GetCount());
+ EXPECT_EQ(0u, task_runner_.GetTaskQueueSize());
+}
+
+TEST_F(CommandQueueTest, CleanupMultipleCommands) {
+ const std::string id1 = "id1";
+ const std::string id2 = "id2";
+
+ queue_.Add(CreateDummyCommandInstance("base.reboot", id1));
+ queue_.Add(CreateDummyCommandInstance("base.reboot", id2));
+ auto remove_task = [this](const std::string& id) { queue_.RemoveLater(id); };
+ remove_task(id1);
+ task_runner_.PostDelayedTask(FROM_HERE, base::Bind(remove_task, id2),
+ base::TimeDelta::FromSeconds(10));
+ EXPECT_EQ(2u, queue_.GetCount());
+ ASSERT_EQ(2u, task_runner_.GetTaskQueueSize());
+ task_runner_.RunOnce(); // Executes "remove_task(id2) @ T+10s".
+ ASSERT_EQ(2u, queue_.GetCount());
+ ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
+ EXPECT_EQ(id1, GetFirstCommandToBeRemoved());
+ task_runner_.RunOnce(); // Should remove task "id1" from queue.
+ ASSERT_EQ(1u, queue_.GetCount());
+ ASSERT_EQ(1u, task_runner_.GetTaskQueueSize());
+ EXPECT_EQ(id2, GetFirstCommandToBeRemoved());
+ task_runner_.RunOnce(); // Should remove task "id2" from queue.
+ EXPECT_EQ(0u, queue_.GetCount());
+ EXPECT_EQ(0u, task_runner_.GetTaskQueueSize());
+}
+
TEST_F(CommandQueueTest, Dispatch) {
FakeDispatcher dispatch(&queue_);
const std::string id1 = "id1";