| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/syncable/syncable.h" | 5 #include "chrome/browser/sync/syncable/syncable.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #include <sys/types.h> | 9 #include <sys/types.h> |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #if !defined(OS_WIN) | 23 #if !defined(OS_WIN) |
| 24 #define MAX_PATH PATH_MAX | 24 #define MAX_PATH PATH_MAX |
| 25 #include <ostream> | 25 #include <ostream> |
| 26 #include <stdio.h> | 26 #include <stdio.h> |
| 27 #include <sys/ipc.h> | 27 #include <sys/ipc.h> |
| 28 #include <sys/sem.h> | 28 #include <sys/sem.h> |
| 29 #include <sys/times.h> | 29 #include <sys/times.h> |
| 30 #endif // !defined(OS_WIN) | 30 #endif // !defined(OS_WIN) |
| 31 | 31 |
| 32 #include "base/at_exit.h" | 32 #include "base/at_exit.h" |
| 33 #include "base/file_path.h" |
| 34 #include "base/file_util.h" |
| 33 #include "base/logging.h" | 35 #include "base/logging.h" |
| 34 #include "base/platform_thread.h" | 36 #include "base/platform_thread.h" |
| 35 #include "base/scoped_ptr.h" | 37 #include "base/scoped_ptr.h" |
| 36 #include "chrome/browser/sync/syncable/directory_backing_store.h" | 38 #include "chrome/browser/sync/syncable/directory_backing_store.h" |
| 37 #include "chrome/browser/sync/syncable/directory_manager.h" | 39 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 38 #include "chrome/browser/sync/util/closure.h" | 40 #include "chrome/browser/sync/util/closure.h" |
| 39 #include "chrome/browser/sync/util/compat_file.h" | |
| 40 #include "chrome/browser/sync/util/event_sys-inl.h" | 41 #include "chrome/browser/sync/util/event_sys-inl.h" |
| 41 #include "chrome/browser/sync/util/path_helpers.h" | 42 #include "chrome/browser/sync/util/path_helpers.h" |
| 42 #include "chrome/browser/sync/util/query_helpers.h" | 43 #include "chrome/browser/sync/util/query_helpers.h" |
| 43 #include "chrome/test/sync/engine/test_id_factory.h" | 44 #include "chrome/test/sync/engine/test_id_factory.h" |
| 44 #include "testing/gtest/include/gtest/gtest.h" | 45 #include "testing/gtest/include/gtest/gtest.h" |
| 45 #include "third_party/sqlite/preprocessed/sqlite3.h" | 46 #include "third_party/sqlite/preprocessed/sqlite3.h" |
| 46 | 47 |
| 47 using browser_sync::TestIdFactory; | 48 using browser_sync::TestIdFactory; |
| 48 using std::cout; | 49 using std::cout; |
| 49 using std::endl; | 50 using std::endl; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 71 ExtendedAttributeKey key(e->Get(META_HANDLE), PSTR("DATA")); | 72 ExtendedAttributeKey key(e->Get(META_HANDLE), PSTR("DATA")); |
| 72 ExtendedAttribute attr(trans, GET_BY_HANDLE, key); | 73 ExtendedAttribute attr(trans, GET_BY_HANDLE, key); |
| 73 EXPECT_FALSE(attr.is_deleted()); | 74 EXPECT_FALSE(attr.is_deleted()); |
| 74 EXPECT_EQ(expected_value, attr.value()); | 75 EXPECT_EQ(expected_value, attr.value()); |
| 75 } | 76 } |
| 76 | 77 |
| 77 | 78 |
| 78 TEST(Syncable, General) { | 79 TEST(Syncable, General) { |
| 79 remove("SimpleTest.sqlite3"); | 80 remove("SimpleTest.sqlite3"); |
| 80 Directory dir; | 81 Directory dir; |
| 81 dir.Open(PSTR("SimpleTest.sqlite3"), PSTR("SimpleTest")); | 82 FilePath test_db(FILE_PATH_LITERAL("SimpleTest.sqlite3")); |
| 83 dir.Open(test_db, PSTR("SimpleTest")); |
| 82 bool entry_exists = false; | 84 bool entry_exists = false; |
| 83 int64 metahandle; | 85 int64 metahandle; |
| 84 const Id id = TestIdFactory::FromNumber(99); | 86 const Id id = TestIdFactory::FromNumber(99); |
| 85 // Test simple read operations. | 87 // Test simple read operations. |
| 86 { | 88 { |
| 87 ReadTransaction rtrans(&dir, __FILE__, __LINE__); | 89 ReadTransaction rtrans(&dir, __FILE__, __LINE__); |
| 88 Entry e(&rtrans, GET_BY_ID, id); | 90 Entry e(&rtrans, GET_BY_ID, id); |
| 89 if (e.good()) { | 91 if (e.good()) { |
| 90 entry_exists = true; | 92 entry_exists = true; |
| 91 metahandle = e.Get(META_HANDLE); | 93 metahandle = e.Get(META_HANDLE); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 } | 171 } |
| 170 | 172 |
| 171 namespace { | 173 namespace { |
| 172 | 174 |
| 173 // A Directory whose backing store always fails SaveChanges by returning false. | 175 // A Directory whose backing store always fails SaveChanges by returning false. |
| 174 class TestUnsaveableDirectory : public Directory { | 176 class TestUnsaveableDirectory : public Directory { |
| 175 public: | 177 public: |
| 176 class UnsaveableBackingStore : public DirectoryBackingStore { | 178 class UnsaveableBackingStore : public DirectoryBackingStore { |
| 177 public: | 179 public: |
| 178 UnsaveableBackingStore(const PathString& dir_name, | 180 UnsaveableBackingStore(const PathString& dir_name, |
| 179 const PathString& backing_filepath) | 181 const FilePath& backing_filepath) |
| 180 : DirectoryBackingStore(dir_name, backing_filepath) { } | 182 : DirectoryBackingStore(dir_name, backing_filepath) { } |
| 181 virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) { | 183 virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) { |
| 182 return false; | 184 return false; |
| 183 } | 185 } |
| 184 }; | 186 }; |
| 185 virtual DirectoryBackingStore* CreateBackingStore( | 187 virtual DirectoryBackingStore* CreateBackingStore( |
| 186 const PathString& dir_name, const PathString& backing_filepath) { | 188 const PathString& dir_name, const FilePath& backing_filepath) { |
| 187 return new UnsaveableBackingStore(dir_name, backing_filepath); | 189 return new UnsaveableBackingStore(dir_name, backing_filepath); |
| 188 } | 190 } |
| 189 }; | 191 }; |
| 190 | 192 |
| 191 // Test suite for syncable::Directory. | 193 // Test suite for syncable::Directory. |
| 192 class SyncableDirectoryTest : public testing::Test { | 194 class SyncableDirectoryTest : public testing::Test { |
| 193 protected: | 195 protected: |
| 194 static const PathString kFilePath; | 196 static const FilePath::CharType kFilePath[]; |
| 195 static const PathString kName; | 197 static const PathString kName; |
| 196 static const PathChar* kSqlite3File; | |
| 197 static const Id kId; | 198 static const Id kId; |
| 198 | 199 |
| 199 // SetUp() is called before each test case is run. | 200 // SetUp() is called before each test case is run. |
| 200 // The sqlite3 DB is deleted before each test is run. | 201 // The sqlite3 DB is deleted before each test is run. |
| 201 virtual void SetUp() { | 202 virtual void SetUp() { |
| 202 PathRemove(PathString(kSqlite3File)); | 203 file_path_ = FilePath(kFilePath); |
| 204 file_util::Delete(file_path_, true); |
| 203 dir_.reset(new Directory()); | 205 dir_.reset(new Directory()); |
| 204 ASSERT_TRUE(dir_.get()); | 206 ASSERT_TRUE(dir_.get()); |
| 205 ASSERT_TRUE(OPENED == dir_->Open(kFilePath, kName)); | 207 ASSERT_TRUE(OPENED == dir_->Open(file_path_, kName)); |
| 206 ASSERT_TRUE(dir_->good()); | 208 ASSERT_TRUE(dir_->good()); |
| 207 } | 209 } |
| 208 | 210 |
| 209 virtual void TearDown() { | 211 virtual void TearDown() { |
| 210 // This also closes file handles. | 212 // This also closes file handles. |
| 211 dir_->SaveChanges(); | 213 dir_->SaveChanges(); |
| 212 dir_.reset(); | 214 dir_.reset(); |
| 213 PathRemove(PathString(kSqlite3File)); | 215 file_util::Delete(file_path_, true); |
| 214 } | 216 } |
| 215 | 217 |
| 216 scoped_ptr<Directory> dir_; | 218 scoped_ptr<Directory> dir_; |
| 219 FilePath file_path_; |
| 217 | 220 |
| 218 // Creates an empty entry and sets the ID field to the default kId. | 221 // Creates an empty entry and sets the ID field to the default kId. |
| 219 void CreateEntry(const PathString &entryname) { | 222 void CreateEntry(const PathString &entryname) { |
| 220 CreateEntry(entryname, kId); | 223 CreateEntry(entryname, kId); |
| 221 } | 224 } |
| 222 | 225 |
| 223 // Creates an empty entry and sets the ID field to id. | 226 // Creates an empty entry and sets the ID field to id. |
| 224 void CreateEntry(const PathString &entryname, const int id) { | 227 void CreateEntry(const PathString &entryname, const int id) { |
| 225 CreateEntry(entryname, TestIdFactory::FromNumber(id)); | 228 CreateEntry(entryname, TestIdFactory::FromNumber(id)); |
| 226 } | 229 } |
| 227 void CreateEntry(const PathString &entryname, Id id) { | 230 void CreateEntry(const PathString &entryname, Id id) { |
| 228 WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 231 WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); |
| 229 MutableEntry me(&wtrans, CREATE, wtrans.root_id(), entryname); | 232 MutableEntry me(&wtrans, CREATE, wtrans.root_id(), entryname); |
| 230 ASSERT_TRUE(me.good()); | 233 ASSERT_TRUE(me.good()); |
| 231 me.Put(ID, id); | 234 me.Put(ID, id); |
| 232 me.Put(IS_UNSYNCED, true); | 235 me.Put(IS_UNSYNCED, true); |
| 233 } | 236 } |
| 234 | 237 |
| 235 void ValidateEntry(BaseTransaction* trans, int64 id, bool check_name, | 238 void ValidateEntry(BaseTransaction* trans, int64 id, bool check_name, |
| 236 PathString name, int64 base_version, int64 server_version, bool is_del); | 239 PathString name, int64 base_version, int64 server_version, bool is_del); |
| 237 void CreateAndCheck(WriteTransaction* trans, int64 parent_id, int64 id, | 240 void CreateAndCheck(WriteTransaction* trans, int64 parent_id, int64 id, |
| 238 PathString name, PathString server_name, int64 version, | 241 PathString name, PathString server_name, int64 version, |
| 239 bool set_server_fields, bool is_dir, bool add_to_lru, int64 *meta_handle); | 242 bool set_server_fields, bool is_dir, bool add_to_lru, int64 *meta_handle); |
| 240 }; | 243 }; |
| 241 | 244 |
| 242 const PathString SyncableDirectoryTest::kFilePath(PSTR("Test.sqlite3")); | 245 const FilePath::CharType SyncableDirectoryTest::kFilePath[] = |
| 243 const PathChar* SyncableDirectoryTest::kSqlite3File(PSTR("Test.sqlite3")); | 246 FILE_PATH_LITERAL("Test.sqlite3"); |
| 244 const PathString SyncableDirectoryTest::kName(PSTR("Foo")); | 247 const PathString SyncableDirectoryTest::kName(PSTR("Foo")); |
| 245 const Id SyncableDirectoryTest::kId(TestIdFactory::FromNumber(-99)); | 248 const Id SyncableDirectoryTest::kId(TestIdFactory::FromNumber(-99)); |
| 246 | 249 |
| 247 TEST_F(SyncableDirectoryTest, TestBasicLookupNonExistantID) { | 250 TEST_F(SyncableDirectoryTest, TestBasicLookupNonExistantID) { |
| 248 ReadTransaction rtrans(dir_.get(), __FILE__, __LINE__); | 251 ReadTransaction rtrans(dir_.get(), __FILE__, __LINE__); |
| 249 Entry e(&rtrans, GET_BY_ID, kId); | 252 Entry e(&rtrans, GET_BY_ID, kId); |
| 250 ASSERT_FALSE(e.good()); | 253 ASSERT_FALSE(e.good()); |
| 251 } | 254 } |
| 252 | 255 |
| 253 TEST_F(SyncableDirectoryTest, TestBasicLookupValidID) { | 256 TEST_F(SyncableDirectoryTest, TestBasicLookupValidID) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 284 ASSERT_FALSE(e1.Put(IS_DEL, false)); | 287 ASSERT_FALSE(e1.Put(IS_DEL, false)); |
| 285 ASSERT_FALSE(e2.Put(IS_DEL, false)); | 288 ASSERT_FALSE(e2.Put(IS_DEL, false)); |
| 286 ASSERT_TRUE(e3.Put(IS_DEL, true)); | 289 ASSERT_TRUE(e3.Put(IS_DEL, true)); |
| 287 | 290 |
| 288 ASSERT_TRUE(e1.Put(IS_DEL, false)); | 291 ASSERT_TRUE(e1.Put(IS_DEL, false)); |
| 289 ASSERT_FALSE(e2.Put(IS_DEL, false)); | 292 ASSERT_FALSE(e2.Put(IS_DEL, false)); |
| 290 ASSERT_FALSE(e3.Put(IS_DEL, false)); | 293 ASSERT_FALSE(e3.Put(IS_DEL, false)); |
| 291 ASSERT_TRUE(e1.Put(IS_DEL, true)); | 294 ASSERT_TRUE(e1.Put(IS_DEL, true)); |
| 292 } | 295 } |
| 293 | 296 |
| 294 TEST_F(SyncableDirectoryTest, TestGetFullPathNeverCrashes) { | |
| 295 PathString dirname = PSTR("honey"), | |
| 296 childname = PSTR("jelly"); | |
| 297 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | |
| 298 MutableEntry e1(&trans, CREATE, trans.root_id(), dirname); | |
| 299 ASSERT_TRUE(e1.good()); | |
| 300 ASSERT_TRUE(e1.Put(IS_DIR, true)); | |
| 301 MutableEntry e2(&trans, CREATE, e1.Get(ID), childname); | |
| 302 ASSERT_TRUE(e2.good()); | |
| 303 PathString path = GetFullPath(&trans, e2); | |
| 304 ASSERT_FALSE(path.empty()); | |
| 305 // Give the child a parent that doesn't exist. | |
| 306 e2.Put(PARENT_ID, TestIdFactory::FromNumber(42)); | |
| 307 path = GetFullPath(&trans, e2); | |
| 308 ASSERT_TRUE(path.empty()); | |
| 309 // Done testing, make sure CheckTreeInvariants doesn't choke. | |
| 310 e2.Put(PARENT_ID, e1.Get(ID)); | |
| 311 e2.Put(IS_DEL, true); | |
| 312 e1.Put(IS_DEL, true); | |
| 313 } | |
| 314 | |
| 315 TEST_F(SyncableDirectoryTest, TestGetUnsynced) { | 297 TEST_F(SyncableDirectoryTest, TestGetUnsynced) { |
| 316 Directory::UnsyncedMetaHandles handles; | 298 Directory::UnsyncedMetaHandles handles; |
| 317 int64 handle1, handle2; | 299 int64 handle1, handle2; |
| 318 { | 300 { |
| 319 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 301 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |
| 320 | 302 |
| 321 dir_->GetUnsyncedMetaHandles(&trans, &handles); | 303 dir_->GetUnsyncedMetaHandles(&trans, &handles); |
| 322 ASSERT_TRUE(0 == handles.size()); | 304 ASSERT_TRUE(0 == handles.size()); |
| 323 | 305 |
| 324 MutableEntry e1(&trans, CREATE, trans.root_id(), PSTR("abba")); | 306 MutableEntry e1(&trans, CREATE, trans.root_id(), PSTR("abba")); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 ASSERT_TRUE(e1.good()); | 698 ASSERT_TRUE(e1.good()); |
| 717 handle1 = e1.Get(META_HANDLE); | 699 handle1 = e1.Get(META_HANDLE); |
| 718 e1.Put(BASE_VERSION, 1); | 700 e1.Put(BASE_VERSION, 1); |
| 719 e1.Put(IS_DIR, true); | 701 e1.Put(IS_DIR, true); |
| 720 e1.Put(ID, TestIdFactory::FromNumber(101)); | 702 e1.Put(ID, TestIdFactory::FromNumber(101)); |
| 721 } | 703 } |
| 722 ASSERT_TRUE(dir_->SaveChanges()); | 704 ASSERT_TRUE(dir_->SaveChanges()); |
| 723 | 705 |
| 724 dir_.reset(new TestUnsaveableDirectory()); | 706 dir_.reset(new TestUnsaveableDirectory()); |
| 725 ASSERT_TRUE(dir_.get()); | 707 ASSERT_TRUE(dir_.get()); |
| 726 ASSERT_TRUE(OPENED == dir_->Open(kFilePath, kName)); | 708 ASSERT_TRUE(OPENED == dir_->Open(FilePath(kFilePath), kName)); |
| 727 ASSERT_TRUE(dir_->good()); | 709 ASSERT_TRUE(dir_->good()); |
| 728 int64 handle2 = 0; | 710 int64 handle2 = 0; |
| 729 { | 711 { |
| 730 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 712 WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |
| 731 | 713 |
| 732 MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); | 714 MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); |
| 733 ASSERT_TRUE(aguilera.good()); | 715 ASSERT_TRUE(aguilera.good()); |
| 734 aguilera.Put(NAME, PSTR("christina")); | 716 aguilera.Put(NAME, PSTR("christina")); |
| 735 ASSERT_TRUE(aguilera.GetKernelCopy().dirty[NAME]); | 717 ASSERT_TRUE(aguilera.GetKernelCopy().dirty[NAME]); |
| 736 | 718 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 Entry e(trans, GET_BY_ID, TestIdFactory::FromNumber(id)); | 750 Entry e(trans, GET_BY_ID, TestIdFactory::FromNumber(id)); |
| 769 ASSERT_TRUE(e.good()); | 751 ASSERT_TRUE(e.good()); |
| 770 if (check_name) | 752 if (check_name) |
| 771 ASSERT_TRUE(name == e.Get(NAME)); | 753 ASSERT_TRUE(name == e.Get(NAME)); |
| 772 ASSERT_TRUE(base_version == e.Get(BASE_VERSION)); | 754 ASSERT_TRUE(base_version == e.Get(BASE_VERSION)); |
| 773 ASSERT_TRUE(server_version == e.Get(SERVER_VERSION)); | 755 ASSERT_TRUE(server_version == e.Get(SERVER_VERSION)); |
| 774 ASSERT_TRUE(is_del == e.Get(IS_DEL)); | 756 ASSERT_TRUE(is_del == e.Get(IS_DEL)); |
| 775 } | 757 } |
| 776 | 758 |
| 777 TEST(SyncableDirectoryManager, TestFileRelease) { | 759 TEST(SyncableDirectoryManager, TestFileRelease) { |
| 778 DirectoryManager dm(PSTR(".")); | 760 DirectoryManager dm(FilePath(FILE_PATH_LITERAL("."))); |
| 779 ASSERT_TRUE(dm.Open(PSTR("ScopeTest"))); | 761 ASSERT_TRUE(dm.Open(PSTR("ScopeTest"))); |
| 780 { | 762 { |
| 781 ScopedDirLookup(&dm, PSTR("ScopeTest")); | 763 ScopedDirLookup(&dm, PSTR("ScopeTest")); |
| 782 } | 764 } |
| 783 dm.Close(PSTR("ScopeTest")); | 765 dm.Close(PSTR("ScopeTest")); |
| 784 ASSERT_TRUE(0 == PathRemove(dm.GetSyncDataDatabasePath())); | 766 ASSERT_TRUE(file_util::Delete(dm.GetSyncDataDatabasePath(), true)); |
| 785 } | 767 } |
| 786 | 768 |
| 787 class ThreadOpenTestDelegate : public PlatformThread::Delegate { | 769 class ThreadOpenTestDelegate : public PlatformThread::Delegate { |
| 788 public: | 770 public: |
| 789 explicit ThreadOpenTestDelegate(DirectoryManager* dm) | 771 explicit ThreadOpenTestDelegate(DirectoryManager* dm) |
| 790 : directory_manager_(dm) {} | 772 : directory_manager_(dm) {} |
| 791 DirectoryManager* const directory_manager_; | 773 DirectoryManager* const directory_manager_; |
| 792 | 774 |
| 793 private: | 775 private: |
| 794 // PlatformThread::Delegate methods: | 776 // PlatformThread::Delegate methods: |
| 795 virtual void ThreadMain() { | 777 virtual void ThreadMain() { |
| 796 CHECK(directory_manager_->Open(PSTR("Open"))); | 778 CHECK(directory_manager_->Open(PSTR("Open"))); |
| 797 } | 779 } |
| 798 | 780 |
| 799 DISALLOW_COPY_AND_ASSIGN(ThreadOpenTestDelegate); | 781 DISALLOW_COPY_AND_ASSIGN(ThreadOpenTestDelegate); |
| 800 }; | 782 }; |
| 801 | 783 |
| 802 TEST(SyncableDirectoryManager, ThreadOpenTest) { | 784 TEST(SyncableDirectoryManager, ThreadOpenTest) { |
| 803 DirectoryManager dm(PSTR(".")); | 785 DirectoryManager dm(FilePath(FILE_PATH_LITERAL("."))); |
| 804 PlatformThreadHandle thread_handle; | 786 PlatformThreadHandle thread_handle; |
| 805 ThreadOpenTestDelegate test_delegate(&dm); | 787 ThreadOpenTestDelegate test_delegate(&dm); |
| 806 ASSERT_TRUE(PlatformThread::Create(0, &test_delegate, &thread_handle)); | 788 ASSERT_TRUE(PlatformThread::Create(0, &test_delegate, &thread_handle)); |
| 807 PlatformThread::Join(thread_handle); | 789 PlatformThread::Join(thread_handle); |
| 808 { | 790 { |
| 809 ScopedDirLookup dir(&dm, PSTR("Open")); | 791 ScopedDirLookup dir(&dm, PSTR("Open")); |
| 810 ASSERT_TRUE(dir.good()); | 792 ASSERT_TRUE(dir.good()); |
| 811 } | 793 } |
| 812 dm.Close(PSTR("Open")); | 794 dm.Close(PSTR("Open")); |
| 813 ScopedDirLookup dir(&dm, PSTR("Open")); | 795 ScopedDirLookup dir(&dm, PSTR("Open")); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 step_->condvar.Signal(); | 856 step_->condvar.Signal(); |
| 875 } | 857 } |
| 876 } | 858 } |
| 877 | 859 |
| 878 DISALLOW_COPY_AND_ASSIGN(ThreadBugDelegate); | 860 DISALLOW_COPY_AND_ASSIGN(ThreadBugDelegate); |
| 879 }; | 861 }; |
| 880 | 862 |
| 881 TEST(SyncableDirectoryManager, ThreadBug1) { | 863 TEST(SyncableDirectoryManager, ThreadBug1) { |
| 882 Step step; | 864 Step step; |
| 883 step.number = 0; | 865 step.number = 0; |
| 884 DirectoryManager dirman(PSTR(".")); | 866 DirectoryManager dirman(FilePath(FILE_PATH_LITERAL("."))); |
| 885 ThreadBugDelegate thread_delegate_1(0, &step, &dirman); | 867 ThreadBugDelegate thread_delegate_1(0, &step, &dirman); |
| 886 ThreadBugDelegate thread_delegate_2(1, &step, &dirman); | 868 ThreadBugDelegate thread_delegate_2(1, &step, &dirman); |
| 887 | 869 |
| 888 PlatformThreadHandle thread_handle_1; | 870 PlatformThreadHandle thread_handle_1; |
| 889 PlatformThreadHandle thread_handle_2; | 871 PlatformThreadHandle thread_handle_2; |
| 890 | 872 |
| 891 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_1, &thread_handle_1)); | 873 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_1, &thread_handle_1)); |
| 892 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_2, &thread_handle_2)); | 874 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_2, &thread_handle_2)); |
| 893 | 875 |
| 894 PlatformThread::Join(thread_handle_1); | 876 PlatformThread::Join(thread_handle_1); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 911 AutoLock scoped_lock(step_->mutex); | 893 AutoLock scoped_lock(step_->mutex); |
| 912 | 894 |
| 913 while (step_->number < 4) { | 895 while (step_->number < 4) { |
| 914 while (step_->number % 2 != role_) { | 896 while (step_->number % 2 != role_) { |
| 915 step_->condvar.Wait(); | 897 step_->condvar.Wait(); |
| 916 } | 898 } |
| 917 switch (step_->number) { | 899 switch (step_->number) { |
| 918 case 0: | 900 case 0: |
| 919 { | 901 { |
| 920 // Clean up remnants of earlier test runs. | 902 // Clean up remnants of earlier test runs. |
| 921 PathRemove(directory_manager_->GetSyncDataDatabasePath()); | 903 file_util::Delete(directory_manager_->GetSyncDataDatabasePath(), |
| 904 true); |
| 922 // Test. | 905 // Test. |
| 923 directory_manager_->Open(dirname); | 906 directory_manager_->Open(dirname); |
| 924 ScopedDirLookup dir(directory_manager_, dirname); | 907 ScopedDirLookup dir(directory_manager_, dirname); |
| 925 CHECK(dir.good()); | 908 CHECK(dir.good()); |
| 926 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 909 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 927 MutableEntry me(&trans, CREATE, trans.root_id(), PSTR("Jeff")); | 910 MutableEntry me(&trans, CREATE, trans.root_id(), PSTR("Jeff")); |
| 928 me.Put(BASE_VERSION, 1); | 911 me.Put(BASE_VERSION, 1); |
| 929 me.Put(ID, TestIdFactory::FromNumber(100)); | 912 me.Put(ID, TestIdFactory::FromNumber(100)); |
| 930 PutDataAsExtendedAttribute(&trans, &me, test_bytes, | 913 PutDataAsExtendedAttribute(&trans, &me, test_bytes, |
| 931 sizeof(test_bytes)); | 914 sizeof(test_bytes)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 step_->condvar.Signal(); | 950 step_->condvar.Signal(); |
| 968 } | 951 } |
| 969 } | 952 } |
| 970 | 953 |
| 971 DISALLOW_COPY_AND_ASSIGN(DirectoryKernelStalenessBugDelegate); | 954 DISALLOW_COPY_AND_ASSIGN(DirectoryKernelStalenessBugDelegate); |
| 972 }; | 955 }; |
| 973 | 956 |
| 974 TEST(SyncableDirectoryManager, DirectoryKernelStalenessBug) { | 957 TEST(SyncableDirectoryManager, DirectoryKernelStalenessBug) { |
| 975 Step step; | 958 Step step; |
| 976 | 959 |
| 977 DirectoryManager dirman(PSTR(".")); | 960 DirectoryManager dirman(FilePath(FILE_PATH_LITERAL("."))); |
| 978 DirectoryKernelStalenessBugDelegate thread_delegate_1(0, &step, &dirman); | 961 DirectoryKernelStalenessBugDelegate thread_delegate_1(0, &step, &dirman); |
| 979 DirectoryKernelStalenessBugDelegate thread_delegate_2(1, &step, &dirman); | 962 DirectoryKernelStalenessBugDelegate thread_delegate_2(1, &step, &dirman); |
| 980 | 963 |
| 981 PlatformThreadHandle thread_handle_1; | 964 PlatformThreadHandle thread_handle_1; |
| 982 PlatformThreadHandle thread_handle_2; | 965 PlatformThreadHandle thread_handle_2; |
| 983 | 966 |
| 984 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_1, &thread_handle_1)); | 967 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_1, &thread_handle_1)); |
| 985 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_2, &thread_handle_2)); | 968 ASSERT_TRUE(PlatformThread::Create(0, &thread_delegate_2, &thread_handle_2)); |
| 986 | 969 |
| 987 PlatformThread::Join(thread_handle_1); | 970 PlatformThread::Join(thread_handle_1); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 e.Get(ID).ServerKnows() && !e.Get(ID).IsRoot()) | 1010 e.Get(ID).ServerKnows() && !e.Get(ID).IsRoot()) |
| 1028 e.Put(BASE_VERSION, 1); | 1011 e.Put(BASE_VERSION, 1); |
| 1029 } | 1012 } |
| 1030 } | 1013 } |
| 1031 } | 1014 } |
| 1032 | 1015 |
| 1033 DISALLOW_COPY_AND_ASSIGN(StressTransactionsDelegate); | 1016 DISALLOW_COPY_AND_ASSIGN(StressTransactionsDelegate); |
| 1034 }; | 1017 }; |
| 1035 | 1018 |
| 1036 TEST(SyncableDirectory, StressTransactions) { | 1019 TEST(SyncableDirectory, StressTransactions) { |
| 1037 DirectoryManager dirman(PSTR(".")); | 1020 DirectoryManager dirman(FilePath(FILE_PATH_LITERAL("."))); |
| 1038 PathString dirname = PSTR("stress"); | 1021 PathString dirname = PSTR("stress"); |
| 1039 PathRemove(dirman.GetSyncDataDatabasePath()); | 1022 file_util::Delete(dirman.GetSyncDataDatabasePath(), true); |
| 1040 dirman.Open(dirname); | 1023 dirman.Open(dirname); |
| 1041 | 1024 |
| 1042 const int kThreadCount = 7; | 1025 const int kThreadCount = 7; |
| 1043 PlatformThreadHandle threads[kThreadCount]; | 1026 PlatformThreadHandle threads[kThreadCount]; |
| 1044 scoped_ptr<StressTransactionsDelegate> thread_delegates[kThreadCount]; | 1027 scoped_ptr<StressTransactionsDelegate> thread_delegates[kThreadCount]; |
| 1045 | 1028 |
| 1046 for (int i = 0; i < kThreadCount; ++i) { | 1029 for (int i = 0; i < kThreadCount; ++i) { |
| 1047 thread_delegates[i].reset( | 1030 thread_delegates[i].reset( |
| 1048 new StressTransactionsDelegate(&dirman, dirname, i)); | 1031 new StressTransactionsDelegate(&dirman, dirname, i)); |
| 1049 ASSERT_TRUE( | 1032 ASSERT_TRUE( |
| 1050 PlatformThread::Create(0, thread_delegates[i].get(), &threads[i])); | 1033 PlatformThread::Create(0, thread_delegates[i].get(), &threads[i])); |
| 1051 } | 1034 } |
| 1052 | 1035 |
| 1053 for (int i = 0; i < kThreadCount; ++i) { | 1036 for (int i = 0; i < kThreadCount; ++i) { |
| 1054 PlatformThread::Join(threads[i]); | 1037 PlatformThread::Join(threads[i]); |
| 1055 } | 1038 } |
| 1056 | 1039 |
| 1057 dirman.Close(dirname); | 1040 dirman.Close(dirname); |
| 1058 PathRemove(dirman.GetSyncDataDatabasePath()); | 1041 file_util::Delete(dirman.GetSyncDataDatabasePath(), true); |
| 1059 } | 1042 } |
| 1060 | 1043 |
| 1061 TEST(Syncable, ComparePathNames) { | 1044 TEST(Syncable, ComparePathNames) { |
| 1062 struct { | 1045 struct { |
| 1063 char a; | 1046 char a; |
| 1064 char b; | 1047 char b; |
| 1065 int expected_result; | 1048 int expected_result; |
| 1066 } tests[] = { | 1049 } tests[] = { |
| 1067 { 'A', 'A', 0 }, | 1050 { 'A', 'A', 0 }, |
| 1068 { 'A', 'a', 0 }, | 1051 { 'A', 'a', 0 }, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1134 Blob value_blob(value, value + arraysize(value)); | 1117 Blob value_blob(value, value + arraysize(value)); |
| 1135 ext.mutable_value()->swap(value_blob); | 1118 ext.mutable_value()->swap(value_blob); |
| 1136 ext.delete_attribute(); | 1119 ext.delete_attribute(); |
| 1137 } | 1120 } |
| 1138 // This call to SaveChanges used to CHECK fail. | 1121 // This call to SaveChanges used to CHECK fail. |
| 1139 dir_.get()->SaveChanges(); | 1122 dir_.get()->SaveChanges(); |
| 1140 } | 1123 } |
| 1141 | 1124 |
| 1142 } // namespace | 1125 } // namespace |
| 1143 } // namespace syncable | 1126 } // namespace syncable |
| OLD | NEW |