Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // MediaDeviceNotificationsLinux unit tests. | 5 // MediaDeviceNotificationsLinux unit tests. |
| 6 | 6 |
| 7 #include "chrome/browser/media_gallery/media_device_notifications_linux.h" | 7 #include "chrome/browser/media_gallery/media_device_notifications_linux.h" |
| 8 | 8 |
| 9 #include <mntent.h> | 9 #include <mntent.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 const char kValidFS[] = "vfat"; | 31 const char kValidFS[] = "vfat"; |
| 32 const char kInvalidFS[] = "invalidfs"; | 32 const char kInvalidFS[] = "invalidfs"; |
| 33 | 33 |
| 34 const char kInvalidPath[] = "invalid path does not exist"; | 34 const char kInvalidPath[] = "invalid path does not exist"; |
| 35 | 35 |
| 36 const char kDevice1[] = "d1"; | 36 const char kDevice1[] = "d1"; |
| 37 const char kDevice2[] = "d2"; | 37 const char kDevice2[] = "d2"; |
| 38 const char kDevice3[] = "d3"; | 38 const char kDevice3[] = "d3"; |
| 39 | 39 |
| 40 const char kDeviceId1[] = "FFF0-000F"; | |
| 41 const char kDeviceId2[] = "FFF0-00F0"; | |
| 42 const char kDeviceId3[] = "FFF0-0F00"; | |
| 43 | |
| 44 const char kDeviceLabel1[] = "TEST_USB_MODEL_1"; | |
| 45 const char kDeviceLabel2[] = "TEST_USB_MODEL_2"; | |
| 46 const char kDeviceLabel3[] = "TEST_USB_MODEL_3"; | |
| 47 | |
| 40 const char kMountPointA[] = "mnt_a"; | 48 const char kMountPointA[] = "mnt_a"; |
| 41 const char kMountPointB[] = "mnt_b"; | 49 const char kMountPointB[] = "mnt_b"; |
| 42 | 50 |
| 43 class MediaDeviceNotificationsLinuxTestWrapper | 51 class MediaDeviceNotificationsLinuxTestWrapper |
| 44 : public MediaDeviceNotificationsLinux { | 52 : public MediaDeviceNotificationsLinux { |
| 45 public: | 53 public: |
| 46 MediaDeviceNotificationsLinuxTestWrapper(const FilePath& path, | 54 MediaDeviceNotificationsLinuxTestWrapper(const FilePath& path, |
| 47 MessageLoop* message_loop) | 55 MessageLoop* message_loop) |
| 48 : MediaDeviceNotificationsLinux(path), | 56 : MediaDeviceNotificationsLinux(path), |
| 49 message_loop_(message_loop) { | 57 message_loop_(message_loop) { |
| 58 PopulateMountDeviceInfoMap(); | |
| 50 } | 59 } |
| 51 | 60 |
| 52 private: | 61 private: |
| 62 // Device unique id and label information. | |
| 63 typedef std::pair<std::string, string16> DeviceInfo; | |
| 64 | |
| 65 // (Mount device, DeviceInfo) | |
| 66 typedef std::map<std::string, DeviceInfo> MountDeviceInfoMap; | |
| 67 | |
| 53 // Avoids code deleting the object while there are references to it. | 68 // Avoids code deleting the object while there are references to it. |
| 54 // Aside from the base::RefCountedThreadSafe friend class, any attempts to | 69 // Aside from the base::RefCountedThreadSafe friend class, any attempts to |
| 55 // call this dtor will result in a compile-time error. | 70 // call this dtor will result in a compile-time error. |
| 56 ~MediaDeviceNotificationsLinuxTestWrapper() {} | 71 ~MediaDeviceNotificationsLinuxTestWrapper() {} |
| 57 | 72 |
| 58 virtual void OnFilePathChanged(const FilePath& path, bool error) OVERRIDE { | 73 virtual void OnFilePathChanged(const FilePath& path, bool error) OVERRIDE { |
| 59 MediaDeviceNotificationsLinux::OnFilePathChanged(path, error); | 74 MediaDeviceNotificationsLinux::OnFilePathChanged(path, error); |
| 60 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 75 message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| 61 } | 76 } |
| 62 | 77 |
| 78 virtual bool GetDeviceInfo(const std::string& dev_path, | |
| 79 std::string* id, | |
| 80 string16* name) OVERRIDE { | |
| 81 MountDeviceInfoMap::const_iterator it = device_info_map_.find(dev_path); | |
| 82 if (it == device_info_map_.end()) | |
| 83 return false; | |
| 84 | |
| 85 id->assign(it->second.first); | |
| 86 *name = it->second.second; | |
| 87 return true; | |
| 88 } | |
| 89 | |
| 90 // Helper function to populate test device information. | |
| 91 void PopulateMountDeviceInfoMap() { | |
| 92 device_info_map_.insert( | |
| 93 std::make_pair(kDevice1, | |
| 94 std::make_pair(kDeviceId1, | |
| 95 UTF8ToUTF16(kDeviceLabel1)))); | |
| 96 device_info_map_.insert( | |
| 97 std::make_pair(kDevice2, | |
| 98 std::make_pair(kDeviceId2, | |
| 99 UTF8ToUTF16(kDeviceLabel2)))); | |
| 100 device_info_map_.insert( | |
| 101 std::make_pair(kDevice3, | |
| 102 std::make_pair(kDeviceId3, | |
| 103 UTF8ToUTF16(kDeviceLabel3)))); | |
| 104 } | |
| 105 | |
| 63 MessageLoop* message_loop_; | 106 MessageLoop* message_loop_; |
| 107 MountDeviceInfoMap device_info_map_; | |
| 64 | 108 |
| 65 DISALLOW_COPY_AND_ASSIGN(MediaDeviceNotificationsLinuxTestWrapper); | 109 DISALLOW_COPY_AND_ASSIGN(MediaDeviceNotificationsLinuxTestWrapper); |
| 66 }; | 110 }; |
| 67 | 111 |
| 68 class MediaDeviceNotificationsLinuxTest : public testing::Test { | 112 class MediaDeviceNotificationsLinuxTest : public testing::Test { |
| 69 public: | 113 public: |
| 70 struct MtabTestData { | 114 struct MtabTestData { |
| 71 MtabTestData(const std::string& mount_device, | 115 MtabTestData(const std::string& mount_device, |
| 72 const std::string& mount_point, | 116 const std::string& mount_point, |
| 73 const std::string& mount_type) | 117 const std::string& mount_type) |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 | 273 |
| 230 // Simple test case where we attach and detach a media device. | 274 // Simple test case where we attach and detach a media device. |
| 231 TEST_F(MediaDeviceNotificationsLinuxTest, BasicAttachDetach) { | 275 TEST_F(MediaDeviceNotificationsLinuxTest, BasicAttachDetach) { |
| 232 testing::Sequence mock_sequence; | 276 testing::Sequence mock_sequence; |
| 233 FilePath test_path = CreateMountPointWithDCIMDir(kMountPointA); | 277 FilePath test_path = CreateMountPointWithDCIMDir(kMountPointA); |
| 234 ASSERT_FALSE(test_path.empty()); | 278 ASSERT_FALSE(test_path.empty()); |
| 235 MtabTestData test_data[] = { | 279 MtabTestData test_data[] = { |
| 236 MtabTestData(kDevice1, kInvalidPath, kValidFS), | 280 MtabTestData(kDevice1, kInvalidPath, kValidFS), |
| 237 MtabTestData(kDevice2, test_path.value(), kValidFS), | 281 MtabTestData(kDevice2, test_path.value(), kValidFS), |
| 238 }; | 282 }; |
| 239 const std::string kDeviceId = "0"; | |
| 240 // Only |kDevice2| should be attached, since |kDevice1| has a bad path. | 283 // Only |kDevice2| should be attached, since |kDevice1| has a bad path. |
| 241 EXPECT_CALL(observer(), | 284 EXPECT_CALL(observer(), |
| 242 OnMediaDeviceAttached(kDeviceId, | 285 OnMediaDeviceAttached(kDeviceId2, |
| 243 ASCIIToUTF16(kDevice2), | 286 UTF8ToUTF16(kDeviceLabel2), |
|
Lei Zhang
2012/08/09 03:47:16
What I mean is, you can still use ASCIIToUTF16().
kmadhusu
2012/08/09 08:10:03
Done.
| |
| 244 base::SystemMonitor::TYPE_PATH, | 287 base::SystemMonitor::TYPE_PATH, |
| 245 test_path.value())) | 288 test_path.value())) |
| 246 .InSequence(mock_sequence); | 289 .InSequence(mock_sequence); |
| 247 AppendToMtabAndRunLoop(test_data, arraysize(test_data)); | 290 AppendToMtabAndRunLoop(test_data, arraysize(test_data)); |
| 248 | 291 |
| 249 // |kDevice2| should be detached here. | 292 // |kDevice2| should be detached here. |
| 250 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId)) | 293 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId2)) |
| 251 .InSequence(mock_sequence); | 294 .InSequence(mock_sequence); |
| 252 WriteEmptyMtabAndRunLoop(); | 295 WriteEmptyMtabAndRunLoop(); |
| 253 } | 296 } |
| 254 | 297 |
| 255 // Only mount points with DCIM directories are recognized. | 298 // Only mount points with DCIM directories are recognized. |
| 256 TEST_F(MediaDeviceNotificationsLinuxTest, DCIM) { | 299 TEST_F(MediaDeviceNotificationsLinuxTest, DCIM) { |
| 257 testing::Sequence mock_sequence; | 300 testing::Sequence mock_sequence; |
| 258 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); | 301 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); |
| 259 ASSERT_FALSE(test_path_a.empty()); | 302 ASSERT_FALSE(test_path_a.empty()); |
| 260 MtabTestData test_data1[] = { | 303 MtabTestData test_data1[] = { |
| 261 MtabTestData(kDevice1, test_path_a.value(), kValidFS), | 304 MtabTestData(kDevice1, test_path_a.value(), kValidFS), |
| 262 }; | 305 }; |
| 263 const std::string kDeviceId = "0"; | |
| 264 // |kDevice1| should be attached as expected. | 306 // |kDevice1| should be attached as expected. |
| 265 EXPECT_CALL(observer(), | 307 EXPECT_CALL(observer(), |
| 266 OnMediaDeviceAttached(kDeviceId, | 308 OnMediaDeviceAttached(kDeviceId1, |
| 267 ASCIIToUTF16(kDevice1), | 309 UTF8ToUTF16(kDeviceLabel1), |
| 268 base::SystemMonitor::TYPE_PATH, | 310 base::SystemMonitor::TYPE_PATH, |
| 269 test_path_a.value())) | 311 test_path_a.value())) |
| 270 .InSequence(mock_sequence); | 312 .InSequence(mock_sequence); |
| 271 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1)); | 313 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1)); |
| 272 | 314 |
| 273 // This should do nothing, since |kMountPointB| does not have a DCIM dir. | 315 // This should do nothing, since |kMountPointB| does not have a DCIM dir. |
| 274 FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB); | 316 FilePath test_path_b = CreateMountPointWithoutDCIMDir(kMountPointB); |
| 275 ASSERT_FALSE(test_path_b.empty()); | 317 ASSERT_FALSE(test_path_b.empty()); |
| 276 MtabTestData test_data2[] = { | 318 MtabTestData test_data2[] = { |
| 277 MtabTestData(kDevice2, test_path_b.value(), kValidFS), | 319 MtabTestData(kDevice2, test_path_b.value(), kValidFS), |
| 278 }; | 320 }; |
| 279 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2)); | 321 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2)); |
| 280 | 322 |
| 281 // |kDevice1| should be detached as expected. | 323 // |kDevice1| should be detached as expected. |
| 282 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId)) | 324 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId1)) |
| 283 .InSequence(mock_sequence); | 325 .InSequence(mock_sequence); |
| 284 WriteEmptyMtabAndRunLoop(); | 326 WriteEmptyMtabAndRunLoop(); |
| 285 } | 327 } |
| 286 | 328 |
| 287 // More complicated test case with multiple devices on multiple mount points. | 329 // More complicated test case with multiple devices on multiple mount points. |
| 330 TEST_F(MediaDeviceNotificationsLinuxTest, SwapMountPoints) { | |
| 331 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); | |
| 332 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB); | |
| 333 ASSERT_FALSE(test_path_a.empty()); | |
| 334 ASSERT_FALSE(test_path_b.empty()); | |
| 335 | |
| 336 // Attach two devices. | |
| 337 // kDevice1 -> kMountPointA | |
| 338 // kDevice2 -> kMountPointB | |
| 339 MtabTestData test_data1[] = { | |
| 340 MtabTestData(kDevice1, test_path_a.value(), kValidFS), | |
| 341 MtabTestData(kDevice2, test_path_b.value(), kValidFS), | |
| 342 }; | |
| 343 EXPECT_CALL(observer(), OnMediaDeviceAttached(_, _, _, _)).Times(2); | |
| 344 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(0); | |
| 345 AppendToMtabAndRunLoop(test_data1, arraysize(test_data1)); | |
| 346 | |
| 347 // Detach two devices from old mount points and attach the devices at new | |
| 348 // mount points. | |
| 349 // kDevice1 -> kMountPointB | |
| 350 // kDevice2 -> kMountPointA | |
| 351 MtabTestData test_data2[] = { | |
| 352 MtabTestData(kDevice1, test_path_b.value(), kValidFS), | |
| 353 MtabTestData(kDevice2, test_path_a.value(), kValidFS), | |
| 354 }; | |
| 355 EXPECT_CALL(observer(), OnMediaDeviceAttached(_, _, _, _)).Times(2); | |
| 356 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(2); | |
| 357 OverwriteMtabAndRunLoop(test_data2, arraysize(test_data2)); | |
| 358 | |
| 359 // Detach all devices. | |
| 360 EXPECT_CALL(observer(), OnMediaDeviceAttached(_, _, _, _)).Times(0); | |
| 361 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(2); | |
| 362 WriteEmptyMtabAndRunLoop(); | |
| 363 } | |
| 364 | |
| 365 // More complicated test case with multiple devices on multiple mount points. | |
| 288 TEST_F(MediaDeviceNotificationsLinuxTest, MultiDevicesMultiMountPoints) { | 366 TEST_F(MediaDeviceNotificationsLinuxTest, MultiDevicesMultiMountPoints) { |
| 289 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); | 367 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); |
| 290 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB); | 368 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB); |
| 291 ASSERT_FALSE(test_path_a.empty()); | 369 ASSERT_FALSE(test_path_a.empty()); |
| 292 ASSERT_FALSE(test_path_b.empty()); | 370 ASSERT_FALSE(test_path_b.empty()); |
| 293 | 371 |
| 294 // Attach two devices. | 372 // Attach two devices. |
| 295 // kDevice1 -> kMountPointA | 373 // kDevice1 -> kMountPointA |
| 296 // kDevice2 -> kMountPointB | 374 // kDevice2 -> kMountPointB |
| 297 MtabTestData test_data1[] = { | 375 MtabTestData test_data1[] = { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(2); | 430 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(2); |
| 353 WriteEmptyMtabAndRunLoop(); | 431 WriteEmptyMtabAndRunLoop(); |
| 354 } | 432 } |
| 355 | 433 |
| 356 // More complicated test case with multiple devices on one mount point. | 434 // More complicated test case with multiple devices on one mount point. |
| 357 TEST_F(MediaDeviceNotificationsLinuxTest, MultiDevicesOneMountPoint) { | 435 TEST_F(MediaDeviceNotificationsLinuxTest, MultiDevicesOneMountPoint) { |
| 358 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); | 436 FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA); |
| 359 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB); | 437 FilePath test_path_b = CreateMountPointWithDCIMDir(kMountPointB); |
| 360 ASSERT_FALSE(test_path_a.empty()); | 438 ASSERT_FALSE(test_path_a.empty()); |
| 361 ASSERT_FALSE(test_path_b.empty()); | 439 ASSERT_FALSE(test_path_b.empty()); |
| 362 const std::string kDeviceId0 = "0"; | |
| 363 const std::string kDeviceId1 = "1"; | |
| 364 | 440 |
| 365 // |kDevice1| is most recently mounted at |kMountPointB|. | 441 // |kDevice1| is most recently mounted at |kMountPointB|. |
| 366 // kDevice1 -> kMountPointA | 442 // kDevice1 -> kMountPointA |
| 367 // kDevice2 -> kMountPointB | 443 // kDevice2 -> kMountPointB |
| 368 // kDevice1 -> kMountPointB | 444 // kDevice1 -> kMountPointB |
| 369 MtabTestData test_data1[] = { | 445 MtabTestData test_data1[] = { |
| 370 MtabTestData(kDevice1, test_path_a.value(), kValidFS), | 446 MtabTestData(kDevice1, test_path_a.value(), kValidFS), |
| 371 MtabTestData(kDevice2, test_path_b.value(), kValidFS), | 447 MtabTestData(kDevice2, test_path_b.value(), kValidFS), |
| 372 MtabTestData(kDevice1, test_path_b.value(), kValidFS), | 448 MtabTestData(kDevice1, test_path_b.value(), kValidFS), |
| 373 }; | 449 }; |
| 374 EXPECT_CALL(observer(), | 450 EXPECT_CALL(observer(), |
| 375 OnMediaDeviceAttached(kDeviceId0, | 451 OnMediaDeviceAttached(kDeviceId1, |
| 376 ASCIIToUTF16(kDevice1), | 452 UTF8ToUTF16(kDeviceLabel1), |
| 377 base::SystemMonitor::TYPE_PATH, | 453 base::SystemMonitor::TYPE_PATH, |
| 378 test_path_b.value())) | 454 test_path_b.value())) |
| 379 .Times(1); | 455 .Times(1); |
| 380 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(0); | 456 EXPECT_CALL(observer(), OnMediaDeviceDetached(_)).Times(0); |
| 381 OverwriteMtabAndRunLoop(test_data1, arraysize(test_data1)); | 457 OverwriteMtabAndRunLoop(test_data1, arraysize(test_data1)); |
| 382 | 458 |
| 383 // Attach |kDevice3| to |kMountPointB|. | 459 // Attach |kDevice3| to |kMountPointB|. |
| 384 // |kDevice1| is inaccessible at its most recent mount point, so it is | 460 // |kDevice1| is inaccessible at its most recent mount point, so it is |
| 385 // detached and unavailable, even though it is still accessible via | 461 // detached and unavailable, even though it is still accessible via |
| 386 // |kMountPointA|. | 462 // |kMountPointA|. |
| 387 // kDevice1 -> kMountPointA | 463 // kDevice1 -> kMountPointA |
| 388 // kDevice2 -> kMountPointB | 464 // kDevice2 -> kMountPointB |
| 389 // kDevice1 -> kMountPointB | 465 // kDevice1 -> kMountPointB |
| 390 // kDevice3 -> kMountPointB | 466 // kDevice3 -> kMountPointB |
| 391 MtabTestData test_data2[] = { | 467 MtabTestData test_data2[] = { |
| 392 MtabTestData(kDevice3, test_path_b.value(), kValidFS), | 468 MtabTestData(kDevice3, test_path_b.value(), kValidFS), |
| 393 }; | 469 }; |
| 394 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId0)).Times(1); | 470 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId1)).Times(1); |
| 395 EXPECT_CALL(observer(), | 471 EXPECT_CALL(observer(), |
| 396 OnMediaDeviceAttached(kDeviceId1, | 472 OnMediaDeviceAttached(kDeviceId3, |
| 397 ASCIIToUTF16(kDevice3), | 473 UTF8ToUTF16(kDeviceLabel3), |
| 398 base::SystemMonitor::TYPE_PATH, | 474 base::SystemMonitor::TYPE_PATH, |
| 399 test_path_b.value())) | 475 test_path_b.value())) |
| 400 .Times(1); | 476 .Times(1); |
| 401 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2)); | 477 AppendToMtabAndRunLoop(test_data2, arraysize(test_data2)); |
| 402 | 478 |
| 403 // Detach all devices. | 479 // Detach all devices. |
| 404 EXPECT_CALL(observer(), OnMediaDeviceAttached(_, _, _, _)).Times(0); | 480 EXPECT_CALL(observer(), OnMediaDeviceAttached(_, _, _, _)).Times(0); |
| 405 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId1)).Times(1); | 481 EXPECT_CALL(observer(), OnMediaDeviceDetached(kDeviceId3)).Times(1); |
| 406 WriteEmptyMtabAndRunLoop(); | 482 WriteEmptyMtabAndRunLoop(); |
| 407 } | 483 } |
| 408 | 484 |
| 409 } // namespace | 485 } // namespace |
| 410 | 486 |
| 411 } // namespace chrome | 487 } // namespace chrome |
| OLD | NEW |