1 2// Copyright 2014 The Chromium Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5 6#include "sync/engine/entity_tracker.h" 7 8#include "base/memory/scoped_ptr.h" 9#include "base/time/time.h" 10#include "sync/internal_api/public/base/model_type.h" 11#include "sync/syncable/syncable_util.h" 12#include "sync/util/time.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15namespace syncer { 16 17// Some simple tests for the EntityTracker. 18// 19// The EntityTracker is an implementation detail of the ModelTypeSyncWorker. 20// As such, it doesn't make much sense to test it exhaustively, since it 21// already gets a lot of test coverage from the ModelTypeSyncWorker unit tests. 22// 23// These tests are intended as a basic sanity check. Anything more complicated 24// would be redundant. 25class EntityTrackerTest : public ::testing::Test { 26 public: 27 EntityTrackerTest() 28 : kServerId("ServerID"), 29 kClientTag("some.sample.tag"), 30 kClientTagHash(syncable::GenerateSyncableHash(PREFERENCES, kClientTag)), 31 kCtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(10)), 32 kMtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(20)) { 33 specifics.mutable_preference()->set_name(kClientTag); 34 specifics.mutable_preference()->set_value("pref.value"); 35 } 36 37 virtual ~EntityTrackerTest() {} 38 39 const std::string kServerId; 40 const std::string kClientTag; 41 const std::string kClientTagHash; 42 const base::Time kCtime; 43 const base::Time kMtime; 44 sync_pb::EntitySpecifics specifics; 45}; 46 47// Construct a new entity from a server update. Then receive another update. 48TEST_F(EntityTrackerTest, FromServerUpdate) { 49 scoped_ptr<EntityTracker> entity( 50 EntityTracker::FromServerUpdate(kServerId, kClientTagHash, 10)); 51 EXPECT_FALSE(entity->IsCommitPending()); 52 53 entity->ReceiveUpdate(20); 54 EXPECT_FALSE(entity->IsCommitPending()); 55} 56 57// Construct a new entity from a commit request. Then serialize it. 58TEST_F(EntityTrackerTest, FromCommitRequest) { 59 scoped_ptr<EntityTracker> entity( 60 EntityTracker::FromCommitRequest(kServerId, 61 kClientTagHash, 62 22, 63 33, 64 kCtime, 65 kMtime, 66 kClientTag, 67 false, 68 specifics)); 69 70 ASSERT_TRUE(entity->IsCommitPending()); 71 sync_pb::SyncEntity pb_entity; 72 int64 sequence_number = 0; 73 entity->PrepareCommitProto(&pb_entity, &sequence_number); 74 EXPECT_EQ(22, sequence_number); 75 EXPECT_EQ(kServerId, pb_entity.id_string()); 76 EXPECT_EQ(kClientTagHash, pb_entity.client_defined_unique_tag()); 77 EXPECT_EQ(33, pb_entity.version()); 78 EXPECT_EQ(kCtime, ProtoTimeToTime(pb_entity.ctime())); 79 EXPECT_EQ(kMtime, ProtoTimeToTime(pb_entity.mtime())); 80 EXPECT_FALSE(pb_entity.deleted()); 81 EXPECT_EQ(specifics.preference().name(), 82 pb_entity.specifics().preference().name()); 83 EXPECT_EQ(specifics.preference().value(), 84 pb_entity.specifics().preference().value()); 85} 86 87// Start with a server initiated entity. Commit over top of it. 88TEST_F(EntityTrackerTest, RequestCommit) { 89 scoped_ptr<EntityTracker> entity( 90 EntityTracker::FromServerUpdate(kServerId, kClientTagHash, 10)); 91 92 entity->RequestCommit(kServerId, 93 kClientTagHash, 94 1, 95 10, 96 kCtime, 97 kMtime, 98 kClientTag, 99 false, 100 specifics); 101 102 EXPECT_TRUE(entity->IsCommitPending()); 103} 104 105// Start with a server initiated entity. Fail to request a commit because of 106// an out of date base version. 107TEST_F(EntityTrackerTest, RequestCommitFailure) { 108 scoped_ptr<EntityTracker> entity( 109 EntityTracker::FromServerUpdate(kServerId, kClientTagHash, 10)); 110 EXPECT_FALSE(entity->IsCommitPending()); 111 112 entity->RequestCommit(kServerId, 113 kClientTagHash, 114 23, 115 5, // Version 5 < 10 116 kCtime, 117 kMtime, 118 kClientTag, 119 false, 120 specifics); 121 EXPECT_FALSE(entity->IsCommitPending()); 122} 123 124// Start with a pending commit. Clobber it with an incoming update. 125TEST_F(EntityTrackerTest, UpdateClobbersCommit) { 126 scoped_ptr<EntityTracker> entity( 127 EntityTracker::FromCommitRequest(kServerId, 128 kClientTagHash, 129 22, 130 33, 131 kCtime, 132 kMtime, 133 kClientTag, 134 false, 135 specifics)); 136 137 EXPECT_TRUE(entity->IsCommitPending()); 138 139 entity->ReceiveUpdate(400); // Version 400 > 33. 140 EXPECT_FALSE(entity->IsCommitPending()); 141} 142 143// Start with a pending commit. Send it a reflected update that 144// will not override the in-progress commit. 145TEST_F(EntityTrackerTest, ReflectedUpdateDoesntClobberCommit) { 146 scoped_ptr<EntityTracker> entity( 147 EntityTracker::FromCommitRequest(kServerId, 148 kClientTagHash, 149 22, 150 33, 151 kCtime, 152 kMtime, 153 kClientTag, 154 false, 155 specifics)); 156 157 EXPECT_TRUE(entity->IsCommitPending()); 158 159 entity->ReceiveUpdate(33); // Version 33 == 33. 160 EXPECT_TRUE(entity->IsCommitPending()); 161} 162 163} // namespace syncer 164