1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <sstream> 6 #include <string> 7 #include <vector> 8 9 #include "chrome/browser/sync_file_system/drive_backend/remote_sync_operation_resolver.h" 10 #include "chrome/browser/sync_file_system/file_change.h" 11 #include "chrome/browser/sync_file_system/sync_file_type.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace sync_file_system { 15 16 namespace { 17 18 struct Input { 19 SyncFileType local_file_type; 20 FileChangeList local_changes; 21 22 std::string DebugString() { 23 std::ostringstream ss; 24 ss << "LocalFileType: " << local_file_type 25 << ", LocalChanges: " << local_changes.DebugString(); 26 return ss.str(); 27 } 28 }; 29 30 template <typename type, size_t array_size> 31 std::vector<type> CreateList(const type (&inputs)[array_size]) { 32 return std::vector<type>(inputs, inputs + array_size); 33 } 34 35 FileChangeList CreateEmptyChange() { 36 return FileChangeList(); 37 } 38 39 FileChangeList CreateAddOrUpdateFileChange() { 40 FileChangeList list; 41 list.Update(FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 42 SYNC_FILE_TYPE_FILE)); 43 return list; 44 } 45 46 FileChangeList CreateAddDirectoryChange() { 47 FileChangeList list; 48 list.Update(FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 49 SYNC_FILE_TYPE_DIRECTORY)); 50 return list; 51 } 52 53 FileChangeList CreateDeleteFileChange() { 54 FileChangeList list; 55 list.Update(FileChange(FileChange::FILE_CHANGE_DELETE, 56 SYNC_FILE_TYPE_FILE)); 57 return list; 58 } 59 60 FileChangeList CreateDeleteDirectoryChange() { 61 FileChangeList list; 62 list.Update(FileChange(FileChange::FILE_CHANGE_DELETE, 63 SYNC_FILE_TYPE_DIRECTORY)); 64 return list; 65 } 66 67 std::vector<Input> CreateInput() { 68 const Input inputs[] = { 69 { SYNC_FILE_TYPE_UNKNOWN, CreateEmptyChange() }, 70 { SYNC_FILE_TYPE_UNKNOWN, CreateAddOrUpdateFileChange() }, 71 { SYNC_FILE_TYPE_UNKNOWN, CreateAddDirectoryChange() }, 72 { SYNC_FILE_TYPE_UNKNOWN, CreateDeleteFileChange() }, 73 { SYNC_FILE_TYPE_UNKNOWN, CreateDeleteDirectoryChange() }, 74 75 { SYNC_FILE_TYPE_FILE, CreateEmptyChange() }, 76 { SYNC_FILE_TYPE_FILE, CreateAddOrUpdateFileChange() }, 77 { SYNC_FILE_TYPE_FILE, CreateAddDirectoryChange() }, 78 { SYNC_FILE_TYPE_FILE, CreateDeleteFileChange() }, 79 { SYNC_FILE_TYPE_FILE, CreateDeleteDirectoryChange() }, 80 81 { SYNC_FILE_TYPE_DIRECTORY, CreateEmptyChange() }, 82 { SYNC_FILE_TYPE_DIRECTORY, CreateAddOrUpdateFileChange() }, 83 { SYNC_FILE_TYPE_DIRECTORY, CreateAddDirectoryChange() }, 84 { SYNC_FILE_TYPE_DIRECTORY, CreateDeleteFileChange() }, 85 { SYNC_FILE_TYPE_DIRECTORY, CreateDeleteDirectoryChange() }, 86 }; 87 return CreateList(inputs); 88 } 89 90 } // namespace 91 92 class RemoteSyncOperationResolverTest : public testing::Test { 93 public: 94 RemoteSyncOperationResolverTest() {} 95 96 protected: 97 typedef RemoteSyncOperationResolver Resolver; 98 typedef std::vector<SyncOperationType> ExpectedTypes; 99 100 private: 101 DISALLOW_COPY_AND_ASSIGN(RemoteSyncOperationResolverTest); 102 }; 103 104 TEST_F(RemoteSyncOperationResolverTest, ResolveForAddOrUpdateFile) { 105 const SyncOperationType kExpectedTypes[] = { 106 SYNC_OPERATION_ADD_FILE, 107 SYNC_OPERATION_FAIL, 108 SYNC_OPERATION_FAIL, 109 SYNC_OPERATION_ADD_FILE, 110 SYNC_OPERATION_ADD_FILE, 111 112 SYNC_OPERATION_UPDATE_FILE, 113 SYNC_OPERATION_CONFLICT, 114 SYNC_OPERATION_FAIL, 115 SYNC_OPERATION_FAIL, 116 SYNC_OPERATION_FAIL, 117 118 SYNC_OPERATION_RESOLVE_TO_LOCAL, 119 SYNC_OPERATION_FAIL, 120 SYNC_OPERATION_RESOLVE_TO_LOCAL, 121 SYNC_OPERATION_FAIL, 122 SYNC_OPERATION_FAIL, 123 }; 124 125 ExpectedTypes expected_types = CreateList(kExpectedTypes); 126 std::vector<Input> inputs = CreateInput(); 127 128 ASSERT_EQ(expected_types.size(), inputs.size()); 129 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 130 EXPECT_EQ(expected_types[i], 131 Resolver::ResolveForAddOrUpdateFile( 132 inputs[i].local_changes, inputs[i].local_file_type)) 133 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 134 } 135 136 TEST_F(RemoteSyncOperationResolverTest, ResolveForAddOrUpdateFileInConflict) { 137 const SyncOperationType kExpectedTypes[] = { 138 SYNC_OPERATION_FAIL, 139 SYNC_OPERATION_FAIL, 140 SYNC_OPERATION_FAIL, 141 SYNC_OPERATION_RESOLVE_TO_REMOTE, 142 SYNC_OPERATION_RESOLVE_TO_REMOTE, 143 144 SYNC_OPERATION_CONFLICT, 145 SYNC_OPERATION_CONFLICT, 146 SYNC_OPERATION_FAIL, 147 SYNC_OPERATION_FAIL, 148 SYNC_OPERATION_FAIL, 149 150 SYNC_OPERATION_FAIL, 151 SYNC_OPERATION_FAIL, 152 SYNC_OPERATION_RESOLVE_TO_LOCAL, 153 SYNC_OPERATION_FAIL, 154 SYNC_OPERATION_FAIL, 155 }; 156 157 ExpectedTypes expected_types = CreateList(kExpectedTypes); 158 std::vector<Input> inputs = CreateInput(); 159 160 ASSERT_EQ(expected_types.size(), inputs.size()); 161 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 162 EXPECT_EQ(expected_types[i], 163 Resolver::ResolveForAddOrUpdateFileInConflict( 164 inputs[i].local_changes, inputs[i].local_file_type)) 165 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 166 } 167 168 TEST_F(RemoteSyncOperationResolverTest, ResolveForAddDirectory) { 169 const SyncOperationType kExpectedTypes[] = { 170 SYNC_OPERATION_ADD_DIRECTORY, 171 SYNC_OPERATION_FAIL, 172 SYNC_OPERATION_FAIL, 173 SYNC_OPERATION_RESOLVE_TO_REMOTE, 174 SYNC_OPERATION_RESOLVE_TO_REMOTE, 175 176 SYNC_OPERATION_RESOLVE_TO_REMOTE, 177 SYNC_OPERATION_RESOLVE_TO_REMOTE, 178 SYNC_OPERATION_FAIL, 179 SYNC_OPERATION_FAIL, 180 SYNC_OPERATION_FAIL, 181 182 SYNC_OPERATION_NONE, 183 SYNC_OPERATION_FAIL, 184 SYNC_OPERATION_NONE, 185 SYNC_OPERATION_FAIL, 186 SYNC_OPERATION_FAIL, 187 }; 188 189 ExpectedTypes expected_types = CreateList(kExpectedTypes); 190 std::vector<Input> inputs = CreateInput(); 191 192 ASSERT_EQ(expected_types.size(), inputs.size()); 193 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 194 EXPECT_EQ(expected_types[i], 195 Resolver::ResolveForAddDirectory( 196 inputs[i].local_changes, inputs[i].local_file_type)) 197 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 198 } 199 200 TEST_F(RemoteSyncOperationResolverTest, ResolveForAddDirectoryInConflict) { 201 const SyncOperationType kExpectedTypes[] = { 202 SYNC_OPERATION_FAIL, 203 SYNC_OPERATION_FAIL, 204 SYNC_OPERATION_FAIL, 205 SYNC_OPERATION_RESOLVE_TO_REMOTE, 206 SYNC_OPERATION_RESOLVE_TO_REMOTE, 207 208 SYNC_OPERATION_RESOLVE_TO_REMOTE, 209 SYNC_OPERATION_RESOLVE_TO_REMOTE, 210 SYNC_OPERATION_FAIL, 211 SYNC_OPERATION_FAIL, 212 SYNC_OPERATION_FAIL, 213 214 SYNC_OPERATION_FAIL, 215 SYNC_OPERATION_FAIL, 216 SYNC_OPERATION_RESOLVE_TO_LOCAL, 217 SYNC_OPERATION_FAIL, 218 SYNC_OPERATION_FAIL, 219 }; 220 221 ExpectedTypes expected_types = CreateList(kExpectedTypes); 222 std::vector<Input> inputs = CreateInput(); 223 224 ASSERT_EQ(expected_types.size(), inputs.size()); 225 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 226 EXPECT_EQ(expected_types[i], 227 Resolver::ResolveForAddDirectoryInConflict( 228 inputs[i].local_changes, inputs[i].local_file_type)) 229 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 230 } 231 232 TEST_F(RemoteSyncOperationResolverTest, ResolveForDeleteFile) { 233 const SyncOperationType kExpectedTypes[] = { 234 SYNC_OPERATION_DELETE_METADATA, 235 SYNC_OPERATION_FAIL, 236 SYNC_OPERATION_FAIL, 237 SYNC_OPERATION_DELETE_METADATA, 238 SYNC_OPERATION_DELETE_METADATA, 239 240 SYNC_OPERATION_DELETE, 241 SYNC_OPERATION_NONE, 242 SYNC_OPERATION_FAIL, 243 SYNC_OPERATION_FAIL, 244 SYNC_OPERATION_FAIL, 245 246 SYNC_OPERATION_NONE, 247 SYNC_OPERATION_FAIL, 248 SYNC_OPERATION_NONE, 249 SYNC_OPERATION_FAIL, 250 SYNC_OPERATION_FAIL, 251 }; 252 253 ExpectedTypes expected_types = CreateList(kExpectedTypes); 254 std::vector<Input> inputs = CreateInput(); 255 256 ASSERT_EQ(expected_types.size(), inputs.size()); 257 for (ExpectedTypes::size_type i = 0; i < inputs.size(); ++i) 258 EXPECT_EQ(expected_types[i], 259 Resolver::ResolveForDeleteFile( 260 inputs[i].local_changes, inputs[i].local_file_type)) 261 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 262 } 263 264 TEST_F(RemoteSyncOperationResolverTest, ResolveForDeleteFileInConflict) { 265 const SyncOperationType kExpectedTypes[] = { 266 SYNC_OPERATION_FAIL, 267 SYNC_OPERATION_FAIL, 268 SYNC_OPERATION_FAIL, 269 SYNC_OPERATION_DELETE_METADATA, 270 SYNC_OPERATION_DELETE_METADATA, 271 272 SYNC_OPERATION_RESOLVE_TO_LOCAL, 273 SYNC_OPERATION_RESOLVE_TO_LOCAL, 274 SYNC_OPERATION_FAIL, 275 SYNC_OPERATION_FAIL, 276 SYNC_OPERATION_FAIL, 277 278 SYNC_OPERATION_FAIL, 279 SYNC_OPERATION_FAIL, 280 SYNC_OPERATION_RESOLVE_TO_LOCAL, 281 SYNC_OPERATION_FAIL, 282 SYNC_OPERATION_FAIL, 283 }; 284 285 ExpectedTypes expected_types = CreateList(kExpectedTypes); 286 std::vector<Input> inputs = CreateInput(); 287 288 ASSERT_EQ(expected_types.size(), inputs.size()); 289 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 290 EXPECT_EQ(expected_types[i], 291 Resolver::ResolveForDeleteFileInConflict( 292 inputs[i].local_changes, inputs[i].local_file_type)) 293 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 294 } 295 296 TEST_F(RemoteSyncOperationResolverTest, ResolveForDeleteDirectory) { 297 const SyncOperationType kExpectedTypes[] = { 298 SYNC_OPERATION_NONE, 299 SYNC_OPERATION_FAIL, 300 SYNC_OPERATION_FAIL, 301 SYNC_OPERATION_NONE, 302 SYNC_OPERATION_NONE, 303 304 SYNC_OPERATION_RESOLVE_TO_LOCAL, 305 SYNC_OPERATION_RESOLVE_TO_LOCAL, 306 SYNC_OPERATION_FAIL, 307 SYNC_OPERATION_FAIL, 308 SYNC_OPERATION_FAIL, 309 310 SYNC_OPERATION_DELETE, 311 SYNC_OPERATION_FAIL, 312 SYNC_OPERATION_RESOLVE_TO_LOCAL, 313 SYNC_OPERATION_FAIL, 314 SYNC_OPERATION_FAIL, 315 }; 316 317 ExpectedTypes expected_types = CreateList(kExpectedTypes); 318 std::vector<Input> inputs = CreateInput(); 319 320 ASSERT_EQ(expected_types.size(), inputs.size()); 321 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 322 EXPECT_EQ(expected_types[i], 323 Resolver::ResolveForDeleteDirectory( 324 inputs[i].local_changes, inputs[i].local_file_type)) 325 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 326 } 327 328 TEST_F(RemoteSyncOperationResolverTest, ResolveForDeleteDirectoryInConflict) { 329 const SyncOperationType kExpectedTypes[] = { 330 SYNC_OPERATION_FAIL, 331 SYNC_OPERATION_FAIL, 332 SYNC_OPERATION_FAIL, 333 SYNC_OPERATION_DELETE_METADATA, 334 SYNC_OPERATION_DELETE_METADATA, 335 336 SYNC_OPERATION_RESOLVE_TO_LOCAL, 337 SYNC_OPERATION_RESOLVE_TO_LOCAL, 338 SYNC_OPERATION_FAIL, 339 SYNC_OPERATION_FAIL, 340 SYNC_OPERATION_FAIL, 341 342 SYNC_OPERATION_FAIL, 343 SYNC_OPERATION_FAIL, 344 SYNC_OPERATION_RESOLVE_TO_LOCAL, 345 SYNC_OPERATION_FAIL, 346 SYNC_OPERATION_FAIL, 347 }; 348 349 ExpectedTypes expected_types = CreateList(kExpectedTypes); 350 std::vector<Input> inputs = CreateInput(); 351 352 ASSERT_EQ(expected_types.size(), inputs.size()); 353 for (ExpectedTypes::size_type i = 0; i < expected_types.size(); ++i) 354 EXPECT_EQ(expected_types[i], 355 Resolver::ResolveForDeleteDirectoryInConflict( 356 inputs[i].local_changes, inputs[i].local_file_type)) 357 << "Case " << i << ": (" << inputs[i].DebugString() << ")"; 358 } 359 360 } // namespace sync_file_system 361