1// Copyright 2014 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 "components/storage_monitor/storage_monitor_mac.h" 6 7#include "base/bind_helpers.h" 8#include "base/file_util.h" 9#include "base/files/scoped_temp_dir.h" 10#include "base/mac/foundation_util.h" 11#include "base/run_loop.h" 12#include "base/strings/sys_string_conversions.h" 13#include "base/strings/utf_string_conversions.h" 14#include "components/storage_monitor/mock_removable_storage_observer.h" 15#include "components/storage_monitor/removable_device_constants.h" 16#include "components/storage_monitor/storage_info.h" 17#include "components/storage_monitor/test_storage_monitor.h" 18#include "content/public/browser/browser_thread.h" 19#include "content/public/test/test_browser_thread_bundle.h" 20#include "testing/gtest/include/gtest/gtest.h" 21 22uint64 kTestSize = 1000000ULL; 23 24namespace storage_monitor { 25 26namespace { 27 28StorageInfo CreateStorageInfo( 29 const std::string& device_id, 30 const std::string& model_name, 31 const base::FilePath& mount_point, 32 uint64 size_bytes) { 33 return StorageInfo( 34 device_id, mount_point.value(), base::string16(), base::string16(), 35 base::UTF8ToUTF16(model_name), size_bytes); 36} 37 38} // namespace 39 40class StorageMonitorMacTest : public testing::Test { 41 public: 42 StorageMonitorMacTest() {} 43 44 virtual void SetUp() OVERRIDE { 45 monitor_.reset(new StorageMonitorMac); 46 47 mock_storage_observer_.reset(new MockRemovableStorageObserver); 48 monitor_->AddObserver(mock_storage_observer_.get()); 49 50 unique_id_ = "test_id"; 51 mount_point_ = base::FilePath("/unused_test_directory"); 52 device_id_ = StorageInfo::MakeDeviceId( 53 StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM, unique_id_); 54 disk_info_ = CreateStorageInfo(device_id_, "", 55 mount_point_, kTestSize); 56 } 57 58 void UpdateDisk(StorageInfo info, StorageMonitorMac::UpdateType update_type) { 59 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 60 base::Bind(&StorageMonitorMac::UpdateDisk, 61 base::Unretained(monitor_.get()), 62 "dummy_bsd_name", info, update_type)); 63 base::RunLoop().RunUntilIdle(); 64 } 65 66 protected: 67 content::TestBrowserThreadBundle thread_bundle_; 68 69 scoped_ptr<MockRemovableStorageObserver> mock_storage_observer_; 70 71 // Information about the disk. 72 std::string unique_id_; 73 base::FilePath mount_point_; 74 std::string device_id_; 75 StorageInfo disk_info_; 76 77 scoped_ptr<StorageMonitorMac> monitor_; 78}; 79 80TEST_F(StorageMonitorMacTest, AddRemove) { 81 UpdateDisk(disk_info_, StorageMonitorMac::UPDATE_DEVICE_ADDED); 82 83 EXPECT_EQ(1, mock_storage_observer_->attach_calls()); 84 EXPECT_EQ(0, mock_storage_observer_->detach_calls()); 85 EXPECT_EQ(device_id_, mock_storage_observer_->last_attached().device_id()); 86 EXPECT_EQ(mount_point_.value(), 87 mock_storage_observer_->last_attached().location()); 88 89 UpdateDisk(disk_info_, StorageMonitorMac::UPDATE_DEVICE_REMOVED); 90 91 EXPECT_EQ(1, mock_storage_observer_->attach_calls()); 92 EXPECT_EQ(1, mock_storage_observer_->detach_calls()); 93 EXPECT_EQ(device_id_, mock_storage_observer_->last_detached().device_id()); 94} 95 96TEST_F(StorageMonitorMacTest, UpdateVolumeName) { 97 UpdateDisk(disk_info_, StorageMonitorMac::UPDATE_DEVICE_ADDED); 98 99 EXPECT_EQ(1, mock_storage_observer_->attach_calls()); 100 EXPECT_EQ(0, mock_storage_observer_->detach_calls()); 101 EXPECT_EQ(device_id_, mock_storage_observer_->last_attached().device_id()); 102 EXPECT_EQ(kTestSize, 103 mock_storage_observer_->last_attached().total_size_in_bytes()); 104 EXPECT_EQ(mount_point_.value(), 105 mock_storage_observer_->last_attached().location()); 106 107 StorageInfo info2 = CreateStorageInfo( 108 device_id_, "", mount_point_, kTestSize * 2); 109 UpdateDisk(info2, StorageMonitorMac::UPDATE_DEVICE_CHANGED); 110 base::RunLoop().RunUntilIdle(); 111 112 EXPECT_EQ(1, mock_storage_observer_->detach_calls()); 113 EXPECT_EQ(device_id_, mock_storage_observer_->last_detached().device_id()); 114 EXPECT_EQ(2, mock_storage_observer_->attach_calls()); 115 EXPECT_EQ(device_id_, mock_storage_observer_->last_attached().device_id()); 116 EXPECT_EQ(kTestSize * 2, 117 mock_storage_observer_->last_attached().total_size_in_bytes()); 118 EXPECT_EQ(mount_point_.value(), 119 mock_storage_observer_->last_attached().location()); 120} 121 122TEST_F(StorageMonitorMacTest, DCIM) { 123 base::ScopedTempDir temp_dir; 124 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 125 ASSERT_TRUE(base::CreateDirectory( 126 temp_dir.path().Append(kDCIMDirectoryName))); 127 128 base::FilePath mount_point = temp_dir.path(); 129 std::string device_id = StorageInfo::MakeDeviceId( 130 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM, unique_id_); 131 StorageInfo info = CreateStorageInfo(device_id, "", mount_point, kTestSize); 132 133 UpdateDisk(info, StorageMonitorMac::UPDATE_DEVICE_ADDED); 134 135 EXPECT_EQ(1, mock_storage_observer_->attach_calls()); 136 EXPECT_EQ(0, mock_storage_observer_->detach_calls()); 137 EXPECT_EQ(device_id, mock_storage_observer_->last_attached().device_id()); 138 EXPECT_EQ(mount_point.value(), 139 mock_storage_observer_->last_attached().location()); 140} 141 142TEST_F(StorageMonitorMacTest, GetStorageInfo) { 143 UpdateDisk(disk_info_, StorageMonitorMac::UPDATE_DEVICE_ADDED); 144 145 EXPECT_EQ(1, mock_storage_observer_->attach_calls()); 146 EXPECT_EQ(0, mock_storage_observer_->detach_calls()); 147 EXPECT_EQ(device_id_, mock_storage_observer_->last_attached().device_id()); 148 EXPECT_EQ(mount_point_.value(), 149 mock_storage_observer_->last_attached().location()); 150 151 StorageInfo info; 152 EXPECT_TRUE(monitor_->GetStorageInfoForPath(mount_point_.AppendASCII("foo"), 153 &info)); 154 EXPECT_EQ(device_id_, info.device_id()); 155 EXPECT_EQ(mount_point_.value(), info.location()); 156 EXPECT_EQ(kTestSize, info.total_size_in_bytes()); 157 158 EXPECT_FALSE(monitor_->GetStorageInfoForPath( 159 base::FilePath("/non/matching/path"), &info)); 160} 161 162// Test that mounting a DMG doesn't send a notification. 163TEST_F(StorageMonitorMacTest, DMG) { 164 StorageInfo info = CreateStorageInfo( 165 device_id_, "Disk Image", mount_point_, kTestSize); 166 UpdateDisk(info, StorageMonitorMac::UPDATE_DEVICE_ADDED); 167 EXPECT_EQ(0, mock_storage_observer_->attach_calls()); 168} 169 170} // namespace storage_monitor 171