1// Copyright 2014 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 "sync/engine/model_thread_sync_entity.h" 6 7#include "base/memory/scoped_ptr.h" 8#include "base/time/time.h" 9#include "sync/internal_api/public/base/model_type.h" 10#include "sync/protocol/sync.pb.h" 11#include "sync/syncable/syncable_util.h" 12 13#include "testing/gtest/include/gtest/gtest.h" 14 15namespace syncer { 16 17// Some simple sanity tests for the ModelThreadSyncEntity. 18// 19// A lot of the more complicated sync logic is implemented in the 20// NonBlockingTypeProcessor that owns the ModelThreadSyncEntity. We 21// can't unit test it here. 22// 23// Instead, we focus on simple tests to make sure that variables are getting 24// properly intialized and flags properly set. Anything more complicated would 25// be a redundant and incomplete version of the NonBlockingTypeProcessor tests. 26class ModelThreadSyncEntityTest : public ::testing::Test { 27 public: 28 ModelThreadSyncEntityTest() 29 : kServerId("ServerID"), 30 kClientTag("sample.pref.name"), 31 kClientTagHash(syncable::GenerateSyncableHash(PREFERENCES, kClientTag)), 32 kCtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(10)), 33 kMtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(20)) { 34 sync_pb::PreferenceSpecifics* pref_specifics = 35 specifics.mutable_preference(); 36 pref_specifics->set_name(kClientTag); 37 pref_specifics->set_value("pref.value"); 38 } 39 40 const std::string kServerId; 41 const std::string kClientTag; 42 const std::string kClientTagHash; 43 const base::Time kCtime; 44 const base::Time kMtime; 45 sync_pb::EntitySpecifics specifics; 46}; 47 48TEST_F(ModelThreadSyncEntityTest, NewLocalItem) { 49 scoped_ptr<ModelThreadSyncEntity> entity( 50 ModelThreadSyncEntity::NewLocalItem("asdf", specifics, kCtime)); 51 52 EXPECT_TRUE(entity->IsWriteRequired()); 53 EXPECT_TRUE(entity->IsUnsynced()); 54 EXPECT_FALSE(entity->UpdateIsReflection(1)); 55 EXPECT_TRUE(entity->UpdateIsInConflict(1)); 56} 57 58TEST_F(ModelThreadSyncEntityTest, FromServerUpdate) { 59 scoped_ptr<ModelThreadSyncEntity> entity( 60 ModelThreadSyncEntity::FromServerUpdate( 61 kServerId, 62 kClientTagHash, 63 kClientTag, // As non-unique name. 64 10, 65 specifics, 66 false, 67 kCtime, 68 kMtime)); 69 70 EXPECT_TRUE(entity->IsWriteRequired()); 71 EXPECT_FALSE(entity->IsUnsynced()); 72 EXPECT_TRUE(entity->UpdateIsReflection(9)); 73 EXPECT_TRUE(entity->UpdateIsReflection(10)); 74 EXPECT_FALSE(entity->UpdateIsReflection(11)); 75 EXPECT_FALSE(entity->UpdateIsInConflict(11)); 76} 77 78// Tombstones should behave just like regular updates. Mostly. The strangest 79// thing about them is that they don't have specifics, so it can be hard to 80// detect their type. Fortunately, this class doesn't care about types in 81// received updates. 82TEST_F(ModelThreadSyncEntityTest, TombstoneUpdate) { 83 scoped_ptr<ModelThreadSyncEntity> entity( 84 ModelThreadSyncEntity::FromServerUpdate( 85 kServerId, 86 kClientTagHash, 87 kClientTag, // As non-unique name. 88 10, 89 sync_pb::EntitySpecifics(), 90 true, 91 kCtime, 92 kMtime)); 93 94 EXPECT_TRUE(entity->IsWriteRequired()); 95 EXPECT_FALSE(entity->IsUnsynced()); 96 EXPECT_TRUE(entity->UpdateIsReflection(9)); 97 EXPECT_TRUE(entity->UpdateIsReflection(10)); 98 EXPECT_FALSE(entity->UpdateIsReflection(11)); 99 EXPECT_FALSE(entity->UpdateIsInConflict(11)); 100} 101 102// Apply a deletion update. 103TEST_F(ModelThreadSyncEntityTest, ApplyUpdate) { 104 scoped_ptr<ModelThreadSyncEntity> entity( 105 ModelThreadSyncEntity::FromServerUpdate( 106 kServerId, 107 kClientTagHash, 108 kClientTag, // As non-unique name. 109 10, 110 specifics, 111 false, 112 kCtime, 113 kMtime)); 114 115 // A deletion update one version later. 116 entity->ApplyUpdateFromServer(11, 117 true, 118 sync_pb::EntitySpecifics(), 119 kMtime + base::TimeDelta::FromSeconds(10)); 120 121 EXPECT_TRUE(entity->IsWriteRequired()); 122 EXPECT_FALSE(entity->IsUnsynced()); 123 EXPECT_TRUE(entity->UpdateIsReflection(11)); 124 EXPECT_FALSE(entity->UpdateIsReflection(12)); 125} 126 127TEST_F(ModelThreadSyncEntityTest, LocalChange) { 128 scoped_ptr<ModelThreadSyncEntity> entity( 129 ModelThreadSyncEntity::FromServerUpdate( 130 kServerId, 131 kClientTagHash, 132 kClientTag, // As non-unique name. 133 10, 134 specifics, 135 false, 136 kCtime, 137 kMtime)); 138 139 sync_pb::EntitySpecifics specifics2; 140 specifics2.CopyFrom(specifics); 141 specifics2.mutable_preference()->set_value("new.pref.value"); 142 143 entity->MakeLocalChange(specifics2); 144 EXPECT_TRUE(entity->IsWriteRequired()); 145 EXPECT_TRUE(entity->IsUnsynced()); 146 147 EXPECT_TRUE(entity->UpdateIsReflection(10)); 148 EXPECT_FALSE(entity->UpdateIsInConflict(10)); 149 150 EXPECT_FALSE(entity->UpdateIsReflection(11)); 151 EXPECT_TRUE(entity->UpdateIsInConflict(11)); 152} 153 154TEST_F(ModelThreadSyncEntityTest, LocalDeletion) { 155 scoped_ptr<ModelThreadSyncEntity> entity( 156 ModelThreadSyncEntity::FromServerUpdate( 157 kServerId, 158 kClientTagHash, 159 kClientTag, // As non-unique name. 160 10, 161 specifics, 162 false, 163 kCtime, 164 kMtime)); 165 166 entity->Delete(); 167 168 EXPECT_TRUE(entity->IsWriteRequired()); 169 EXPECT_TRUE(entity->IsUnsynced()); 170 171 EXPECT_TRUE(entity->UpdateIsReflection(10)); 172 EXPECT_FALSE(entity->UpdateIsInConflict(10)); 173 174 EXPECT_FALSE(entity->UpdateIsReflection(11)); 175 EXPECT_TRUE(entity->UpdateIsInConflict(11)); 176} 177 178} // namespace syncer 179