| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium 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 |
| 5 #include "blimp/net/helium/syncable.h" |
| 6 |
| 7 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 #include "testing/gmock/include/gmock/gmock.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 namespace blimp { |
| 13 namespace { |
| 14 |
| 15 // This is a sample implementation that demostrates the implementation |
| 16 // of the SyncableMember and SyncableObject |
| 17 |
| 18 // For simplicity of this example, the ChangeSet will be an integer. |
| 19 class IntValueSyncable : public SyncableMember<int> { |
| 20 public: |
| 21 explicit IntValueSyncable(SyncableObject* parent) |
| 22 : SyncableMember(parent), value_(0) { |
| 23 last_modified_ = parent_->clock(); |
| 24 } |
| 25 |
| 26 bool ModifiedSince(const VectorClock& from) override { |
| 27 return from.local_revision() < last_modified_.local_revision(); |
| 28 } |
| 29 |
| 30 std::unique_ptr<int> CreateChangesetToCurrent( |
| 31 const VectorClock& from) override { |
| 32 return base::MakeUnique<int>(value_); |
| 33 } |
| 34 |
| 35 void ApplyChangeset(const VectorClock& from, |
| 36 const VectorClock& to, |
| 37 std::unique_ptr<int> changeset) override { |
| 38 // Restore the value |
| 39 value_ = *changeset; |
| 40 |
| 41 // Update our clock to the latest clock |
| 42 last_modified_ = to; |
| 43 } |
| 44 |
| 45 void ReleaseCheckpointsBefore(const VectorClock& checkpoint) override { |
| 46 last_modified_ = checkpoint; |
| 47 } |
| 48 |
| 49 void SetValue(int value) { |
| 50 value_ = value; |
| 51 |
| 52 // Increment the parent clock and update our last_modified_ value |
| 53 last_modified_ = IncrementParentClock(); |
| 54 } |
| 55 |
| 56 int value() { return value_; } |
| 57 |
| 58 private: |
| 59 // The last time this object was changed |
| 60 VectorClock last_modified_; |
| 61 int32_t value_; |
| 62 |
| 63 DISALLOW_COPY_AND_ASSIGN(IntValueSyncable); |
| 64 }; |
| 65 |
| 66 class ParentObjectSyncable : public SyncableObject { |
| 67 public: |
| 68 explicit ParentObjectSyncable(VectorClock clock) |
| 69 : SyncableObject(clock), child1_(this), child2_(this) {} |
| 70 |
| 71 std::unique_ptr<helium::ChangesetMessage> CreateChangesetToCurrent( |
| 72 const VectorClock& from) override { |
| 73 std::unique_ptr<helium::ChangesetMessage> changeset = |
| 74 base::MakeUnique<helium::ChangesetMessage>(); |
| 75 |
| 76 helium::TestChangesetMessage* bm = changeset->mutable_test(); |
| 77 |
| 78 if (child1_.ModifiedSince(from)) { |
| 79 std::unique_ptr<int> value1 = child1_.CreateChangesetToCurrent(from); |
| 80 bm->set_value1(*value1); |
| 81 } |
| 82 |
| 83 if (child2_.ModifiedSince(from)) { |
| 84 std::unique_ptr<int> value2 = child2_.CreateChangesetToCurrent(from); |
| 85 bm->set_value2(*value2); |
| 86 } |
| 87 |
| 88 return changeset; |
| 89 } |
| 90 |
| 91 void ApplyChangeset( |
| 92 const VectorClock& from, |
| 93 const VectorClock& to, |
| 94 std::unique_ptr<helium::ChangesetMessage> changeset) override { |
| 95 helium::TestChangesetMessage bm = changeset->test(); |
| 96 |
| 97 int child1_value = bm.value1(); |
| 98 if (child1_value != 0) { |
| 99 child1_.ApplyChangeset(from, to, base::MakeUnique<int>(child1_value)); |
| 100 } |
| 101 |
| 102 int child2_value = bm.value2(); |
| 103 if (child2_value != 0) { |
| 104 child2_.ApplyChangeset(from, to, base::MakeUnique<int>(child2_value)); |
| 105 } |
| 106 } |
| 107 |
| 108 void ReleaseCheckpointsBefore(const VectorClock& checkpoint) override { |
| 109 child1_.ReleaseCheckpointsBefore(checkpoint); |
| 110 child2_.ReleaseCheckpointsBefore(checkpoint); |
| 111 } |
| 112 |
| 113 IntValueSyncable& get_child1() { return child1_; } |
| 114 IntValueSyncable& get_child2() { return child2_; } |
| 115 |
| 116 private: |
| 117 IntValueSyncable child1_; |
| 118 IntValueSyncable child2_; |
| 119 |
| 120 DISALLOW_COPY_AND_ASSIGN(ParentObjectSyncable); |
| 121 }; |
| 122 |
| 123 class SyncableTest : public testing::Test { |
| 124 public: |
| 125 SyncableTest() |
| 126 : last_sync_local_(), |
| 127 last_sync_remote_(), |
| 128 parent_local_(last_sync_local_), |
| 129 parent_remote_(last_sync_remote_) {} |
| 130 |
| 131 ~SyncableTest() override {} |
| 132 |
| 133 protected: |
| 134 VectorClock last_sync_local_; |
| 135 VectorClock last_sync_remote_; |
| 136 ParentObjectSyncable parent_local_; |
| 137 ParentObjectSyncable parent_remote_; |
| 138 |
| 139 private: |
| 140 DISALLOW_COPY_AND_ASSIGN(SyncableTest); |
| 141 }; |
| 142 |
| 143 TEST_F(SyncableTest, DemoAPITest) { |
| 144 // Lets modify a children object |
| 145 parent_local_.get_child1().SetValue(123); |
| 146 |
| 147 // At this point |child1| and |parentObject| should have its clock incremented |
| 148 // whereas |child2| should still be the same. |
| 149 EXPECT_TRUE(parent_local_.get_child1().ModifiedSince(last_sync_local_)); |
| 150 EXPECT_FALSE(parent_local_.get_child2().ModifiedSince(last_sync_local_)); |
| 151 |
| 152 std::unique_ptr<helium::ChangesetMessage> changeset = |
| 153 parent_local_.CreateChangesetToCurrent(last_sync_local_); |
| 154 |
| 155 VectorClock local_clock = parent_local_.clock(); |
| 156 VectorClock remote_clock = local_clock.Invert(); |
| 157 |
| 158 parent_remote_.ApplyChangeset(last_sync_remote_, remote_clock, |
| 159 std::move(changeset)); |
| 160 last_sync_local_ = local_clock; |
| 161 parent_local_.ReleaseCheckpointsBefore(local_clock); |
| 162 EXPECT_FALSE(parent_local_.get_child1().ModifiedSince(last_sync_local_)); |
| 163 EXPECT_FALSE(parent_local_.get_child2().ModifiedSince(last_sync_local_)); |
| 164 |
| 165 EXPECT_EQ(123, parent_remote_.get_child1().value()); |
| 166 EXPECT_EQ(0, parent_remote_.get_child2().value()); |
| 167 } |
| 168 |
| 169 } // namespace |
| 170 } // namespace blimp |
| OLD | NEW |