blob: 9f26071279bc469ef79938b1abf5bbe189a9cff4 [file] [log] [blame]
Vitaly Buka4615e0d2015-10-14 15:35:12 -07001// Copyright 2015 The Weave Authors. All rights reserved.
Alex Vakulenko57123b22014-10-28 13:50:16 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Stefan Sauer2d16dfa2015-09-25 17:08:35 +02005#include "src/states/state_change_queue.h"
Alex Vakulenko57123b22014-10-28 13:50:16 -07006
Alex Deymof6cbe322014-11-10 19:55:35 -08007#include <gtest/gtest.h>
8
Stefan Sauer2d16dfa2015-09-25 17:08:35 +02009#include "src/bind_lambda.h"
10#include "src/commands/unittest_utils.h"
Anton Muhin01829452014-11-21 02:16:04 +040011
Vitaly Bukab6f015a2015-07-09 14:59:23 -070012namespace weave {
Alex Vakulenko57123b22014-10-28 13:50:16 -070013
14class StateChangeQueueTest : public ::testing::Test {
15 public:
Vitaly Bukaa647c852015-07-06 14:51:01 -070016 void SetUp() override { queue_.reset(new StateChangeQueue(100)); }
Alex Vakulenko57123b22014-10-28 13:50:16 -070017
Vitaly Bukaa647c852015-07-06 14:51:01 -070018 void TearDown() override { queue_.reset(); }
Alex Vakulenko57123b22014-10-28 13:50:16 -070019
20 std::unique_ptr<StateChangeQueue> queue_;
21};
22
23TEST_F(StateChangeQueueTest, Empty) {
24 EXPECT_TRUE(queue_->IsEmpty());
Alex Vakulenkoe7a70072015-06-25 11:36:07 -070025 EXPECT_EQ(0, queue_->GetLastStateChangeId());
Alex Vakulenko57123b22014-10-28 13:50:16 -070026 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
27}
28
29TEST_F(StateChangeQueueTest, UpdateOne) {
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070030 StateChange change{base::Time::Now(),
31 ValueMap{{"prop.name", test::make_int_prop_value(23)}}};
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070032 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(change.timestamp,
33 change.changed_properties));
Alex Vakulenko57123b22014-10-28 13:50:16 -070034 EXPECT_FALSE(queue_->IsEmpty());
Alex Vakulenkoe7a70072015-06-25 11:36:07 -070035 EXPECT_EQ(1, queue_->GetLastStateChangeId());
Alex Vakulenko57123b22014-10-28 13:50:16 -070036 auto changes = queue_->GetAndClearRecordedStateChanges();
Alex Vakulenkoe7a70072015-06-25 11:36:07 -070037 EXPECT_EQ(1, queue_->GetLastStateChangeId());
Alex Vakulenko57123b22014-10-28 13:50:16 -070038 ASSERT_EQ(1, changes.size());
39 EXPECT_EQ(change.timestamp, changes.front().timestamp);
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070040 EXPECT_EQ(change.changed_properties, changes.front().changed_properties);
Alex Vakulenko57123b22014-10-28 13:50:16 -070041 EXPECT_TRUE(queue_->IsEmpty());
42 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
43}
44
Vitaly Buka575118a2015-08-18 18:03:48 -070045// TODO(vitalybuka): Fix flakiness.
46TEST_F(StateChangeQueueTest, DISABLED_UpdateMany) {
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070047 StateChange change1{base::Time::Now(),
48 ValueMap{{"prop.name1", test::make_int_prop_value(23)}}};
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070049 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(change1.timestamp,
50 change1.changed_properties));
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070051 StateChange change2{base::Time::Now(),
52 ValueMap{
53 {"prop.name1", test::make_int_prop_value(17)},
54 {"prop.name2", test::make_double_prop_value(1.0)},
55 {"prop.name3", test::make_bool_prop_value(false)},
56 }};
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070057 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(change2.timestamp,
58 change2.changed_properties));
Alex Vakulenkoe7a70072015-06-25 11:36:07 -070059 EXPECT_EQ(2, queue_->GetLastStateChangeId());
Alex Vakulenko57123b22014-10-28 13:50:16 -070060 EXPECT_FALSE(queue_->IsEmpty());
61 auto changes = queue_->GetAndClearRecordedStateChanges();
62 ASSERT_EQ(2, changes.size());
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070063 EXPECT_EQ(change1.timestamp, changes[0].timestamp);
64 EXPECT_EQ(change1.changed_properties, changes[0].changed_properties);
65 EXPECT_EQ(change2.timestamp, changes[1].timestamp);
66 EXPECT_EQ(change2.changed_properties, changes[1].changed_properties);
Alex Vakulenko57123b22014-10-28 13:50:16 -070067 EXPECT_TRUE(queue_->IsEmpty());
68 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
69}
70
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070071TEST_F(StateChangeQueueTest, GroupByTimestamp) {
72 base::Time timestamp = base::Time::Now();
73 base::TimeDelta time_delta = base::TimeDelta::FromMinutes(1);
74
75 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070076 timestamp, ValueMap{{"prop.name1", test::make_int_prop_value(1)}}));
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070077
78 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070079 timestamp, ValueMap{{"prop.name2", test::make_int_prop_value(2)}}));
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070080
81 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070082 timestamp, ValueMap{{"prop.name1", test::make_int_prop_value(3)}}));
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070083
84 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
85 timestamp + time_delta,
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070086 ValueMap{{"prop.name1", test::make_int_prop_value(4)}}));
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070087
88 auto changes = queue_->GetAndClearRecordedStateChanges();
Alex Vakulenkoe7a70072015-06-25 11:36:07 -070089 EXPECT_EQ(4, queue_->GetLastStateChangeId());
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070090 ASSERT_EQ(2, changes.size());
91
Vitaly Buka774cdf52015-07-21 13:55:00 -070092 ValueMap expected1{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070093 {"prop.name1", test::make_int_prop_value(3)},
94 {"prop.name2", test::make_int_prop_value(2)},
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070095 };
Vitaly Buka774cdf52015-07-21 13:55:00 -070096 ValueMap expected2{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -070097 {"prop.name1", test::make_int_prop_value(4)},
Alex Vakulenkoff73cf22014-10-29 09:53:52 -070098 };
99 EXPECT_EQ(timestamp, changes[0].timestamp);
100 EXPECT_EQ(expected1, changes[0].changed_properties);
101 EXPECT_EQ(timestamp + time_delta, changes[1].timestamp);
102 EXPECT_EQ(expected2, changes[1].changed_properties);
103}
104
Alex Vakulenko57123b22014-10-28 13:50:16 -0700105TEST_F(StateChangeQueueTest, MaxQueueSize) {
106 queue_.reset(new StateChangeQueue(2));
107 base::Time start_time = base::Time::Now();
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700108 base::TimeDelta time_delta1 = base::TimeDelta::FromMinutes(1);
109 base::TimeDelta time_delta2 = base::TimeDelta::FromMinutes(3);
Alex Vakulenko57123b22014-10-28 13:50:16 -0700110
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700111 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
Vitaly Buka774cdf52015-07-21 13:55:00 -0700112 start_time, ValueMap{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -0700113 {"prop.name1", test::make_int_prop_value(1)},
114 {"prop.name2", test::make_int_prop_value(2)},
Vitaly Bukaa647c852015-07-06 14:51:01 -0700115 }));
Alex Vakulenko57123b22014-10-28 13:50:16 -0700116
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700117 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
118 start_time + time_delta1,
Vitaly Buka774cdf52015-07-21 13:55:00 -0700119 ValueMap{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -0700120 {"prop.name1", test::make_int_prop_value(3)},
121 {"prop.name3", test::make_int_prop_value(4)},
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700122 }));
Alex Vakulenko57123b22014-10-28 13:50:16 -0700123
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700124 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
125 start_time + time_delta2,
Vitaly Buka774cdf52015-07-21 13:55:00 -0700126 ValueMap{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -0700127 {"prop.name10", test::make_int_prop_value(10)},
128 {"prop.name11", test::make_int_prop_value(11)},
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700129 }));
Alex Vakulenko57123b22014-10-28 13:50:16 -0700130
Alex Vakulenkoe7a70072015-06-25 11:36:07 -0700131 EXPECT_EQ(3, queue_->GetLastStateChangeId());
Alex Vakulenko57123b22014-10-28 13:50:16 -0700132 auto changes = queue_->GetAndClearRecordedStateChanges();
133 ASSERT_EQ(2, changes.size());
134
Vitaly Buka774cdf52015-07-21 13:55:00 -0700135 ValueMap expected1{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -0700136 {"prop.name1", test::make_int_prop_value(3)},
137 {"prop.name2", test::make_int_prop_value(2)},
138 {"prop.name3", test::make_int_prop_value(4)},
Alex Vakulenko57123b22014-10-28 13:50:16 -0700139 };
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700140 EXPECT_EQ(start_time + time_delta1, changes[0].timestamp);
141 EXPECT_EQ(expected1, changes[0].changed_properties);
Alex Vakulenko57123b22014-10-28 13:50:16 -0700142
Vitaly Buka774cdf52015-07-21 13:55:00 -0700143 ValueMap expected2{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -0700144 {"prop.name10", test::make_int_prop_value(10)},
145 {"prop.name11", test::make_int_prop_value(11)},
Alex Vakulenko57123b22014-10-28 13:50:16 -0700146 };
Alex Vakulenkoff73cf22014-10-29 09:53:52 -0700147 EXPECT_EQ(start_time + time_delta2, changes[1].timestamp);
148 EXPECT_EQ(expected2, changes[1].changed_properties);
Alex Vakulenko57123b22014-10-28 13:50:16 -0700149}
150
Alex Vakulenkobe4254b2015-06-26 11:34:03 -0700151TEST_F(StateChangeQueueTest, ImmediateStateChangeNotification) {
152 // When queue is empty, registering a new callback will trigger it.
153 bool called = false;
154 auto callback = [&called](StateChangeQueueInterface::UpdateID id) {
155 called = true;
156 };
157 queue_->AddOnStateUpdatedCallback(base::Bind(callback));
158 EXPECT_TRUE(called);
159}
160
161TEST_F(StateChangeQueueTest, DelayedStateChangeNotification) {
162 // When queue is not empty, registering a new callback will not trigger it.
163 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
Vitaly Buka774cdf52015-07-21 13:55:00 -0700164 base::Time::Now(), ValueMap{
Vitaly Buka0f6b2ec2015-08-20 15:35:19 -0700165 {"prop.name1", test::make_int_prop_value(1)},
166 {"prop.name2", test::make_int_prop_value(2)},
Vitaly Bukaa647c852015-07-06 14:51:01 -0700167 }));
Alex Vakulenkobe4254b2015-06-26 11:34:03 -0700168
169 auto callback = [](StateChangeQueueInterface::UpdateID id) {
170 FAIL() << "This should not be called";
171 };
172 queue_->AddOnStateUpdatedCallback(base::Bind(callback));
173}
174
Vitaly Bukab6f015a2015-07-09 14:59:23 -0700175} // namespace weave