summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 21:13:33 +0000
committerqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 21:13:33 +0000
commit65ad0ec760770b0a81efb66bc490b7bbb580786a (patch)
tree4e6cb701d9bd29482b7f6d9bd0dad42a713cd104
parente10392c8a0ec0bc09386d9fe1db1b79e0b2f4f36 (diff)
downloadchromium_src-65ad0ec760770b0a81efb66bc490b7bbb580786a.zip
chromium_src-65ad0ec760770b0a81efb66bc490b7bbb580786a.tar.gz
chromium_src-65ad0ec760770b0a81efb66bc490b7bbb580786a.tar.bz2
Implement a bag of chips for sync.
The bag of chips is a per-client state used by the server. This state is stored on the client and send back to the server on all communication. BUG=None TEST=None Review URL: https://chromiumcodereview.appspot.com/10916174 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156123 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--sync/engine/build_commit_command.cc2
-rw-r--r--sync/engine/download_updates_command.cc1
-rw-r--r--sync/engine/syncer_proto_util.cc21
-rw-r--r--sync/engine/syncer_proto_util.h10
-rw-r--r--sync/protocol/sync.proto12
-rw-r--r--sync/syncable/directory.cc13
-rw-r--r--sync/syncable/directory.h9
-rw-r--r--sync/syncable/directory_backing_store.cc47
-rw-r--r--sync/syncable/directory_backing_store.h1
-rw-r--r--sync/syncable/directory_backing_store_unittest.cc124
-rw-r--r--sync/syncable/syncable_unittest.cc11
-rw-r--r--sync/test/test_directory_backing_store.h1
12 files changed, 241 insertions, 11 deletions
diff --git a/sync/engine/build_commit_command.cc b/sync/engine/build_commit_command.cc
index 534e196..ade6acb 100644
--- a/sync/engine/build_commit_command.cc
+++ b/sync/engine/build_commit_command.cc
@@ -114,6 +114,8 @@ SyncerError BuildCommitCommand::ExecuteImpl(SyncSession* session) {
SyncerProtoUtil::SetProtocolVersion(commit_message_);
SyncerProtoUtil::AddRequestBirthday(
session->write_transaction()->directory(), commit_message_);
+ SyncerProtoUtil::AddBagOfChips(
+ session->write_transaction()->directory(), commit_message_);
// Cache previously computed position values. Because |commit_ids|
// is already in sibling order, we should always hit this map after
diff --git a/sync/engine/download_updates_command.cc b/sync/engine/download_updates_command.cc
index e1ba189..cd0730a 100644
--- a/sync/engine/download_updates_command.cc
+++ b/sync/engine/download_updates_command.cc
@@ -111,6 +111,7 @@ SyncerError DownloadUpdatesCommand::ExecuteImpl(SyncSession* session) {
SyncerProtoUtil::SetProtocolVersion(&client_to_server_message);
SyncerProtoUtil::AddRequestBirthday(dir, &client_to_server_message);
+ SyncerProtoUtil::AddBagOfChips(dir, &client_to_server_message);
DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
diff --git a/sync/engine/syncer_proto_util.cc b/sync/engine/syncer_proto_util.cc
index 8149ad8..eef0208 100644
--- a/sync/engine/syncer_proto_util.cc
+++ b/sync/engine/syncer_proto_util.cc
@@ -163,6 +163,12 @@ void SyncerProtoUtil::AddRequestBirthday(syncable::Directory* dir,
}
// static
+void SyncerProtoUtil::AddBagOfChips(syncable::Directory* dir,
+ ClientToServerMessage* msg) {
+ msg->mutable_bag_of_chips()->ParseFromString(dir->bag_of_chips());
+}
+
+// static
void SyncerProtoUtil::SetProtocolVersion(ClientToServerMessage* msg) {
const int current_version =
ClientToServerMessage::default_instance().protocol_version();
@@ -349,6 +355,8 @@ SyncerError SyncerProtoUtil::PostClientToServerMessage(
DCHECK(!msg.get_updates().has_requested_types()); // Deprecated.
DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg))
<< "Must call AddRequestBirthday to set birthday.";
+ DCHECK(msg.has_bag_of_chips())
+ << "Must call AddBagOfChips to set bag_of_chips.";
syncable::Directory* dir = session->context()->directory();
@@ -371,6 +379,9 @@ SyncerError SyncerProtoUtil::PostClientToServerMessage(
session->context()->traffic_recorder()->RecordClientToServerResponse(
*response);
+ // Persist a bag of chips if it has been sent by the server.
+ PersistBagOfChips(dir, *response);
+
SyncProtocolError sync_protocol_error;
// Birthday mismatch overrides any error that is sent by the server.
@@ -509,6 +520,16 @@ const std::string& SyncerProtoUtil::NameFromCommitEntryResponse(
return entry.name();
}
+// static
+void SyncerProtoUtil::PersistBagOfChips(syncable::Directory* dir,
+ const sync_pb::ClientToServerResponse& response) {
+ if (!response.has_new_bag_of_chips())
+ return;
+ std::string bag_of_chips;
+ if (response.new_bag_of_chips().SerializeToString(&bag_of_chips))
+ dir->set_bag_of_chips(bag_of_chips);
+}
+
std::string SyncerProtoUtil::SyncEntityDebugString(
const sync_pb::SyncEntity& entry) {
const std::string& mtime_str =
diff --git a/sync/engine/syncer_proto_util.h b/sync/engine/syncer_proto_util.h
index b674b50..fab1406 100644
--- a/sync/engine/syncer_proto_util.h
+++ b/sync/engine/syncer_proto_util.h
@@ -74,6 +74,11 @@ class SyncerProtoUtil {
static const std::string& NameFromCommitEntryResponse(
const sync_pb::CommitResponse_EntryResponse& entry);
+ // Persist the bag of chips if it is present in the response.
+ static void PersistBagOfChips(
+ syncable::Directory* dir,
+ const sync_pb::ClientToServerResponse& response);
+
// EntitySpecifics is used as a filter for the GetUpdates message to tell
// the server which datatypes to send back. This adds a datatype so that
// it's included in the filter.
@@ -92,6 +97,11 @@ class SyncerProtoUtil {
static void AddRequestBirthday(syncable::Directory* dir,
sync_pb::ClientToServerMessage* msg);
+ // Pull the bag of chips from the dir and put it into the msg.
+ static void AddBagOfChips(syncable::Directory* dir,
+ sync_pb::ClientToServerMessage* msg);
+
+
// Set the protocol version field in the outgoing message.
static void SetProtocolVersion(sync_pb::ClientToServerMessage* msg);
diff --git a/sync/protocol/sync.proto b/sync/protocol/sync.proto
index 6d0622b2..5e637ed 100644
--- a/sync/protocol/sync.proto
+++ b/sync/protocol/sync.proto
@@ -463,6 +463,10 @@ message AuthenticateMessage {
required string auth_token = 1;
};
+// Opaque data used by the server to track the client with.
+message ChipBag {
+};
+
message ClientToServerMessage {
required string share = 1;
optional int32 protocol_version = 2 [default = 31];
@@ -491,6 +495,10 @@ message ClientToServerMessage {
// This is only sent on the first getupdates of every sync cycle,
// as an optimization to save bandwidth.
optional DebugInfo debug_info = 10;
+
+ // Per-client state for use by the server. Sent with every message sent to the
+ // server.
+ optional ChipBag bag_of_chips = 11;
};
message CommitResponse {
@@ -678,5 +686,9 @@ message ClientToServerResponse {
repeated int32 error_data_type_ids = 5;
}
optional Error error = 13;
+
+ // The new per-client state for this client. If set, should be persisted and
+ // sent with any subsequent ClientToServerMessages.
+ optional ChipBag new_bag_of_chips = 14;
};
diff --git a/sync/syncable/directory.cc b/sync/syncable/directory.cc
index 77979ae..644a4e2 100644
--- a/sync/syncable/directory.cc
+++ b/sync/syncable/directory.cc
@@ -710,6 +710,19 @@ void Directory::set_store_birthday(const string& store_birthday) {
kernel_->info_status = KERNEL_SHARE_INFO_DIRTY;
}
+string Directory::bag_of_chips() const {
+ ScopedKernelLock lock(this);
+ return kernel_->persisted_info.bag_of_chips;
+}
+
+void Directory::set_bag_of_chips(const string& bag_of_chips) {
+ ScopedKernelLock lock(this);
+ if (kernel_->persisted_info.bag_of_chips == bag_of_chips)
+ return;
+ kernel_->persisted_info.bag_of_chips = bag_of_chips;
+ kernel_->info_status = KERNEL_SHARE_INFO_DIRTY;
+}
+
std::string Directory::GetNotificationState() const {
ScopedKernelLock lock(this);
std::string notification_state = kernel_->persisted_info.notification_state;
diff --git a/sync/syncable/directory.h b/sync/syncable/directory.h
index b34882f..49d598c 100644
--- a/sync/syncable/directory.h
+++ b/sync/syncable/directory.h
@@ -170,6 +170,10 @@ class Directory {
int64 next_id;
// The persisted notification state.
std::string notification_state;
+ // The serialized bag of chips we were given by the server. Contents are
+ // opaque to the client. This is the serialization of a message of type
+ // ChipBag defined in sync.proto. It can contains NULL characters.
+ std::string bag_of_chips;
};
// What the Directory needs on initialization to create itself and its Kernel.
@@ -260,6 +264,11 @@ class Directory {
std::string store_birthday() const;
void set_store_birthday(const std::string& store_birthday);
+ // (Account) Bag of chip is an opaque state used by the server to track the
+ // client.
+ std::string bag_of_chips() const;
+ void set_bag_of_chips(const std::string& bag_of_chips);
+
std::string GetNotificationState() const;
void SetNotificationState(const std::string& notification_state);
diff --git a/sync/syncable/directory_backing_store.cc b/sync/syncable/directory_backing_store.cc
index c64c535..9b8e0db 100644
--- a/sync/syncable/directory_backing_store.cc
+++ b/sync/syncable/directory_backing_store.cc
@@ -39,7 +39,7 @@ static const string::size_type kUpdateStatementBufferSize = 2048;
// Increment this version whenever updating DB tables.
extern const int32 kCurrentDBVersion; // Global visibility for our unittest.
-const int32 kCurrentDBVersion = 79;
+const int32 kCurrentDBVersion = 80;
// Iterate over the fields of |entry| and bind each to |statement| for
// updating. Returns the number of args bound.
@@ -201,11 +201,13 @@ bool DirectoryBackingStore::SaveChanges(
"UPDATE share_info "
"SET store_birthday = ?, "
"next_id = ?, "
- "notification_state = ?"));
+ "notification_state = ?, "
+ "bag_of_chips = ?"));
s1.BindString(0, info.store_birthday);
s1.BindInt64(1, info.next_id);
s1.BindBlob(2, info.notification_state.data(),
info.notification_state.size());
+ s1.BindBlob(3, info.bag_of_chips.data(), info.bag_of_chips.size());
if (!s1.Run())
return false;
@@ -315,6 +317,12 @@ bool DirectoryBackingStore::InitializeTables() {
version_on_disk = 79;
}
+ // Version 80 migration is adding the bag_of_chips column.
+ if (version_on_disk == 79) {
+ if (MigrateVersion79To80())
+ version_on_disk = 80;
+ }
+
// If one of the migrations requested it, drop columns that aren't current.
// It's only safe to do this after migrating all the way to the current
// version.
@@ -395,9 +403,10 @@ bool DirectoryBackingStore::RefreshColumns() {
if (!db_->Execute(
"INSERT INTO temp_share_info (id, name, store_birthday, "
"db_create_version, db_create_time, next_id, cache_guid,"
- "notification_state) "
+ "notification_state, bag_of_chips) "
"SELECT id, name, store_birthday, db_create_version, "
- "db_create_time, next_id, cache_guid, notification_state "
+ "db_create_time, next_id, cache_guid, notification_state, "
+ "bag_of_chips "
"FROM share_info"))
return false;
@@ -429,7 +438,8 @@ bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) {
{
sql::Statement s(
db_->GetUniqueStatement(
- "SELECT store_birthday, next_id, cache_guid, notification_state "
+ "SELECT store_birthday, next_id, cache_guid, notification_state, "
+ "bag_of_chips "
"FROM share_info"));
if (!s.Step())
return false;
@@ -438,6 +448,7 @@ bool DirectoryBackingStore::LoadInfo(Directory::KernelLoadInfo* info) {
info->kernel_info.next_id = s.ColumnInt64(1);
info->cache_guid = s.ColumnString(2);
s.ColumnBlobAsString(3, &(info->kernel_info.notification_state));
+ s.ColumnBlobAsString(4, &(info->kernel_info.bag_of_chips));
// Verify there was only one row returned.
DCHECK(!s.Step());
@@ -957,6 +968,19 @@ bool DirectoryBackingStore::MigrateVersion78To79() {
SetVersion(79);
return true;
}
+bool DirectoryBackingStore::MigrateVersion79To80() {
+ if (!db_->Execute(
+ "ALTER TABLE share_info ADD COLUMN bag_of_chips BLOB"))
+ return false;
+ sql::Statement update(db_->GetUniqueStatement(
+ "UPDATE share_info SET bag_of_chips = ?"));
+ // An empty message is serialized to an empty string.
+ update.BindBlob(0, NULL, 0);
+ if (!update.Run())
+ return false;
+ SetVersion(80);
+ return true;
+}
bool DirectoryBackingStore::CreateTables() {
DVLOG(1) << "First run, creating tables";
@@ -992,7 +1016,8 @@ bool DirectoryBackingStore::CreateTables() {
"?, " // db_create_time
"-2, " // next_id
"?, " // cache_guid
- "?);")); // notification_state
+ "?, " // notification_state
+ "?);")); // bag_of_chips
s.BindString(0, dir_name_); // id
s.BindString(1, dir_name_); // name
s.BindString(2, ""); // store_birthday
@@ -1002,7 +1027,7 @@ bool DirectoryBackingStore::CreateTables() {
s.BindInt(4, static_cast<int32>(time(0))); // db_create_time
s.BindString(5, GenerateCacheGUID()); // cache_guid
s.BindBlob(6, NULL, 0); // notification_state
-
+ s.BindBlob(7, NULL, 0); // bag_of_chips
if (!s.Run())
return false;
}
@@ -1078,10 +1103,10 @@ bool DirectoryBackingStore::CreateShareInfoTable(bool is_temporary) {
"db_create_version TEXT, "
"db_create_time INT, "
"next_id INT default -2, "
- "cache_guid TEXT ");
-
- query.append(", notification_state BLOB");
- query.append(")");
+ "cache_guid TEXT, "
+ "notification_state BLOB, "
+ "bag_of_chips BLOB"
+ ")");
return db_->Execute(query.c_str());
}
diff --git a/sync/syncable/directory_backing_store.h b/sync/syncable/directory_backing_store.h
index 054c4d5..a441a86 100644
--- a/sync/syncable/directory_backing_store.h
+++ b/sync/syncable/directory_backing_store.h
@@ -154,6 +154,7 @@ class DirectoryBackingStore : public base::NonThreadSafe {
bool MigrateVersion76To77();
bool MigrateVersion77To78();
bool MigrateVersion78To79();
+ bool MigrateVersion79To80();
scoped_ptr<sql::Connection> db_;
sql::Statement save_entry_statement_;
diff --git a/sync/syncable/directory_backing_store_unittest.cc b/sync/syncable/directory_backing_store_unittest.cc
index affddbf..1864ba9 100644
--- a/sync/syncable/directory_backing_store_unittest.cc
+++ b/sync/syncable/directory_backing_store_unittest.cc
@@ -62,6 +62,7 @@ class MigrationTest : public testing::TestWithParam<int> {
void SetUpVersion76Database(sql::Connection* connection);
void SetUpVersion77Database(sql::Connection* connection);
void SetUpVersion78Database(sql::Connection* connection);
+ void SetUpVersion79Database(sql::Connection* connection);
void SetUpCurrentDatabaseAndCheckVersion(sql::Connection* connection) {
SetUpVersion77Database(connection); // Prepopulates data.
@@ -1629,6 +1630,101 @@ void MigrationTest::SetUpVersion78Database(sql::Connection* connection) {
ASSERT_TRUE(connection->CommitTransaction());
}
+void MigrationTest::SetUpVersion79Database(sql::Connection* connection) {
+ ASSERT_TRUE(connection->is_open());
+ ASSERT_TRUE(connection->BeginTransaction());
+ ASSERT_TRUE(connection->Execute(
+ "CREATE TABLE share_version (id VARCHAR(128) primary key, data INT);"
+ "INSERT INTO 'share_version' VALUES('nick@chromium.org',78);"
+ "CREATE TABLE models (model_id BLOB primary key, progress_marker BLOB, in"
+ "itial_sync_ended BOOLEAN default 0);"
+ "INSERT INTO 'models' VALUES(X'C2881000',X'0888810218B605',1);"
+ "CREATE TABLE 'metas'(metahandle bigint primary key ON CONFLICT FAIL,base"
+ "_version bigint default -1,server_version bigint default 0,server_po"
+ "sition_in_parent bigint default 0,local_external_id bigint default 0"
+ ",mtime bigint default 0,server_mtime bigint default 0,ctime bigint d"
+ "efault 0,server_ctime bigint default 0,id varchar(255) default 'r',p"
+ "arent_id varchar(255) default 'r',server_parent_id varchar(255) defa"
+ "ult 'r',prev_id varchar(255) default 'r',next_id varchar(255) defaul"
+ "t 'r',is_unsynced bit default 0,is_unapplied_update bit default 0,is"
+ "_del bit default 0,is_dir bit default 0,server_is_dir bit default 0,"
+ "server_is_del bit default 0,non_unique_name varchar,server_non_uniqu"
+ "e_name varchar(255),unique_server_tag varchar,unique_client_tag varc"
+ "har,specifics blob,server_specifics blob, base_server_specifics BLOB"
+ ");"
+ "INSERT INTO 'metas' VALUES(1,-1,0,0,0," META_PROTO_TIMES_VALS(1) ",'r','"
+ "r','r','r','r',0,0,0,1,0,0,NULL,NULL,NULL,NULL,X'',X'',NULL);"
+ "INSERT INTO 'metas' VALUES(2,669,669,-2097152,4,"
+ META_PROTO_TIMES_VALS(2) ",'s_ID_2','s_ID_9','s_ID_9','s_ID_2','s_ID_"
+ "2',0,0,1,0,0,1,'Deleted Item','Deleted Item',NULL,NULL,X'C28810220A1"
+ "6687474703A2F2F7777772E676F6F676C652E636F6D2F12084141534741534741',X"
+ "'C28810260A17687474703A2F2F7777772E676F6F676C652E636F6D2F32120B41534"
+ "14447414447414447',NULL);"
+ "INSERT INTO 'metas' VALUES(4,681,681,-3145728,3,"
+ META_PROTO_TIMES_VALS(4) ",'s_ID_4','s_ID_9','s_ID_9','s_ID_4','s_ID_"
+ "4',0,0,1,0,0,1,'Welcome to Chromium','Welcome to Chromium',NULL,NULL"
+ ",X'C28810350A31687474703A2F2F7777772E676F6F676C652E636F6D2F6368726F6"
+ "D652F696E746C2F656E2F77656C636F6D652E68746D6C1200',X'C28810350A31687"
+ "474703A2F2F7777772E676F6F676C652E636F6D2F6368726F6D652F696E746C2F656"
+ "E2F77656C636F6D652E68746D6C1200',NULL);"
+ "INSERT INTO 'metas' VALUES(5,677,677,1048576,7,"
+ META_PROTO_TIMES_VALS(5) ",'s_ID_5','s_ID_9','s_ID_9','s_ID_5','s_ID_"
+ "5',0,0,1,0,0,1,'Google','Google',NULL,NULL,X'C28810220A16687474703A2"
+ "F2F7777772E676F6F676C652E636F6D2F12084147415347415347',X'C28810220A1"
+ "6687474703A2F2F7777772E676F6F676C652E636F6D2F12084147464447415347',N"
+ "ULL);"
+ "INSERT INTO 'metas' VALUES(6,694,694,-4194304,6,"
+ META_PROTO_TIMES_VALS(6) ",'s_ID_6','s_ID_9','s_ID_9','r','r',0,0,0,1"
+ ",1,0,'The Internet','The Internet',NULL,NULL,X'C2881000',X'C2881000'"
+ ",NULL);"
+ "INSERT INTO 'metas' VALUES(7,663,663,1048576,0,"
+ META_PROTO_TIMES_VALS(7) ",'s_ID_7','r','r','r','r',0,0,0,1,1,0,'Goog"
+ "le Chrome','Google Chrome','google_chrome',NULL,NULL,NULL,NULL);"
+ "INSERT INTO 'metas' VALUES(8,664,664,1048576,0,"
+ META_PROTO_TIMES_VALS(8) ",'s_ID_8','s_ID_7','s_ID_7','r','r',0,0,0,1"
+ ",1,0,'Bookmarks','Bookmarks','google_chrome_bookmarks',NULL,X'C28810"
+ "00',X'C2881000',NULL);"
+ "INSERT INTO 'metas' VALUES(9,665,665,1048576,1,"
+ META_PROTO_TIMES_VALS(9) ",'s_ID_9','s_ID_8','s_ID_8','r','s_ID_10',0"
+ ",0,0,1,1,0,'Bookmark Bar','Bookmark Bar','bookmark_bar',NULL,X'C2881"
+ "000',X'C2881000',NULL);"
+ "INSERT INTO 'metas' VALUES(10,666,666,2097152,2,"
+ META_PROTO_TIMES_VALS(10) ",'s_ID_10','s_ID_8','s_ID_8','s_ID_9','r',"
+ "0,0,0,1,1,0,'Other Bookmarks','Other Bookmarks','other_bookmarks',NU"
+ "LL,X'C2881000',X'C2881000',NULL);"
+ "INSERT INTO 'metas' VALUES(11,683,683,-1048576,8,"
+ META_PROTO_TIMES_VALS(11) ",'s_ID_11','s_ID_6','s_ID_6','r','s_ID_13'"
+ ",0,0,0,0,0,0,'Home (The Chromium Projects)','Home (The Chromium Proj"
+ "ects)',NULL,NULL,X'C28810220A18687474703A2F2F6465762E6368726F6D69756"
+ "D2E6F72672F1206414741545741',X'C28810290A1D687474703A2F2F6465762E636"
+ "8726F6D69756D2E6F72672F6F7468657212084146414756415346',NULL);"
+ "INSERT INTO 'metas' VALUES(12,685,685,0,9,"
+ META_PROTO_TIMES_VALS(12) ",'s_ID_12','s_ID_6','s_ID_6','s_ID_13','s_"
+ "ID_14',0,0,0,1,1,0,'Extra Bookmarks','Extra Bookmarks',NULL,NULL,X'C"
+ "2881000',X'C2881000',NULL);"
+ "INSERT INTO 'metas' VALUES(13,687,687,-917504,10,"
+ META_PROTO_TIMES_VALS(13) ",'s_ID_13','s_ID_6','s_ID_6','s_ID_11','s_"
+ "ID_12',0,0,0,0,0,0,'ICANN | Internet Corporation for Assigned Names "
+ "and Numbers','ICANN | Internet Corporation for Assigned Names and Nu"
+ "mbers',NULL,NULL,X'C28810240A15687474703A2F2F7777772E6963616E6E2E636"
+ "F6D2F120B504E474158463041414646',X'C28810200A15687474703A2F2F7777772"
+ "E6963616E6E2E636F6D2F120744414146415346',NULL);"
+ "INSERT INTO 'metas' VALUES(14,692,692,1048576,11,"
+ META_PROTO_TIMES_VALS(14) ",'s_ID_14','s_ID_6','s_ID_6','s_ID_12','r'"
+ ",0,0,0,0,0,0,'The WebKit Open Source Project','The WebKit Open Sourc"
+ "e Project',NULL,NULL,X'C288101A0A12687474703A2F2F7765626B69742E6F726"
+ "72F1204504E4758',X'C288101C0A13687474703A2F2F7765626B69742E6F72672F7"
+ "81205504E473259',NULL);"
+ "CREATE TABLE 'share_info' (id TEXT primary key, name TEXT, store_birthda"
+ "y TEXT, db_create_version TEXT, db_create_time INT, next_id INT defa"
+ "ult -2, cache_guid TEXT , notification_state BLOB);"
+ "INSERT INTO 'share_info' VALUES('nick@chromium.org','nick@chromium.org',"
+ "'c27e9f59-08ca-46f8-b0cc-f16a2ed778bb','Unknown',1263522064,"
+ "-131078,'9010788312004066376x-6609234393368420856x',NULL);"
+ ));
+ ASSERT_TRUE(connection->CommitTransaction());
+}
+
TEST_F(DirectoryBackingStoreTest, MigrateVersion67To68) {
sql::Connection connection;
ASSERT_TRUE(connection.OpenInMemory());
@@ -1958,6 +2054,31 @@ TEST_F(DirectoryBackingStoreTest, MigrateVersion78To79) {
EXPECT_LE(load_info.kernel_info.next_id, kInitialNextId - 65536);
}
+TEST_F(DirectoryBackingStoreTest, MigrateVersion79To80) {
+ sql::Connection connection;
+ ASSERT_TRUE(connection.OpenInMemory());
+ SetUpVersion79Database(&connection);
+
+ scoped_ptr<TestDirectoryBackingStore> dbs(
+ new TestDirectoryBackingStore(GetUsername(), &connection));
+ ASSERT_FALSE(dbs->needs_column_refresh_);
+ ASSERT_TRUE(dbs->MigrateVersion79To80());
+ ASSERT_EQ(80, dbs->GetVersion());
+ ASSERT_FALSE(dbs->needs_column_refresh_);
+
+ // Ensure the bag_of_chips has been set.
+ MetahandlesIndex entry_bucket;
+ STLElementDeleter<MetahandlesIndex> deleter(&entry_bucket);
+ Directory::KernelLoadInfo load_info;
+
+ ASSERT_TRUE(dbs->Load(&entry_bucket, &load_info));
+ // Check that the initial value is the serialization of an empty ChipBag.
+ sync_pb::ChipBag chip_bag;
+ std::string serialized_chip_bag;
+ ASSERT_TRUE(chip_bag.SerializeToString(&serialized_chip_bag));
+ EXPECT_EQ(serialized_chip_bag, load_info.kernel_info.bag_of_chips);
+}
+
TEST_P(MigrationTest, ToCurrentVersion) {
sql::Connection connection;
ASSERT_TRUE(connection.OpenInMemory());
@@ -1998,6 +2119,9 @@ TEST_P(MigrationTest, ToCurrentVersion) {
case 78:
SetUpVersion78Database(&connection);
break;
+ case 79:
+ SetUpVersion79Database(&connection);
+ break;
default:
// If you see this error, it may mean that you've increased the
// database version number but you haven't finished adding unit tests
diff --git a/sync/syncable/syncable_unittest.cc b/sync/syncable/syncable_unittest.cc
index b74d41c..f69347b 100644
--- a/sync/syncable/syncable_unittest.cc
+++ b/sync/syncable/syncable_unittest.cc
@@ -1583,15 +1583,24 @@ TEST_F(OnDiskSyncableDirectoryTest, TestShareInfo) {
dir_->set_initial_sync_ended_for_type(AUTOFILL, true);
dir_->set_store_birthday("Jan 31st");
dir_->SetNotificationState("notification_state");
+ const char* const bag_of_chips_array = "\0bag of chips";
+ const std::string bag_of_chips_string =
+ std::string(bag_of_chips_array, sizeof(bag_of_chips_array));
+ dir_->set_bag_of_chips(bag_of_chips_string);
{
ReadTransaction trans(FROM_HERE, dir_.get());
EXPECT_TRUE(dir_->initial_sync_ended_for_type(AUTOFILL));
EXPECT_FALSE(dir_->initial_sync_ended_for_type(BOOKMARKS));
EXPECT_EQ("Jan 31st", dir_->store_birthday());
EXPECT_EQ("notification_state", dir_->GetNotificationState());
+ EXPECT_EQ(bag_of_chips_string, dir_->bag_of_chips());
}
dir_->set_store_birthday("April 10th");
dir_->SetNotificationState("notification_state2");
+ const char* const bag_of_chips2_array = "\0bag of chips2";
+ const std::string bag_of_chips2_string =
+ std::string(bag_of_chips2_array, sizeof(bag_of_chips2_array));
+ dir_->set_bag_of_chips(bag_of_chips2_string);
dir_->SaveChanges();
{
ReadTransaction trans(FROM_HERE, dir_.get());
@@ -1599,6 +1608,7 @@ TEST_F(OnDiskSyncableDirectoryTest, TestShareInfo) {
EXPECT_FALSE(dir_->initial_sync_ended_for_type(BOOKMARKS));
EXPECT_EQ("April 10th", dir_->store_birthday());
EXPECT_EQ("notification_state2", dir_->GetNotificationState());
+ EXPECT_EQ(bag_of_chips2_string, dir_->bag_of_chips());
}
dir_->SetNotificationState("notification_state2");
// Restore the directory from disk. Make sure that nothing's changed.
@@ -1609,6 +1619,7 @@ TEST_F(OnDiskSyncableDirectoryTest, TestShareInfo) {
EXPECT_FALSE(dir_->initial_sync_ended_for_type(BOOKMARKS));
EXPECT_EQ("April 10th", dir_->store_birthday());
EXPECT_EQ("notification_state2", dir_->GetNotificationState());
+ EXPECT_EQ(bag_of_chips2_string, dir_->bag_of_chips());
}
}
diff --git a/sync/test/test_directory_backing_store.h b/sync/test/test_directory_backing_store.h
index f6b0322..612e728 100644
--- a/sync/test/test_directory_backing_store.h
+++ b/sync/test/test_directory_backing_store.h
@@ -41,6 +41,7 @@ class TestDirectoryBackingStore : public DirectoryBackingStore {
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion76To77);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion77To78);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion78To79);
+ FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion79To80);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, ModelTypeIds);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, Corruption);
FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, DeleteEntries);