| 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 24 matching lines...) Expand all  Loading... | 
|    35 #include "base/logging.h" |    35 #include "base/logging.h" | 
|    36 #include "base/platform_thread.h" |    36 #include "base/platform_thread.h" | 
|    37 #include "base/scoped_ptr.h" |    37 #include "base/scoped_ptr.h" | 
|    38 #include "chrome/browser/sync/syncable/directory_backing_store.h" |    38 #include "chrome/browser/sync/syncable/directory_backing_store.h" | 
|    39 #include "chrome/browser/sync/syncable/directory_manager.h" |    39 #include "chrome/browser/sync/syncable/directory_manager.h" | 
|    40 #include "chrome/browser/sync/util/closure.h" |    40 #include "chrome/browser/sync/util/closure.h" | 
|    41 #include "chrome/browser/sync/util/event_sys-inl.h" |    41 #include "chrome/browser/sync/util/event_sys-inl.h" | 
|    42 #include "chrome/browser/sync/util/path_helpers.h" |    42 #include "chrome/browser/sync/util/path_helpers.h" | 
|    43 #include "chrome/browser/sync/util/query_helpers.h" |    43 #include "chrome/browser/sync/util/query_helpers.h" | 
|    44 #include "chrome/test/sync/engine/test_id_factory.h" |    44 #include "chrome/test/sync/engine/test_id_factory.h" | 
 |    45 #include "chrome/test/sync/engine/test_syncable_utils.h" | 
|    45 #include "testing/gtest/include/gtest/gtest.h" |    46 #include "testing/gtest/include/gtest/gtest.h" | 
|    46 #include "third_party/sqlite/preprocessed/sqlite3.h" |    47 #include "third_party/sqlite/preprocessed/sqlite3.h" | 
|    47  |    48  | 
|    48 using browser_sync::TestIdFactory; |    49 using browser_sync::TestIdFactory; | 
|    49 using std::cout; |    50 using std::cout; | 
|    50 using std::endl; |    51 using std::endl; | 
|    51 using std::string; |    52 using std::string; | 
|    52  |    53  | 
|    53 namespace syncable { |    54 namespace syncable { | 
|    54  |    55  | 
 |    56 namespace { | 
|    55 // A lot of these tests were written expecting to be able to read and write |    57 // A lot of these tests were written expecting to be able to read and write | 
|    56 // object data on entries.  However, the design has changed. |    58 // object data on entries.  However, the design has changed. | 
|    57 void PutDataAsExtendedAttribute(WriteTransaction* wtrans, |    59 void PutDataAsExtendedAttribute(WriteTransaction* wtrans, | 
|    58                                 MutableEntry* e, |    60                                 MutableEntry* e, | 
|    59                                 const char* bytes, |    61                                 const char* bytes, | 
|    60                                 size_t bytes_length) { |    62                                 size_t bytes_length) { | 
|    61   ExtendedAttributeKey key(e->Get(META_HANDLE), PSTR("DATA")); |    63   ExtendedAttributeKey key(e->Get(META_HANDLE), PSTR("DATA")); | 
|    62   MutableExtendedAttribute attr(wtrans, CREATE, key); |    64   MutableExtendedAttribute attr(wtrans, CREATE, key); | 
|    63   Blob bytes_blob(bytes, bytes + bytes_length); |    65   Blob bytes_blob(bytes, bytes + bytes_length); | 
|    64   attr.mutable_value()->swap(bytes_blob); |    66   attr.mutable_value()->swap(bytes_blob); | 
|    65 } |    67 } | 
|    66  |    68  | 
|    67 void ExpectDataFromExtendedAttributeEquals(BaseTransaction* trans, |    69 void ExpectDataFromExtendedAttributeEquals(BaseTransaction* trans, | 
|    68                                            Entry* e, |    70                                            Entry* e, | 
|    69                                            const char* bytes, |    71                                            const char* bytes, | 
|    70                                            size_t bytes_length) { |    72                                            size_t bytes_length) { | 
 |    73   ASSERT_TRUE(e->good()); | 
|    71   Blob expected_value(bytes, bytes + bytes_length); |    74   Blob expected_value(bytes, bytes + bytes_length); | 
|    72   ExtendedAttributeKey key(e->Get(META_HANDLE), PSTR("DATA")); |    75   ExtendedAttributeKey key(e->Get(META_HANDLE), PSTR("DATA")); | 
|    73   ExtendedAttribute attr(trans, GET_BY_HANDLE, key); |    76   ExtendedAttribute attr(trans, GET_BY_HANDLE, key); | 
|    74   EXPECT_FALSE(attr.is_deleted()); |    77   EXPECT_FALSE(attr.is_deleted()); | 
|    75   EXPECT_EQ(expected_value, attr.value()); |    78   EXPECT_EQ(expected_value, attr.value()); | 
|    76 } |    79 } | 
|    77  |    80 }  // namespace | 
|    78  |    81  | 
|    79 TEST(Syncable, General) { |    82 TEST(Syncable, General) { | 
|    80   remove("SimpleTest.sqlite3"); |    83   remove("SimpleTest.sqlite3"); | 
|    81   Directory dir; |    84   Directory dir; | 
|    82   FilePath test_db(FILE_PATH_LITERAL("SimpleTest.sqlite3")); |    85   FilePath test_db(FILE_PATH_LITERAL("SimpleTest.sqlite3")); | 
|    83   dir.Open(test_db, PSTR("SimpleTest")); |    86   dir.Open(test_db, PSTR("SimpleTest")); | 
|    84   bool entry_exists = false; |    87  | 
|    85   int64 metahandle; |    88   int64 written_metahandle; | 
|    86   const Id id = TestIdFactory::FromNumber(99); |    89   const Id id = TestIdFactory::FromNumber(99); | 
|    87   // Test simple read operations. |    90   PathString name = PSTR("Jeff"); | 
 |    91   // Test simple read operations on an empty DB. | 
|    88   { |    92   { | 
|    89     ReadTransaction rtrans(&dir, __FILE__, __LINE__); |    93     ReadTransaction rtrans(&dir, __FILE__, __LINE__); | 
|    90     Entry e(&rtrans, GET_BY_ID, id); |    94     Entry e(&rtrans, GET_BY_ID, id); | 
|    91     if (e.good()) { |    95     ASSERT_FALSE(e.good());  // Hasn't been written yet. | 
|    92       entry_exists = true; |    96  | 
|    93       metahandle = e.Get(META_HANDLE); |  | 
|    94     } |  | 
|    95     Directory::ChildHandles child_handles; |    97     Directory::ChildHandles child_handles; | 
|    96     dir.GetChildHandles(&rtrans, rtrans.root_id(), &child_handles); |    98     dir.GetChildHandles(&rtrans, rtrans.root_id(), &child_handles); | 
|    97     for (Directory::ChildHandles::iterator i = child_handles.begin(); |    99     EXPECT_TRUE(child_handles.empty()); | 
|    98          i != child_handles.end(); ++i) |  | 
|    99       cout << *i << endl; |  | 
|   100  |  | 
|   101     Entry e2(&rtrans, GET_BY_PATH, PSTR("/Hello\\World/")); |  | 
|   102   } |   100   } | 
|   103  |   101  | 
|   104   // Test creating a new meta entry. |   102   // Test creating a new meta entry. | 
|   105   { |   103   { | 
|   106     WriteTransaction wtrans(&dir, UNITTEST, __FILE__, __LINE__); |   104     WriteTransaction wtrans(&dir, UNITTEST, __FILE__, __LINE__); | 
|   107     MutableEntry me(&wtrans, CREATE, wtrans.root_id(), PSTR("Jeff")); |   105     MutableEntry me(&wtrans, CREATE, wtrans.root_id(), name); | 
|   108     ASSERT_TRUE(entry_exists ? !me.good() : me.good()); |   106     ASSERT_TRUE(me.good()); | 
|   109     if (me.good()) { |   107     me.Put(ID, id); | 
|   110       me.Put(ID, id); |   108     me.Put(BASE_VERSION, 1); | 
|   111       me.Put(BASE_VERSION, 1); |   109     written_metahandle = me.Get(META_HANDLE); | 
|   112       metahandle = me.Get(META_HANDLE); |   110   } | 
 |   111  | 
 |   112   // Test GetChildHandles after something is now in the DB. | 
 |   113   // Also check that GET_BY_ID works. | 
 |   114   { | 
 |   115     ReadTransaction rtrans(&dir, __FILE__, __LINE__); | 
 |   116     Entry e(&rtrans, GET_BY_ID, id); | 
 |   117     ASSERT_TRUE(e.good()); | 
 |   118  | 
 |   119     Directory::ChildHandles child_handles; | 
 |   120     dir.GetChildHandles(&rtrans, rtrans.root_id(), &child_handles); | 
 |   121     EXPECT_EQ(1u, child_handles.size()); | 
 |   122  | 
 |   123     for (Directory::ChildHandles::iterator i = child_handles.begin(); | 
 |   124          i != child_handles.end(); ++i) { | 
 |   125       EXPECT_EQ(*i, written_metahandle); | 
|   113     } |   126     } | 
|   114   } |   127   } | 
|   115  |   128  | 
|   116   // Test writing data to an entity. |   129   // Test writing data to an entity. Also check that GET_BY_HANDLE works. | 
|   117   static const char s[] = "Hello World."; |   130   static const char s[] = "Hello World."; | 
|   118   { |   131   { | 
|   119     WriteTransaction trans(&dir, UNITTEST, __FILE__, __LINE__); |   132     WriteTransaction trans(&dir, UNITTEST, __FILE__, __LINE__); | 
|   120     MutableEntry e(&trans, GET_BY_PATH, |   133     MutableEntry e(&trans, GET_BY_HANDLE, written_metahandle); | 
|   121                    PathString(kPathSeparator) + PSTR("Jeff")); |  | 
|   122     ASSERT_TRUE(e.good()); |   134     ASSERT_TRUE(e.good()); | 
|   123     PutDataAsExtendedAttribute(&trans, &e, s, sizeof(s)); |   135     PutDataAsExtendedAttribute(&trans, &e, s, sizeof(s)); | 
|   124   } |   136   } | 
|   125  |   137  | 
|   126   // Test reading back the name contents that we just wrote. |   138   // Test reading back the contents that we just wrote. | 
|   127   { |   139   { | 
|   128     WriteTransaction trans(&dir, UNITTEST, __FILE__, __LINE__); |   140     WriteTransaction trans(&dir, UNITTEST, __FILE__, __LINE__); | 
|   129     MutableEntry e(&trans, GET_BY_PATH, |   141     MutableEntry e(&trans, GET_BY_HANDLE, written_metahandle); | 
|   130                    PathString(kPathSeparator) + PSTR("Jeff")); |  | 
|   131     ASSERT_TRUE(e.good()); |   142     ASSERT_TRUE(e.good()); | 
|   132     ExpectDataFromExtendedAttributeEquals(&trans, &e, s, sizeof(s)); |   143     ExpectDataFromExtendedAttributeEquals(&trans, &e, s, sizeof(s)); | 
|   133   } |   144   } | 
|   134  |   145  | 
 |   146   // Verify it exists in the folder. | 
 |   147   { | 
 |   148     ReadTransaction rtrans(&dir, __FILE__, __LINE__); | 
 |   149     EXPECT_EQ(1, CountEntriesWithName(&rtrans, rtrans.root_id(), name)); | 
 |   150   } | 
 |   151  | 
|   135   // Now delete it. |   152   // Now delete it. | 
|   136   { |   153   { | 
|   137     WriteTransaction trans(&dir, UNITTEST, __FILE__, __LINE__); |   154     WriteTransaction trans(&dir, UNITTEST, __FILE__, __LINE__); | 
|   138     MutableEntry e(&trans, CREATE, trans.root_id(), PSTR("New File")); |   155     MutableEntry e(&trans, GET_BY_HANDLE, written_metahandle); | 
|   139     e.Put(IS_DEL, true); |   156     e.Put(IS_DEL, true); | 
 |   157  | 
 |   158     EXPECT_EQ(0, CountEntriesWithName(&trans, trans.root_id(), name)); | 
|   140   } |   159   } | 
|   141  |   160  | 
|   142   dir.SaveChanges(); |   161   dir.SaveChanges(); | 
|   143 } |   162   remove("SimpleTest.sqlite3"); | 
|   144  |  | 
|   145 TEST(Syncable, NameClassTest) { |  | 
|   146   const PathString foo(PSTR("foo")); |  | 
|   147   const PathString bar(PSTR("bar")); |  | 
|   148  |  | 
|   149   Name name1(foo); |  | 
|   150   EXPECT_EQ(name1.value(), foo); |  | 
|   151   EXPECT_EQ(name1.db_value(), foo); |  | 
|   152   EXPECT_FALSE(name1.HasBeenSanitized()); |  | 
|   153   EXPECT_TRUE(name1.GetUnsanitizedName().empty()); |  | 
|   154  |  | 
|   155   Name name2(foo, foo); |  | 
|   156   EXPECT_EQ(name2.value(), foo); |  | 
|   157   EXPECT_EQ(name2.db_value(), foo); |  | 
|   158   EXPECT_FALSE(name2.HasBeenSanitized()); |  | 
|   159   EXPECT_TRUE(name2.GetUnsanitizedName().empty()); |  | 
|   160  |  | 
|   161   Name name3(foo, bar); |  | 
|   162   EXPECT_EQ(name3.value(), bar); |  | 
|   163   EXPECT_EQ(name3.db_value(), foo); |  | 
|   164   EXPECT_TRUE(name3.HasBeenSanitized()); |  | 
|   165   EXPECT_EQ(name3.GetUnsanitizedName(), bar); |  | 
|   166  |  | 
|   167   EXPECT_TRUE(name1 == name2); |  | 
|   168   EXPECT_FALSE(name1 != name2); |  | 
|   169   EXPECT_FALSE(name2 == name3); |  | 
|   170   EXPECT_TRUE(name2 != name3); |  | 
|   171 } |   163 } | 
|   172  |   164  | 
|   173 namespace { |   165 namespace { | 
|   174  |   166  | 
|   175 // A Directory whose backing store always fails SaveChanges by returning false. |   167 // A Directory whose backing store always fails SaveChanges by returning false. | 
|   176 class TestUnsaveableDirectory : public Directory { |   168 class TestUnsaveableDirectory : public Directory { | 
|   177  public: |   169  public: | 
|   178   class UnsaveableBackingStore : public DirectoryBackingStore { |   170   class UnsaveableBackingStore : public DirectoryBackingStore { | 
|   179    public: |   171    public: | 
|   180      UnsaveableBackingStore(const PathString& dir_name, |   172      UnsaveableBackingStore(const PathString& dir_name, | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   253   ASSERT_FALSE(e.good()); |   245   ASSERT_FALSE(e.good()); | 
|   254 } |   246 } | 
|   255  |   247  | 
|   256 TEST_F(SyncableDirectoryTest, TestBasicLookupValidID) { |   248 TEST_F(SyncableDirectoryTest, TestBasicLookupValidID) { | 
|   257   CreateEntry(PSTR("rtc")); |   249   CreateEntry(PSTR("rtc")); | 
|   258   ReadTransaction rtrans(dir_.get(), __FILE__, __LINE__); |   250   ReadTransaction rtrans(dir_.get(), __FILE__, __LINE__); | 
|   259   Entry e(&rtrans, GET_BY_ID, kId); |   251   Entry e(&rtrans, GET_BY_ID, kId); | 
|   260   ASSERT_TRUE(e.good()); |   252   ASSERT_TRUE(e.good()); | 
|   261 } |   253 } | 
|   262  |   254  | 
|   263 TEST_F(SyncableDirectoryTest, TestBasicCaseSensitivity) { |  | 
|   264   PathString name = PSTR("RYAN"); |  | 
|   265   PathString conflicting_name = PSTR("ryan"); |  | 
|   266   CreateEntry(name); |  | 
|   267  |  | 
|   268   WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); |  | 
|   269   MutableEntry me(&wtrans, CREATE, wtrans.root_id(), conflicting_name); |  | 
|   270   ASSERT_FALSE(me.good()); |  | 
|   271 } |  | 
|   272  |  | 
|   273 TEST_F(SyncableDirectoryTest, TestDelete) { |   255 TEST_F(SyncableDirectoryTest, TestDelete) { | 
|   274   PathString name = PSTR("peanut butter jelly time"); |   256   PathString name = PSTR("peanut butter jelly time"); | 
|   275   WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   257   WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   276   MutableEntry e1(&trans, CREATE, trans.root_id(), name); |   258   MutableEntry e1(&trans, CREATE, trans.root_id(), name); | 
|   277   ASSERT_TRUE(e1.good()); |   259   ASSERT_TRUE(e1.good()); | 
|   278   ASSERT_TRUE(e1.Put(IS_DEL, true)); |   260   ASSERT_TRUE(e1.Put(IS_DEL, true)); | 
|   279   MutableEntry e2(&trans, CREATE, trans.root_id(), name); |   261   MutableEntry e2(&trans, CREATE, trans.root_id(), name); | 
|   280   ASSERT_TRUE(e2.good()); |   262   ASSERT_TRUE(e2.good()); | 
|   281   ASSERT_TRUE(e2.Put(IS_DEL, true)); |   263   ASSERT_TRUE(e2.Put(IS_DEL, true)); | 
|   282   MutableEntry e3(&trans, CREATE, trans.root_id(), name); |   264   MutableEntry e3(&trans, CREATE, trans.root_id(), name); | 
|   283   ASSERT_TRUE(e3.good()); |   265   ASSERT_TRUE(e3.good()); | 
|   284   ASSERT_TRUE(e3.Put(IS_DEL, true)); |   266   ASSERT_TRUE(e3.Put(IS_DEL, true)); | 
|   285  |   267  | 
 |   268   ASSERT_TRUE(e1.Put(IS_DEL, false)); | 
 |   269   ASSERT_TRUE(e2.Put(IS_DEL, false)); | 
|   286   ASSERT_TRUE(e3.Put(IS_DEL, false)); |   270   ASSERT_TRUE(e3.Put(IS_DEL, false)); | 
|   287   ASSERT_FALSE(e1.Put(IS_DEL, false)); |   271  | 
|   288   ASSERT_FALSE(e2.Put(IS_DEL, false)); |   272   ASSERT_TRUE(e1.Put(IS_DEL, true)); | 
 |   273   ASSERT_TRUE(e2.Put(IS_DEL, true)); | 
|   289   ASSERT_TRUE(e3.Put(IS_DEL, true)); |   274   ASSERT_TRUE(e3.Put(IS_DEL, true)); | 
|   290  |  | 
|   291   ASSERT_TRUE(e1.Put(IS_DEL, false)); |  | 
|   292   ASSERT_FALSE(e2.Put(IS_DEL, false)); |  | 
|   293   ASSERT_FALSE(e3.Put(IS_DEL, false)); |  | 
|   294   ASSERT_TRUE(e1.Put(IS_DEL, true)); |  | 
|   295 } |   275 } | 
|   296  |   276  | 
|   297 TEST_F(SyncableDirectoryTest, TestGetUnsynced) { |   277 TEST_F(SyncableDirectoryTest, TestGetUnsynced) { | 
|   298   Directory::UnsyncedMetaHandles handles; |   278   Directory::UnsyncedMetaHandles handles; | 
|   299   int64 handle1, handle2; |   279   int64 handle1, handle2; | 
|   300   { |   280   { | 
|   301     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   281     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   302  |   282  | 
|   303     dir_->GetUnsyncedMetaHandles(&trans, &handles); |   283     dir_->GetUnsyncedMetaHandles(&trans, &handles); | 
|   304     ASSERT_TRUE(0 == handles.size()); |   284     ASSERT_TRUE(0 == handles.size()); | 
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   455     child.Put(BASE_VERSION, 1); |   435     child.Put(BASE_VERSION, 1); | 
|   456     MutableEntry grandchild(&wtrans, CREATE, child.Get(ID), PSTR("Bob")); |   436     MutableEntry grandchild(&wtrans, CREATE, child.Get(ID), PSTR("Bob")); | 
|   457     ASSERT_TRUE(grandchild.good()); |   437     ASSERT_TRUE(grandchild.good()); | 
|   458     grandchild.Put(ID, id_factory.NewServerId()); |   438     grandchild.Put(ID, id_factory.NewServerId()); | 
|   459     grandchild.Put(BASE_VERSION, 1); |   439     grandchild.Put(BASE_VERSION, 1); | 
|   460     ASSERT_TRUE(grandchild.Put(IS_DEL, true)); |   440     ASSERT_TRUE(grandchild.Put(IS_DEL, true)); | 
|   461     MutableEntry twin(&wtrans, CREATE, child.Get(ID), PSTR("Bob")); |   441     MutableEntry twin(&wtrans, CREATE, child.Get(ID), PSTR("Bob")); | 
|   462     ASSERT_TRUE(twin.good()); |   442     ASSERT_TRUE(twin.good()); | 
|   463     ASSERT_TRUE(twin.Put(IS_DEL, true)); |   443     ASSERT_TRUE(twin.Put(IS_DEL, true)); | 
|   464     ASSERT_TRUE(grandchild.Put(IS_DEL, false)); |   444     ASSERT_TRUE(grandchild.Put(IS_DEL, false)); | 
|   465     ASSERT_FALSE(twin.Put(IS_DEL, false)); |   445  | 
|   466     grandchild_handle = grandchild.Get(META_HANDLE); |   446     grandchild_handle = grandchild.Get(META_HANDLE); | 
|   467     twin_handle = twin.Get(META_HANDLE); |   447     twin_handle = twin.Get(META_HANDLE); | 
|   468   } |   448   } | 
|   469   dir_->SaveChanges(); |   449   dir_->SaveChanges(); | 
|   470   { |   450   { | 
|   471     WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   451     WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   472     MutableEntry grandchild(&wtrans, GET_BY_HANDLE, grandchild_handle); |   452     MutableEntry grandchild(&wtrans, GET_BY_HANDLE, grandchild_handle); | 
|   473     grandchild.Put(IS_DEL, true);  // Used to CHECK fail here. |   453     grandchild.Put(IS_DEL, true);  // Used to CHECK fail here. | 
|   474   } |   454   } | 
|   475 } |   455 } | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   524   ASSERT_TRUE(IsLegalNewParent(child, parent)); |   504   ASSERT_TRUE(IsLegalNewParent(child, parent)); | 
|   525   ASSERT_FALSE(IsLegalNewParent(child, child)); |   505   ASSERT_FALSE(IsLegalNewParent(child, child)); | 
|   526   ASSERT_FALSE(IsLegalNewParent(child, grandchild)); |   506   ASSERT_FALSE(IsLegalNewParent(child, grandchild)); | 
|   527   ASSERT_TRUE(IsLegalNewParent(child, parent2)); |   507   ASSERT_TRUE(IsLegalNewParent(child, parent2)); | 
|   528   ASSERT_TRUE(IsLegalNewParent(child, grandchild2)); |   508   ASSERT_TRUE(IsLegalNewParent(child, grandchild2)); | 
|   529   ASSERT_FALSE(IsLegalNewParent(parent, grandchild)); |   509   ASSERT_FALSE(IsLegalNewParent(parent, grandchild)); | 
|   530   ASSERT_FALSE(IsLegalNewParent(root, grandchild)); |   510   ASSERT_FALSE(IsLegalNewParent(root, grandchild)); | 
|   531   ASSERT_FALSE(IsLegalNewParent(parent, grandchild)); |   511   ASSERT_FALSE(IsLegalNewParent(parent, grandchild)); | 
|   532 } |   512 } | 
|   533  |   513  | 
|   534 TEST_F(SyncableDirectoryTest, TestFindEntryInFolder) { |   514 TEST_F(SyncableDirectoryTest, TestEntryIsInFolder) { | 
|   535   // Create a subdir and an entry. |   515   // Create a subdir and an entry. | 
|   536   int64 entry_handle; |   516   int64 entry_handle; | 
 |   517   syncable::Id folder_id; | 
 |   518   syncable::Id entry_id; | 
 |   519   PathString entry_name = PSTR("entry"); | 
 |   520  | 
|   537   { |   521   { | 
|   538     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   522     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   539     MutableEntry folder(&trans, CREATE, trans.root_id(), PSTR("folder")); |   523     MutableEntry folder(&trans, CREATE, trans.root_id(), PSTR("folder")); | 
|   540     ASSERT_TRUE(folder.good()); |   524     ASSERT_TRUE(folder.good()); | 
|   541     EXPECT_TRUE(folder.Put(IS_DIR, true)); |   525     EXPECT_TRUE(folder.Put(IS_DIR, true)); | 
|   542     EXPECT_TRUE(folder.Put(IS_UNSYNCED, true)); |   526     EXPECT_TRUE(folder.Put(IS_UNSYNCED, true)); | 
|   543     MutableEntry entry(&trans, CREATE, folder.Get(ID), PSTR("entry")); |   527     folder_id = folder.Get(ID); | 
 |   528  | 
 |   529     MutableEntry entry(&trans, CREATE, folder.Get(ID), entry_name); | 
|   544     ASSERT_TRUE(entry.good()); |   530     ASSERT_TRUE(entry.good()); | 
|   545     entry_handle = entry.Get(META_HANDLE); |   531     entry_handle = entry.Get(META_HANDLE); | 
|   546     entry.Put(IS_UNSYNCED, true); |   532     entry.Put(IS_UNSYNCED, true); | 
 |   533     entry_id = entry.Get(ID); | 
|   547   } |   534   } | 
|   548  |   535  | 
|   549   // Make sure we can find the entry in the folder. |   536   // Make sure we can find the entry in the folder. | 
|   550   { |   537   { | 
|   551     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |   538     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); | 
|   552     Entry entry(&trans, GET_BY_PATH, PathString(kPathSeparator) + |   539     EXPECT_EQ(0, CountEntriesWithName(&trans, trans.root_id(), entry_name)); | 
|   553                                     PSTR("folder") + |   540     EXPECT_EQ(1, CountEntriesWithName(&trans, folder_id, entry_name)); | 
|   554                                     kPathSeparator + PSTR("entry")); |   541  | 
 |   542     Entry entry(&trans, GET_BY_ID, entry_id); | 
|   555     ASSERT_TRUE(entry.good()); |   543     ASSERT_TRUE(entry.good()); | 
|   556     ASSERT_TRUE(entry.Get(META_HANDLE) == entry_handle); |   544     EXPECT_EQ(entry_handle, entry.Get(META_HANDLE)); | 
 |   545     EXPECT_TRUE(entry.Get(NON_UNIQUE_NAME) == entry_name); | 
 |   546     EXPECT_TRUE(entry.Get(PARENT_ID) == folder_id); | 
|   557   } |   547   } | 
|   558 } |   548 } | 
|   559  |   549  | 
|   560 TEST_F(SyncableDirectoryTest, TestGetByParentIdAndName) { |   550 TEST_F(SyncableDirectoryTest, TestParentIdIndexUpdate) { | 
|   561   PathString name = PSTR("Bob"); |   551   PathString child_name = PSTR("child"); | 
|   562   Id id = TestIdFactory::MakeServer("ID for Bob"); |  | 
|   563   { |  | 
|   564     WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); |  | 
|   565     MutableEntry entry(&wtrans, CREATE, wtrans.root_id() /*entry id*/, name); |  | 
|   566     ASSERT_TRUE(entry.good()); |  | 
|   567     entry.Put(IS_DIR, true); |  | 
|   568     entry.Put(ID, id); |  | 
|   569     entry.Put(BASE_VERSION, 1); |  | 
|   570     entry.Put(IS_UNSYNCED, true); |  | 
|   571   } |  | 
|   572   { |  | 
|   573     WriteTransaction wtrans(dir_.get(), UNITTEST, __FILE__, __LINE__); |  | 
|   574     MutableEntry entry(&wtrans, GET_BY_PARENTID_AND_NAME, wtrans.root_id(), |  | 
|   575                        name); |  | 
|   576     ASSERT_TRUE(entry.good()); |  | 
|   577     ASSERT_TRUE(id == entry.Get(ID)); |  | 
|   578   } |  | 
|   579   { |  | 
|   580     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |  | 
|   581     Entry entry(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), name); |  | 
|   582     ASSERT_TRUE(entry.good()); |  | 
|   583     ASSERT_TRUE(id == entry.Get(ID)); |  | 
|   584   } |  | 
|   585 } |  | 
|   586  |   552  | 
|   587 TEST_F(SyncableDirectoryTest, TestParentIDIndexUpdate) { |  | 
|   588   WriteTransaction wt(dir_.get(), UNITTEST, __FILE__, __LINE__); |   553   WriteTransaction wt(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   589   MutableEntry folder(&wt, CREATE, wt.root_id(), PSTR("oldname")); |   554   MutableEntry parent_folder(&wt, CREATE, wt.root_id(), PSTR("folder1")); | 
|   590   folder.Put(NAME, PSTR("newname")); |   555   parent_folder.Put(IS_UNSYNCED, true); | 
|   591   folder.Put(IS_UNSYNCED, true); |   556   EXPECT_TRUE(parent_folder.Put(IS_DIR, true)); | 
|   592   Entry entry(&wt, GET_BY_PATH, PSTR("newname")); |   557  | 
|   593   ASSERT_TRUE(entry.good()); |   558   MutableEntry parent_folder2(&wt, CREATE, wt.root_id(), PSTR("folder2")); | 
 |   559   parent_folder2.Put(IS_UNSYNCED, true); | 
 |   560   EXPECT_TRUE(parent_folder2.Put(IS_DIR, true)); | 
 |   561  | 
 |   562   MutableEntry child(&wt, CREATE, parent_folder.Get(ID), child_name); | 
 |   563   EXPECT_TRUE(child.Put(IS_DIR, true)); | 
 |   564   child.Put(IS_UNSYNCED, true); | 
 |   565  | 
 |   566   ASSERT_TRUE(child.good()); | 
 |   567  | 
 |   568   EXPECT_EQ(0, CountEntriesWithName(&wt, wt.root_id(), child_name)); | 
 |   569   EXPECT_EQ(parent_folder.Get(ID), child.Get(PARENT_ID)); | 
 |   570   EXPECT_EQ(1, CountEntriesWithName(&wt, parent_folder.Get(ID), child_name)); | 
 |   571   EXPECT_EQ(0, CountEntriesWithName(&wt, parent_folder2.Get(ID), child_name)); | 
 |   572   child.Put(PARENT_ID, parent_folder2.Get(ID)); | 
 |   573   EXPECT_EQ(parent_folder2.Get(ID), child.Get(PARENT_ID)); | 
 |   574   EXPECT_EQ(0, CountEntriesWithName(&wt, parent_folder.Get(ID), child_name)); | 
 |   575   EXPECT_EQ(1, CountEntriesWithName(&wt, parent_folder2.Get(ID), child_name)); | 
 |   576  | 
|   594 } |   577 } | 
|   595  |   578  | 
|   596 TEST_F(SyncableDirectoryTest, TestNoReindexDeletedItems) { |   579 TEST_F(SyncableDirectoryTest, TestNoReindexDeletedItems) { | 
 |   580   PathString folder_name = PSTR("folder"); | 
 |   581   PathString new_name = PSTR("new_name"); | 
 |   582  | 
|   597   WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   583   WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   598   MutableEntry folder(&trans, CREATE, trans.root_id(), PSTR("folder")); |   584   MutableEntry folder(&trans, CREATE, trans.root_id(), folder_name); | 
|   599   ASSERT_TRUE(folder.good()); |   585   ASSERT_TRUE(folder.good()); | 
|   600   ASSERT_TRUE(folder.Put(IS_DIR, true)); |   586   ASSERT_TRUE(folder.Put(IS_DIR, true)); | 
|   601   ASSERT_TRUE(folder.Put(IS_DEL, true)); |   587   ASSERT_TRUE(folder.Put(IS_DEL, true)); | 
|   602   Entry gone(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("folder")); |   588  | 
|   603   ASSERT_FALSE(gone.good()); |   589   EXPECT_EQ(0, CountEntriesWithName(&trans, trans.root_id(), folder_name)); | 
|   604   ASSERT_TRUE(folder.PutParentIdAndName(trans.root_id(), |   590  | 
|   605                                         Name(PSTR("new_name")))); |   591   MutableEntry deleted(&trans, GET_BY_ID, folder.Get(ID)); | 
 |   592   ASSERT_TRUE(deleted.good()); | 
 |   593   ASSERT_TRUE(deleted.Put(PARENT_ID, trans.root_id())); | 
 |   594   ASSERT_TRUE(deleted.Put(NON_UNIQUE_NAME, new_name)); | 
 |   595  | 
 |   596   EXPECT_EQ(0, CountEntriesWithName(&trans, trans.root_id(), folder_name)); | 
 |   597   EXPECT_EQ(0, CountEntriesWithName(&trans, trans.root_id(), new_name)); | 
|   606 } |   598 } | 
|   607  |   599  | 
|   608 TEST_F(SyncableDirectoryTest, TestCaseChangeRename) { |   600 TEST_F(SyncableDirectoryTest, TestCaseChangeRename) { | 
|   609   WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   601   WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   610   MutableEntry folder(&trans, CREATE, trans.root_id(), PSTR("CaseChange")); |   602   MutableEntry folder(&trans, CREATE, trans.root_id(), PSTR("CaseChange")); | 
|   611   ASSERT_TRUE(folder.good()); |   603   ASSERT_TRUE(folder.good()); | 
|   612   EXPECT_TRUE(folder.PutParentIdAndName(trans.root_id(), |   604   EXPECT_TRUE(folder.Put(PARENT_ID, trans.root_id())); | 
|   613                                         Name(PSTR("CASECHANGE")))); |   605   EXPECT_TRUE(folder.Put(NON_UNIQUE_NAME, PSTR("CASECHANGE"))); | 
|   614   EXPECT_TRUE(folder.Put(IS_DEL, true)); |   606   EXPECT_TRUE(folder.Put(IS_DEL, true)); | 
|   615 } |   607 } | 
|   616  |   608  | 
|   617 TEST_F(SyncableDirectoryTest, TestShareInfo) { |   609 TEST_F(SyncableDirectoryTest, TestShareInfo) { | 
|   618   dir_->set_last_sync_timestamp(100); |   610   dir_->set_last_sync_timestamp(100); | 
|   619   dir_->set_store_birthday("Jan 31st"); |   611   dir_->set_store_birthday("Jan 31st"); | 
|   620   { |   612   { | 
|   621     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |   613     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); | 
|   622     EXPECT_EQ(100, dir_->last_sync_timestamp()); |   614     EXPECT_EQ(100, dir_->last_sync_timestamp()); | 
|   623     EXPECT_EQ("Jan 31st", dir_->store_birthday()); |   615     EXPECT_EQ("Jan 31st", dir_->store_birthday()); | 
|   624   } |   616   } | 
|   625   dir_->set_last_sync_timestamp(200); |   617   dir_->set_last_sync_timestamp(200); | 
|   626   dir_->set_store_birthday("April 10th"); |   618   dir_->set_store_birthday("April 10th"); | 
|   627   dir_->SaveChanges(); |   619   dir_->SaveChanges(); | 
|   628   { |   620   { | 
|   629     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |   621     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); | 
|   630     EXPECT_EQ(200, dir_->last_sync_timestamp()); |   622     EXPECT_EQ(200, dir_->last_sync_timestamp()); | 
|   631     EXPECT_EQ("April 10th", dir_->store_birthday()); |   623     EXPECT_EQ("April 10th", dir_->store_birthday()); | 
|   632   } |   624   } | 
|   633 } |   625 } | 
|   634  |   626  | 
|   635 TEST_F(SyncableDirectoryTest, TestSimpleFieldsPreservedDuringSaveChanges) { |   627 TEST_F(SyncableDirectoryTest, TestSimpleFieldsPreservedDuringSaveChanges) { | 
|   636   Id id = TestIdFactory::FromNumber(1); |   628   Id update_id = TestIdFactory::FromNumber(1); | 
 |   629   Id create_id; | 
|   637   EntryKernel create_pre_save, update_pre_save; |   630   EntryKernel create_pre_save, update_pre_save; | 
|   638   EntryKernel create_post_save, update_post_save; |   631   EntryKernel create_post_save, update_post_save; | 
 |   632   PathString create_name =  PSTR("Create"); | 
 |   633  | 
|   639   { |   634   { | 
|   640     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   635     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   641     MutableEntry create(&trans, CREATE, trans.root_id(), PSTR("Create")); |   636     MutableEntry create(&trans, CREATE, trans.root_id(), create_name); | 
|   642     MutableEntry update(&trans, CREATE_NEW_UPDATE_ITEM, id); |   637     MutableEntry update(&trans, CREATE_NEW_UPDATE_ITEM, update_id); | 
|   643     create.Put(IS_UNSYNCED, true); |   638     create.Put(IS_UNSYNCED, true); | 
|   644     update.Put(IS_UNAPPLIED_UPDATE, true); |   639     update.Put(IS_UNAPPLIED_UPDATE, true); | 
|   645     create_pre_save = create.GetKernelCopy(); |   640     create_pre_save = create.GetKernelCopy(); | 
|   646     update_pre_save = update.GetKernelCopy(); |   641     update_pre_save = update.GetKernelCopy(); | 
 |   642     create_id = create.Get(ID); | 
|   647   } |   643   } | 
|   648   dir_->SaveChanges(); |   644   dir_->SaveChanges(); | 
 |   645  | 
|   649   { |   646   { | 
|   650     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |   647     ReadTransaction trans(dir_.get(), __FILE__, __LINE__); | 
|   651     Entry create(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), |   648     Entry create(&trans, GET_BY_ID, create_id); | 
|   652                  PSTR("Create")); |   649     EXPECT_EQ(1, CountEntriesWithName(&trans, trans.root_id(), create_name)); | 
|   653     Entry update(&trans, GET_BY_ID, id); |   650     Entry update(&trans, GET_BY_ID, update_id); | 
|   654     create_post_save = create.GetKernelCopy(); |   651     create_post_save = create.GetKernelCopy(); | 
|   655     update_post_save = update.GetKernelCopy(); |   652     update_post_save = update.GetKernelCopy(); | 
|   656   } |   653   } | 
|   657   int i = BEGIN_FIELDS; |   654   int i = BEGIN_FIELDS; | 
|   658   for ( ; i < INT64_FIELDS_END ; ++i) { |   655   for ( ; i < INT64_FIELDS_END ; ++i) { | 
|   659     EXPECT_EQ(create_pre_save.ref((Int64Field)i), |   656     EXPECT_EQ(create_pre_save.ref((Int64Field)i), | 
|   660               create_post_save.ref((Int64Field)i)) |   657               create_post_save.ref((Int64Field)i)) | 
|   661               << "int64 field #" << i << " changed during save/load"; |   658               << "int64 field #" << i << " changed during save/load"; | 
|   662     EXPECT_EQ(update_pre_save.ref((Int64Field)i), |   659     EXPECT_EQ(update_pre_save.ref((Int64Field)i), | 
|   663               update_post_save.ref((Int64Field)i)) |   660               update_post_save.ref((Int64Field)i)) | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   706   dir_.reset(new TestUnsaveableDirectory()); |   703   dir_.reset(new TestUnsaveableDirectory()); | 
|   707   ASSERT_TRUE(dir_.get()); |   704   ASSERT_TRUE(dir_.get()); | 
|   708   ASSERT_TRUE(OPENED == dir_->Open(FilePath(kFilePath), kName)); |   705   ASSERT_TRUE(OPENED == dir_->Open(FilePath(kFilePath), kName)); | 
|   709   ASSERT_TRUE(dir_->good()); |   706   ASSERT_TRUE(dir_->good()); | 
|   710   int64 handle2 = 0; |   707   int64 handle2 = 0; | 
|   711   { |   708   { | 
|   712     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |   709     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|   713  |   710  | 
|   714     MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); |   711     MutableEntry aguilera(&trans, GET_BY_HANDLE, handle1); | 
|   715     ASSERT_TRUE(aguilera.good()); |   712     ASSERT_TRUE(aguilera.good()); | 
|   716     aguilera.Put(NAME, PSTR("christina")); |   713     aguilera.Put(NON_UNIQUE_NAME, PSTR("christina")); | 
|   717     ASSERT_TRUE(aguilera.GetKernelCopy().dirty[NAME]); |   714     ASSERT_TRUE(aguilera.GetKernelCopy().dirty[NON_UNIQUE_NAME]); | 
|   718  |   715  | 
|   719     MutableEntry kids_on_block(&trans, CREATE, trans.root_id(), PSTR("kids")); |   716     MutableEntry kids_on_block(&trans, CREATE, trans.root_id(), PSTR("kids")); | 
|   720     ASSERT_TRUE(kids_on_block.good()); |   717     ASSERT_TRUE(kids_on_block.good()); | 
|   721     handle2 = kids_on_block.Get(META_HANDLE); |   718     handle2 = kids_on_block.Get(META_HANDLE); | 
|   722     kids_on_block.Put(BASE_VERSION, 1); |   719     kids_on_block.Put(BASE_VERSION, 1); | 
|   723     kids_on_block.Put(IS_DIR, true); |   720     kids_on_block.Put(IS_DIR, true); | 
|   724     kids_on_block.Put(ID, TestIdFactory::FromNumber(102)); |   721     kids_on_block.Put(ID, TestIdFactory::FromNumber(102)); | 
|   725     EXPECT_TRUE(kids_on_block.Get(IS_NEW)); |   722     EXPECT_TRUE(kids_on_block.Get(IS_NEW)); | 
|   726   } |   723   } | 
|   727  |   724  | 
|   728   // We are using an unsaveable directory, so this can't succeed.  However, |   725   // We are using an unsaveable directory, so this can't succeed.  However, | 
|   729   // the HandleSaveChangesFailure code path should have been triggered. |   726   // the HandleSaveChangesFailure code path should have been triggered. | 
|   730   ASSERT_FALSE(dir_->SaveChanges()); |   727   ASSERT_FALSE(dir_->SaveChanges()); | 
|   731  |   728  | 
|   732   // Make sure things were rolled back and the world is as it was before call. |   729   // Make sure things were rolled back and the world is as it was before call. | 
|   733   { |   730   { | 
|   734      ReadTransaction trans(dir_.get(), __FILE__, __LINE__); |   731      ReadTransaction trans(dir_.get(), __FILE__, __LINE__); | 
|   735      Entry e1(&trans, GET_BY_HANDLE, handle1); |   732      Entry e1(&trans, GET_BY_HANDLE, handle1); | 
|   736      ASSERT_TRUE(e1.good()); |   733      ASSERT_TRUE(e1.good()); | 
|   737      const EntryKernel& aguilera = e1.GetKernelCopy(); |   734      const EntryKernel& aguilera = e1.GetKernelCopy(); | 
|   738      Entry kids_on_block(&trans, GET_BY_HANDLE, handle2); |   735      Entry kids_on_block(&trans, GET_BY_HANDLE, handle2); | 
|   739      ASSERT_TRUE(kids_on_block.good()); |   736      ASSERT_TRUE(kids_on_block.good()); | 
|   740  |   737  | 
|   741      EXPECT_TRUE(aguilera.dirty[NAME]); |   738      EXPECT_TRUE(aguilera.dirty[NON_UNIQUE_NAME]); | 
|   742      EXPECT_TRUE(kids_on_block.Get(IS_NEW)); |   739      EXPECT_TRUE(kids_on_block.Get(IS_NEW)); | 
|   743   } |   740   } | 
|   744 } |   741 } | 
|   745  |   742  | 
|   746  |   743  | 
|   747 void SyncableDirectoryTest::ValidateEntry(BaseTransaction* trans, int64 id, |   744 void SyncableDirectoryTest::ValidateEntry(BaseTransaction* trans, int64 id, | 
|   748     bool check_name, PathString name, int64 base_version, int64 server_version, |   745     bool check_name, PathString name, int64 base_version, int64 server_version, | 
|   749     bool is_del) { |   746     bool is_del) { | 
|   750   Entry e(trans, GET_BY_ID, TestIdFactory::FromNumber(id)); |   747   Entry e(trans, GET_BY_ID, TestIdFactory::FromNumber(id)); | 
|   751   ASSERT_TRUE(e.good()); |   748   ASSERT_TRUE(e.good()); | 
|   752   if (check_name) |   749   if (check_name) { | 
|   753     ASSERT_TRUE(name == e.Get(NAME)); |   750     ASSERT_TRUE(name == e.Get(NON_UNIQUE_NAME)); | 
 |   751   } | 
|   754   ASSERT_TRUE(base_version == e.Get(BASE_VERSION)); |   752   ASSERT_TRUE(base_version == e.Get(BASE_VERSION)); | 
|   755   ASSERT_TRUE(server_version == e.Get(SERVER_VERSION)); |   753   ASSERT_TRUE(server_version == e.Get(SERVER_VERSION)); | 
|   756   ASSERT_TRUE(is_del == e.Get(IS_DEL)); |   754   ASSERT_TRUE(is_del == e.Get(IS_DEL)); | 
|   757 } |   755 } | 
|   758  |   756  | 
|   759 TEST(SyncableDirectoryManager, TestFileRelease) { |   757 TEST(SyncableDirectoryManager, TestFileRelease) { | 
|   760   DirectoryManager dm(FilePath(FILE_PATH_LITERAL("."))); |   758   DirectoryManager dm(FilePath(FILE_PATH_LITERAL("."))); | 
|   761   ASSERT_TRUE(dm.Open(PSTR("ScopeTest"))); |   759   ASSERT_TRUE(dm.Open(PSTR("ScopeTest"))); | 
|   762   { |   760   { | 
|   763     ScopedDirLookup(&dm, PSTR("ScopeTest")); |   761     ScopedDirLookup(&dm, PSTR("ScopeTest")); | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   884 class DirectoryKernelStalenessBugDelegate : public ThreadBugDelegate { |   882 class DirectoryKernelStalenessBugDelegate : public ThreadBugDelegate { | 
|   885  public: |   883  public: | 
|   886   DirectoryKernelStalenessBugDelegate(int role, Step* step, |   884   DirectoryKernelStalenessBugDelegate(int role, Step* step, | 
|   887                                                DirectoryManager* dirman) |   885                                                DirectoryManager* dirman) | 
|   888     : ThreadBugDelegate(role, step, dirman) {} |   886     : ThreadBugDelegate(role, step, dirman) {} | 
|   889  |   887  | 
|   890   virtual void ThreadMain() { |   888   virtual void ThreadMain() { | 
|   891     const char test_bytes[] = "test data"; |   889     const char test_bytes[] = "test data"; | 
|   892     const PathString dirname = PSTR("DirectoryKernelStalenessBug"); |   890     const PathString dirname = PSTR("DirectoryKernelStalenessBug"); | 
|   893     AutoLock scoped_lock(step_->mutex); |   891     AutoLock scoped_lock(step_->mutex); | 
 |   892     const Id jeff_id = TestIdFactory::FromNumber(100); | 
|   894  |   893  | 
|   895     while (step_->number < 4) { |   894     while (step_->number < 4) { | 
|   896       while (step_->number % 2 != role_) { |   895       while (step_->number % 2 != role_) { | 
|   897         step_->condvar.Wait(); |   896         step_->condvar.Wait(); | 
|   898       } |   897       } | 
|   899       switch (step_->number) { |   898       switch (step_->number) { | 
|   900       case 0: |   899       case 0: | 
|   901         { |   900         { | 
|   902           // Clean up remnants of earlier test runs. |   901           // Clean up remnants of earlier test runs. | 
|   903           file_util::Delete(directory_manager_->GetSyncDataDatabasePath(), |   902           file_util::Delete(directory_manager_->GetSyncDataDatabasePath(), | 
|   904                             true); |   903                             true); | 
|   905           // Test. |   904           // Test. | 
|   906           directory_manager_->Open(dirname); |   905           directory_manager_->Open(dirname); | 
|   907           ScopedDirLookup dir(directory_manager_, dirname); |   906           ScopedDirLookup dir(directory_manager_, dirname); | 
|   908           CHECK(dir.good()); |   907           CHECK(dir.good()); | 
|   909           WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |   908           WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 
|   910           MutableEntry me(&trans, CREATE, trans.root_id(), PSTR("Jeff")); |   909           MutableEntry me(&trans, CREATE, trans.root_id(), PSTR("Jeff")); | 
|   911           me.Put(BASE_VERSION, 1); |   910           me.Put(BASE_VERSION, 1); | 
|   912           me.Put(ID, TestIdFactory::FromNumber(100)); |   911           me.Put(ID, jeff_id); | 
|   913           PutDataAsExtendedAttribute(&trans, &me, test_bytes, |   912           PutDataAsExtendedAttribute(&trans, &me, test_bytes, | 
|   914                                      sizeof(test_bytes)); |   913                                      sizeof(test_bytes)); | 
|   915         } |   914         } | 
|   916         { |   915         { | 
|   917           ScopedDirLookup dir(directory_manager_, dirname); |   916           ScopedDirLookup dir(directory_manager_, dirname); | 
|   918           CHECK(dir.good()); |   917           CHECK(dir.good()); | 
|   919           dir->SaveChanges(); |   918           dir->SaveChanges(); | 
|   920         } |   919         } | 
|   921         directory_manager_->Close(dirname); |   920         directory_manager_->Close(dirname); | 
|   922         break; |   921         break; | 
|   923       case 1: |   922       case 1: | 
|   924         { |   923         { | 
|   925           directory_manager_->Open(dirname); |   924           directory_manager_->Open(dirname); | 
|   926           ScopedDirLookup dir(directory_manager_, dirname); |   925           ScopedDirLookup dir(directory_manager_, dirname); | 
|   927           CHECK(dir.good()); |   926           CHECK(dir.good()); | 
|   928         } |   927         } | 
|   929         break; |   928         break; | 
|   930       case 2: |   929       case 2: | 
|   931         { |   930         { | 
|   932           ScopedDirLookup dir(directory_manager_, dirname); |   931           ScopedDirLookup dir(directory_manager_, dirname); | 
|   933           CHECK(dir.good()); |   932           CHECK(dir.good()); | 
|   934         } |   933         } | 
|   935         break; |   934         break; | 
|   936       case 3: |   935       case 3: | 
|   937         { |   936         { | 
|   938           ScopedDirLookup dir(directory_manager_, dirname); |   937           ScopedDirLookup dir(directory_manager_, dirname); | 
|   939           CHECK(dir.good()); |   938           CHECK(dir.good()); | 
|   940           ReadTransaction trans(dir, __FILE__, __LINE__); |   939           ReadTransaction trans(dir, __FILE__, __LINE__); | 
|   941           Entry e(&trans, GET_BY_PATH, PSTR("Jeff")); |   940           Entry e(&trans, GET_BY_ID, jeff_id); | 
|   942           ExpectDataFromExtendedAttributeEquals(&trans, &e, test_bytes, |   941           ExpectDataFromExtendedAttributeEquals(&trans, &e, test_bytes, | 
|   943                                                 sizeof(test_bytes)); |   942                                                 sizeof(test_bytes)); | 
|   944         } |   943         } | 
|   945         // Same result as CloseAllDirectories, but more code coverage. |   944         // Same result as CloseAllDirectories, but more code coverage. | 
|   946         directory_manager_->Close(dirname); |   945         directory_manager_->Close(dirname); | 
|   947         break; |   946         break; | 
|   948       } |   947       } | 
|   949       step_->number += 1; |   948       step_->number += 1; | 
|   950       step_->condvar.Signal(); |   949       step_->condvar.Signal(); | 
|   951     } |   950     } | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   987    virtual void ThreadMain() { |   986    virtual void ThreadMain() { | 
|   988      ScopedDirLookup dir(directory_manager_, dirname_); |   987      ScopedDirLookup dir(directory_manager_, dirname_); | 
|   989      CHECK(dir.good()); |   988      CHECK(dir.good()); | 
|   990      int entry_count = 0; |   989      int entry_count = 0; | 
|   991      PathString path_name; |   990      PathString path_name; | 
|   992  |   991  | 
|   993      for (int i = 0; i < 20; ++i) { |   992      for (int i = 0; i < 20; ++i) { | 
|   994        const int rand_action = rand() % 10; |   993        const int rand_action = rand() % 10; | 
|   995        if (rand_action < 4 && !path_name.empty()) { |   994        if (rand_action < 4 && !path_name.empty()) { | 
|   996          ReadTransaction trans(dir, __FILE__, __LINE__); |   995          ReadTransaction trans(dir, __FILE__, __LINE__); | 
|   997          Entry e(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), path_name); |   996          CHECK(1 == CountEntriesWithName(&trans, trans.root_id(), path_name)); | 
|   998          PlatformThread::Sleep(rand() % 10); |   997          PlatformThread::Sleep(rand() % 10); | 
|   999          CHECK(e.good()); |  | 
|  1000        } else { |   998        } else { | 
|  1001          string unique_name = StringPrintf("%d.%d", thread_number_, |   999          string unique_name = StringPrintf("%d.%d", thread_number_, | 
|  1002            entry_count++); |  1000            entry_count++); | 
|  1003          path_name.assign(unique_name.begin(), unique_name.end()); |  1001          path_name.assign(unique_name.begin(), unique_name.end()); | 
|  1004          WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |  1002          WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 
|  1005          MutableEntry e(&trans, CREATE, trans.root_id(), path_name); |  1003          MutableEntry e(&trans, CREATE, trans.root_id(), path_name); | 
|  1006          CHECK(e.good()); |  1004          CHECK(e.good()); | 
|  1007          PlatformThread::Sleep(rand() % 20); |  1005          PlatformThread::Sleep(rand() % 20); | 
|  1008          e.Put(IS_UNSYNCED, true); |  1006          e.Put(IS_UNSYNCED, true); | 
|  1009          if (e.Put(ID, TestIdFactory::FromNumber(rand())) && |  1007          if (e.Put(ID, TestIdFactory::FromNumber(rand())) && | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1064     PathString b(1, tests[i].b); |  1062     PathString b(1, tests[i].b); | 
|  1065     const int result = ComparePathNames(a, b); |  1063     const int result = ComparePathNames(a, b); | 
|  1066     if (result != tests[i].expected_result) { |  1064     if (result != tests[i].expected_result) { | 
|  1067       ADD_FAILURE() << "ComparePathNames(" << tests[i].a << ", " << tests[i].b |  1065       ADD_FAILURE() << "ComparePathNames(" << tests[i].a << ", " << tests[i].b | 
|  1068        << ") returned " << result << "; expected " |  1066        << ") returned " << result << "; expected " | 
|  1069        << tests[i].expected_result; |  1067        << tests[i].expected_result; | 
|  1070     } |  1068     } | 
|  1071   } |  1069   } | 
|  1072 } |  1070 } | 
|  1073  |  1071  | 
|  1074 #if defined(OS_WIN) |  | 
|  1075 TEST(Syncable, PathNameMatch) { |  | 
|  1076   // basic stuff, not too many otherwise we're testing the os. |  | 
|  1077   EXPECT_TRUE(PathNameMatch(PSTR("bob"), PSTR("bob"))); |  | 
|  1078   EXPECT_FALSE(PathNameMatch(PSTR("bob"), PSTR("fred"))); |  | 
|  1079   // Test our ; extension. |  | 
|  1080   EXPECT_TRUE(PathNameMatch(PSTR("bo;b"), PSTR("bo;b"))); |  | 
|  1081   EXPECT_TRUE(PathNameMatch(PSTR("bo;b"), PSTR("bo*"))); |  | 
|  1082   EXPECT_FALSE(PathNameMatch(PSTR("bo;b"), PSTR("co;b"))); |  | 
|  1083   EXPECT_FALSE(PathNameMatch(PSTR("bo;b"), PSTR("co*"))); |  | 
|  1084   // Test our fixes for prepended spaces. |  | 
|  1085   EXPECT_TRUE(PathNameMatch(PSTR("  bob"), PSTR("  bo*"))); |  | 
|  1086   EXPECT_TRUE(PathNameMatch(PSTR("  bob"), PSTR("  bob"))); |  | 
|  1087   EXPECT_FALSE(PathNameMatch(PSTR("bob"), PSTR("  bob"))); |  | 
|  1088   EXPECT_FALSE(PathNameMatch(PSTR("  bob"), PSTR("bob"))); |  | 
|  1089   // Combo test. |  | 
|  1090   EXPECT_TRUE(PathNameMatch(PSTR("  b;ob"), PSTR("  b;o*"))); |  | 
|  1091   EXPECT_TRUE(PathNameMatch(PSTR("  b;ob"), PSTR("  b;ob"))); |  | 
|  1092   EXPECT_FALSE(PathNameMatch(PSTR("b;ob"), PSTR("  b;ob"))); |  | 
|  1093   EXPECT_FALSE(PathNameMatch(PSTR("  b;ob"), PSTR("b;ob"))); |  | 
|  1094   // other whitespace should give no matches. |  | 
|  1095   EXPECT_FALSE(PathNameMatch(PSTR("bob"), PSTR("\tbob"))); |  | 
|  1096 } |  | 
|  1097 #endif  // defined(OS_WIN) |  | 
|  1098  |  | 
|  1099 void FakeSync(MutableEntry* e, const char* fake_id) { |  1072 void FakeSync(MutableEntry* e, const char* fake_id) { | 
|  1100   e->Put(IS_UNSYNCED, false); |  1073   e->Put(IS_UNSYNCED, false); | 
|  1101   e->Put(BASE_VERSION, 2); |  1074   e->Put(BASE_VERSION, 2); | 
|  1102   e->Put(ID, Id::CreateFromServerId(fake_id)); |  1075   e->Put(ID, Id::CreateFromServerId(fake_id)); | 
|  1103 } |  1076 } | 
|  1104  |  1077  | 
|  1105 TEST_F(SyncableDirectoryTest, Bug1509232) { |  1078 TEST_F(SyncableDirectoryTest, Bug1509232) { | 
|  1106   const PathString a = PSTR("alpha"); |  1079   const PathString a = PSTR("alpha"); | 
|  1107  |  1080   const Id entry_id = dir_.get()->NextId(); | 
|  1108   CreateEntry(a, dir_.get()->NextId()); |  1081   CreateEntry(a, entry_id); | 
|  1109   { |  1082   { | 
|  1110     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); |  1083     WriteTransaction trans(dir_.get(), UNITTEST, __FILE__, __LINE__); | 
|  1111     MutableEntry e(&trans, GET_BY_PATH, a); |  1084     MutableEntry e(&trans, GET_BY_ID, entry_id); | 
|  1112     ASSERT_TRUE(e.good()); |  1085     ASSERT_TRUE(e.good()); | 
|  1113     ExtendedAttributeKey key(e.Get(META_HANDLE), PSTR("resourcefork")); |  1086     ExtendedAttributeKey key(e.Get(META_HANDLE), PSTR("resourcefork")); | 
|  1114     MutableExtendedAttribute ext(&trans, CREATE, key); |  1087     MutableExtendedAttribute ext(&trans, CREATE, key); | 
|  1115     ASSERT_TRUE(ext.good()); |  1088     ASSERT_TRUE(ext.good()); | 
|  1116     const char value[] = "stuff"; |  1089     const char value[] = "stuff"; | 
|  1117     Blob value_blob(value, value + arraysize(value)); |  1090     Blob value_blob(value, value + arraysize(value)); | 
|  1118     ext.mutable_value()->swap(value_blob); |  1091     ext.mutable_value()->swap(value_blob); | 
|  1119     ext.delete_attribute(); |  1092     ext.delete_attribute(); | 
|  1120   } |  1093   } | 
|  1121   // This call to SaveChanges used to CHECK fail. |  1094   // This call to SaveChanges used to CHECK fail. | 
|  1122   dir_.get()->SaveChanges(); |  1095   dir_.get()->SaveChanges(); | 
|  1123 } |  1096 } | 
|  1124  |  1097  | 
|  1125 }  // namespace |  1098 }  // namespace | 
|  1126 }  // namespace syncable |  1099 }  // namespace syncable | 
| OLD | NEW |