disk_mount_manager_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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
3// found in the LICENSE file.
4
5#include "base/bind.h"
6#include "base/message_loop.h"
7#include "chromeos/dbus/fake_cros_disks_client.h"
8#include "chromeos/dbus/mock_dbus_thread_manager_without_gmock.h"
9#include "chromeos/disks/disk_mount_manager.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13using chromeos::disks::DiskMountManager;
14using chromeos::CrosDisksClient;
15using chromeos::DBusThreadManager;
16using chromeos::FakeCrosDisksClient;
17using chromeos::MockDBusThreadManagerWithoutGMock;
18using testing::_;
19using testing::Field;
20using testing::InSequence;
21
22namespace {
23
24// Holds information needed to create a DiskMountManager::Disk instance.
25struct TestDiskInfo {
26  const char* source_path;
27  const char* mount_path;
28  const char* system_path;
29  const char* file_path;
30  const char* device_label;
31  const char* drive_label;
32  const char* vendor_id;
33  const char* vendor_name;
34  const char* product_id;
35  const char* product_name;
36  const char* fs_uuid;
37  const char* system_path_prefix;
38  chromeos::DeviceType device_type;
39  uint64 size_in_bytes;
40  bool is_parent;
41  bool is_read_only;
42  bool has_media;
43  bool on_boot_device;
44  bool is_hidden;
45};
46
47// Holds information to create a DiskMOuntManager::MountPointInfo instance.
48struct TestMountPointInfo {
49  const char* source_path;
50  const char* mount_path;
51  chromeos::MountType mount_type;
52  chromeos::disks::MountCondition mount_condition;
53};
54
55// List of disks held in DiskMountManager at the begining of the test.
56const TestDiskInfo kTestDisks[] = {
57  {
58    "/device/source_path",
59    "/device/mount_path",
60    "/device/prefix/system_path",
61    "/device/file_path",
62    "/device/device_label",
63    "/device/drive_label",
64    "/device/vendor_id",
65    "/device/vendor_name",
66    "/device/product_id",
67    "/device/product_name",
68    "/device/fs_uuid",
69    "/device/prefix",
70    chromeos::DEVICE_TYPE_USB,
71    1073741824,  // size in bytes
72    false,  // is parent
73    false,  // is read only
74    true,  // has media
75    false,  // is on boot device
76    false  // is hidden
77  },
78};
79
80// List of mount points  held in DiskMountManager at the begining of the test.
81const TestMountPointInfo kTestMountPoints[] = {
82  {
83    "/archive/source_path",
84    "/archive/mount_path",
85    chromeos::MOUNT_TYPE_ARCHIVE,
86    chromeos::disks::MOUNT_CONDITION_NONE
87  },
88  {
89    "/device/source_path",
90    "/device/mount_path",
91    chromeos::MOUNT_TYPE_DEVICE,
92    chromeos::disks::MOUNT_CONDITION_NONE
93  },
94};
95
96// Mocks DiskMountManager observer.
97class MockDiskMountManagerObserver : public DiskMountManager::Observer {
98 public:
99  virtual ~MockDiskMountManagerObserver() {}
100
101  MOCK_METHOD2(OnDiskEvent, void(DiskMountManager::DiskEvent event,
102                                 const DiskMountManager::Disk* disk));
103  MOCK_METHOD2(OnDeviceEvent, void(DiskMountManager::DeviceEvent event,
104                                   const std::string& device_path));
105  MOCK_METHOD3(OnMountEvent,
106      void(DiskMountManager::MountEvent event,
107           chromeos::MountError error_code,
108           const DiskMountManager::MountPointInfo& mount_point));
109  MOCK_METHOD3(OnFormatEvent,
110      void(DiskMountManager::FormatEvent event,
111           chromeos::FormatError error_code,
112           const std::string& device_path));
113};
114
115class DiskMountManagerTest : public testing::Test {
116 public:
117  DiskMountManagerTest() {}
118  virtual ~DiskMountManagerTest() {}
119
120  // Sets up test dbus tread manager and disks mount manager.
121  // Initializes disk mount manager disks and mount points.
122  // Adds a test observer to the disk mount manager.
123  virtual void SetUp() {
124    MockDBusThreadManagerWithoutGMock* mock_thread_manager =
125        new MockDBusThreadManagerWithoutGMock();
126    DBusThreadManager::InitializeForTesting(mock_thread_manager);
127
128    fake_cros_disks_client_ = mock_thread_manager->fake_cros_disks_client();
129
130    DiskMountManager::Initialize();
131
132    InitDisksAndMountPoints();
133
134    DiskMountManager::GetInstance()->AddObserver(&observer_);
135  }
136
137  // Shuts down dbus thread manager and disk moutn manager used in the test.
138  virtual void TearDown() {
139    DiskMountManager::GetInstance()->RemoveObserver(&observer_);
140    DiskMountManager::Shutdown();
141    DBusThreadManager::Shutdown();
142  }
143
144 protected:
145  // Checks if disk mount manager contains a mount point with specified moutn
146  // path.
147  bool HasMountPoint(const std::string& mount_path) {
148    const DiskMountManager::MountPointMap& mount_points =
149        DiskMountManager::GetInstance()->mount_points();
150    return mount_points.find(mount_path) != mount_points.end();
151  }
152
153 private:
154  // Adds a new disk to the disk mount manager.
155  void AddTestDisk(const TestDiskInfo& disk) {
156    EXPECT_TRUE(DiskMountManager::GetInstance()->AddDiskForTest(
157        new DiskMountManager::Disk(disk.source_path,
158                                   disk.mount_path,
159                                   disk.system_path,
160                                   disk.file_path,
161                                   disk.device_label,
162                                   disk.drive_label,
163                                   disk.vendor_id,
164                                   disk.vendor_name,
165                                   disk.product_id,
166                                   disk.product_name,
167                                   disk.fs_uuid,
168                                   disk.system_path_prefix,
169                                   disk.device_type,
170                                   disk.size_in_bytes,
171                                   disk.is_parent,
172                                   disk.is_read_only,
173                                   disk.has_media,
174                                   disk.on_boot_device,
175                                   disk.is_hidden)));
176  }
177
178  // Adds a new mount point to the disk mount manager.
179  // If the moutn point is a device mount point, disk with its source path
180  // should already be added to the disk mount manager.
181  void AddTestMountPoint(const TestMountPointInfo& mount_point) {
182    EXPECT_TRUE(DiskMountManager::GetInstance()->AddMountPointForTest(
183        DiskMountManager::MountPointInfo(mount_point.source_path,
184                                         mount_point.mount_path,
185                                         mount_point.mount_type,
186                                         mount_point.mount_condition)));
187  }
188
189  // Adds disks and mount points to disk mount manager.
190  void InitDisksAndMountPoints() {
191    // Disks should be  added first (when adding device mount points it is
192    // expected that the corresponding disk is already added).
193    for (size_t i = 0; i < arraysize(kTestDisks); i++)
194      AddTestDisk(kTestDisks[i]);
195
196    for (size_t i = 0; i < arraysize(kTestMountPoints); i++)
197      AddTestMountPoint(kTestMountPoints[i]);
198  }
199
200 protected:
201  chromeos::FakeCrosDisksClient* fake_cros_disks_client_;
202  MockDiskMountManagerObserver observer_;
203  base::MessageLoopForUI message_loop_;
204};
205
206// Tests that the observer gets notified on attempt to format non existent mount
207// point.
208TEST_F(DiskMountManagerTest, Format_NotMounted) {
209  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
210                                       chromeos::FORMAT_ERROR_UNKNOWN,
211                                       "/mount/non_existent"))
212      .Times(1);
213  DiskMountManager::GetInstance()->FormatMountedDevice("/mount/non_existent");
214}
215
216// Tests that it is not possible to format archive mount point.
217TEST_F(DiskMountManagerTest, Format_Archive) {
218  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
219                                       chromeos::FORMAT_ERROR_UNKNOWN,
220                                       "/archive/source_path"))
221      .Times(1);
222
223  DiskMountManager::GetInstance()->FormatMountedDevice("/archive/mount_path");
224}
225
226// Tests that format fails if the device cannot be unmounted.
227TEST_F(DiskMountManagerTest, Format_FailToUnmount) {
228  // Before formatting mounted device, the device should be unmounted.
229  // In this test unmount will fail, and there should be no attempt to
230  // format the device.
231
232  // Set up expectations for observer mock.
233  // Observer should be notified that unmount attempt fails and format task
234  // failed to start.
235  {
236    InSequence s;
237
238    EXPECT_CALL(observer_,
239        OnMountEvent(DiskMountManager::UNMOUNTING,
240                     chromeos::MOUNT_ERROR_INTERNAL,
241                     Field(&DiskMountManager::MountPointInfo::mount_path,
242                           "/device/mount_path")))
243        .Times(1);
244
245    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
246                                         chromeos::FORMAT_ERROR_UNKNOWN,
247                                         "/device/source_path"))
248        .Times(1);
249  }
250
251  fake_cros_disks_client_->MakeUnmountFail();
252  // Start test.
253  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
254
255  // Cros disks will respond asynchronoulsy, so let's drain the message loop.
256  message_loop_.RunUntilIdle();
257
258  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
259  EXPECT_EQ("/device/mount_path",
260            fake_cros_disks_client_->last_unmount_device_path());
261  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
262            fake_cros_disks_client_->last_unmount_options());
263  EXPECT_EQ(0, fake_cros_disks_client_->format_device_call_count());
264
265  // The device mount should still be here.
266  EXPECT_TRUE(HasMountPoint("/device/mount_path"));
267}
268
269// Tests that observer is notified when cros disks fails to start format
270// process.
271TEST_F(DiskMountManagerTest, Format_FormatFailsToStart) {
272  // Before formatting mounted device, the device should be unmounted.
273  // In this test, unmount will succeed, but call to FormatDevice method will
274  // fail.
275
276  // Set up expectations for observer mock.
277  // Observer should be notified that the device was unmounted and format task
278  // failed to start.
279  {
280    InSequence s;
281
282    EXPECT_CALL(observer_,
283        OnMountEvent(DiskMountManager::UNMOUNTING,
284                     chromeos::MOUNT_ERROR_NONE,
285                     Field(&DiskMountManager::MountPointInfo::mount_path,
286                           "/device/mount_path")))
287        .Times(1);
288
289    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
290                                         chromeos::FORMAT_ERROR_UNKNOWN,
291                                         "/device/source_path"))
292        .Times(1);
293  }
294
295  fake_cros_disks_client_->MakeFormatDeviceFail();
296  // Start the test.
297  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
298
299  // Cros disks will respond asynchronoulsy, so let's drain the message loop.
300  message_loop_.RunUntilIdle();
301
302  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
303  EXPECT_EQ("/device/mount_path",
304            fake_cros_disks_client_->last_unmount_device_path());
305  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
306            fake_cros_disks_client_->last_unmount_options());
307  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
308  EXPECT_EQ("/device/source_path",
309            fake_cros_disks_client_->last_format_device_device_path());
310  EXPECT_EQ("vfat",
311            fake_cros_disks_client_->last_format_device_filesystem());
312
313  // The device mount should be gone.
314  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
315}
316
317// Tests the case where there are two format requests for the same device.
318TEST_F(DiskMountManagerTest, Format_ConcurrentFormatCalls) {
319  // Only the first format request should be processed (the second unmount
320  // request fails because the device is already unmounted at that point).
321  // CrosDisksClient will report that the format process for the first request
322  // is successfully started.
323
324  // Set up expectations for observer mock.
325  // The observer should get two FORMAT_STARTED events, one for each format
326  // request, but with different error codes (the formatting will be started
327  // only for the first request).
328  // There should be only one UNMOUNTING event. The result of the second one
329  // should not be reported as the mount point will go away after the first
330  // request.
331  //
332  // Note that in this test the format completion signal will not be simulated,
333  // so the observer should not get FORMAT_COMPLETED signal.
334  {
335    InSequence s;
336
337    EXPECT_CALL(observer_,
338        OnMountEvent(DiskMountManager::UNMOUNTING,
339                     chromeos::MOUNT_ERROR_NONE,
340                     Field(&DiskMountManager::MountPointInfo::mount_path,
341                           "/device/mount_path")))
342        .Times(1);
343
344    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
345                                         chromeos::FORMAT_ERROR_UNKNOWN,
346                                         "/device/source_path"))
347        .Times(1);
348
349    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
350                                         chromeos::FORMAT_ERROR_NONE,
351                                         "/device/source_path"))
352        .Times(1);
353  }
354
355  fake_cros_disks_client_->set_unmount_listener(
356      base::Bind(&FakeCrosDisksClient::MakeUnmountFail,
357                 base::Unretained(fake_cros_disks_client_)));
358  // Start the test.
359  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
360  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
361
362  // Cros disks will respond asynchronoulsy, so let's drain the message loop.
363  message_loop_.RunUntilIdle();
364
365  EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
366  EXPECT_EQ("/device/mount_path",
367            fake_cros_disks_client_->last_unmount_device_path());
368  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
369            fake_cros_disks_client_->last_unmount_options());
370  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
371  EXPECT_EQ("/device/source_path",
372            fake_cros_disks_client_->last_format_device_device_path());
373  EXPECT_EQ("vfat",
374            fake_cros_disks_client_->last_format_device_filesystem());
375
376  // The device mount should be gone.
377  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
378}
379
380// Tests the case when the format process actually starts and fails.
381TEST_F(DiskMountManagerTest, Format_FormatFails) {
382  // Both unmount and format device cals are successfull in this test.
383
384  // Set up expectations for observer mock.
385  // The observer should get notified that the device was unmounted and that
386  // formatting has started.
387  // After the formatting starts, the test will simulate failing
388  // FORMATTING_FINISHED signal, so the observer should also be notified the
389  // formatting has failed (FORMAT_COMPLETED event).
390  {
391    InSequence s;
392
393    EXPECT_CALL(observer_,
394        OnMountEvent(DiskMountManager::UNMOUNTING,
395                     chromeos::MOUNT_ERROR_NONE,
396                     Field(&DiskMountManager::MountPointInfo::mount_path,
397                           "/device/mount_path")))
398        .Times(1);
399
400    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
401                                         chromeos::FORMAT_ERROR_NONE,
402                                         "/device/source_path"))
403        .Times(1);
404
405    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
406                                         chromeos::FORMAT_ERROR_UNKNOWN,
407                                         "/device/source_path"))
408        .Times(1);
409  }
410
411  // Start the test.
412  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
413
414  // Wait for Unmount and FormatDevice calls to end.
415  message_loop_.RunUntilIdle();
416
417  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
418  EXPECT_EQ("/device/mount_path",
419            fake_cros_disks_client_->last_unmount_device_path());
420  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
421            fake_cros_disks_client_->last_unmount_options());
422  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
423  EXPECT_EQ("/device/source_path",
424            fake_cros_disks_client_->last_format_device_device_path());
425  EXPECT_EQ("vfat",
426            fake_cros_disks_client_->last_format_device_filesystem());
427
428  // The device should be unmounted by now.
429  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
430
431  // Send failing FORMATTING_FINISHED signal.
432  // The failure is marked by ! in fromt of the path (but this should change
433  // soon).
434  fake_cros_disks_client_->SendMountEvent(
435      chromeos::CROS_DISKS_FORMATTING_FINISHED, "!/device/source_path");
436}
437
438// Tests the same case as Format_FormatFails, but the FORMATTING_FINISHED event
439// is sent with file_path of the formatted device (instead of its device path).
440TEST_F(DiskMountManagerTest, Format_FormatFailsAndReturnFilePath) {
441  // Set up expectations for observer mock.
442  {
443    InSequence s;
444
445    EXPECT_CALL(observer_,
446        OnMountEvent(DiskMountManager::UNMOUNTING,
447                     chromeos::MOUNT_ERROR_NONE,
448                     Field(&DiskMountManager::MountPointInfo::mount_path,
449                           "/device/mount_path")))
450        .Times(1);
451
452    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
453                                         chromeos::FORMAT_ERROR_NONE,
454                                         "/device/source_path"))
455        .Times(1);
456
457    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
458                                         chromeos::FORMAT_ERROR_UNKNOWN,
459                                         "/device/source_path"))
460        .Times(1);
461  }
462
463  // Start test.
464  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
465
466  // Wait for Unmount and FormatDevice calls to end.
467  message_loop_.RunUntilIdle();
468
469  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
470  EXPECT_EQ("/device/mount_path",
471            fake_cros_disks_client_->last_unmount_device_path());
472  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
473            fake_cros_disks_client_->last_unmount_options());
474  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
475  EXPECT_EQ("/device/source_path",
476            fake_cros_disks_client_->last_format_device_device_path());
477  EXPECT_EQ("vfat",
478            fake_cros_disks_client_->last_format_device_filesystem());
479
480  // The device should be unmounted by now.
481  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
482
483  // Send failing FORMATTING_FINISHED signal with the device's file path.
484  fake_cros_disks_client_->SendMountEvent(
485      chromeos::CROS_DISKS_FORMATTING_FINISHED, "!/device/file_path");
486}
487
488// Tests the case when formatting completes successfully.
489TEST_F(DiskMountManagerTest, Format_FormatSuccess) {
490  // Set up cros disks client mocks.
491  // Both unmount and format device cals are successfull in this test.
492
493  // Set up expectations for observer mock.
494  // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
495  // events (all of them without an error set).
496  {
497    InSequence s;
498
499    EXPECT_CALL(observer_,
500        OnMountEvent(DiskMountManager::UNMOUNTING,
501                     chromeos::MOUNT_ERROR_NONE,
502                     Field(&DiskMountManager::MountPointInfo::mount_path,
503                           "/device/mount_path")))
504        .Times(1);
505
506    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
507                                         chromeos::FORMAT_ERROR_NONE,
508                                         "/device/source_path"))
509        .Times(1);
510
511    EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
512                                         chromeos::FORMAT_ERROR_NONE,
513                                         "/device/source_path"))
514        .Times(1);
515  }
516
517  // Start the test.
518  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
519
520  // Wait for Unmount and FormatDevice calls to end.
521  message_loop_.RunUntilIdle();
522
523  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
524  EXPECT_EQ("/device/mount_path",
525            fake_cros_disks_client_->last_unmount_device_path());
526  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
527            fake_cros_disks_client_->last_unmount_options());
528  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
529  EXPECT_EQ("/device/source_path",
530            fake_cros_disks_client_->last_format_device_device_path());
531  EXPECT_EQ("vfat",
532            fake_cros_disks_client_->last_format_device_filesystem());
533
534  // The device should be unmounted by now.
535  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
536
537  // Simulate cros_disks reporting success.
538  fake_cros_disks_client_->SendMountEvent(
539      chromeos::CROS_DISKS_FORMATTING_FINISHED, "/device/source_path");
540}
541
542// Tests that it's possible to format the device twice in a row (this may not be
543// true if the list of pending formats is not properly cleared).
544TEST_F(DiskMountManagerTest, Format_ConsecutiveFormatCalls) {
545  // All unmount and format device cals are successfull in this test.
546  // Each of the should be made twice (once for each formatting task).
547
548  // Set up expectations for observer mock.
549  // The observer should receive UNMOUNTING, FORMAT_STARTED and FORMAT_COMPLETED
550  // events (all of them without an error set) twice (once for each formatting
551  // task).
552  // Also, there should be a MOUNTING event when the device remounting is
553  // simulated.
554  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_COMPLETED,
555                                       chromeos::FORMAT_ERROR_NONE,
556                                       "/device/source_path"))
557      .Times(2);
558
559  EXPECT_CALL(observer_, OnFormatEvent(DiskMountManager::FORMAT_STARTED,
560                                       chromeos::FORMAT_ERROR_NONE,
561                                       "/device/source_path"))
562      .Times(2);
563
564  EXPECT_CALL(observer_,
565      OnMountEvent(DiskMountManager::UNMOUNTING,
566                   chromeos::MOUNT_ERROR_NONE,
567                   Field(&DiskMountManager::MountPointInfo::mount_path,
568                         "/device/mount_path")))
569      .Times(2);
570
571  EXPECT_CALL(observer_,
572      OnMountEvent(DiskMountManager::MOUNTING,
573                   chromeos::MOUNT_ERROR_NONE,
574                   Field(&DiskMountManager::MountPointInfo::mount_path,
575                         "/device/mount_path")))
576      .Times(1);
577
578  // Start the test.
579  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
580
581  // Wait for Unmount and FormatDevice calls to end.
582  message_loop_.RunUntilIdle();
583
584  EXPECT_EQ(1, fake_cros_disks_client_->unmount_call_count());
585  EXPECT_EQ("/device/mount_path",
586            fake_cros_disks_client_->last_unmount_device_path());
587  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
588            fake_cros_disks_client_->last_unmount_options());
589  EXPECT_EQ(1, fake_cros_disks_client_->format_device_call_count());
590  EXPECT_EQ("/device/source_path",
591            fake_cros_disks_client_->last_format_device_device_path());
592  EXPECT_EQ("vfat",
593            fake_cros_disks_client_->last_format_device_filesystem());
594
595  // The device should be unmounted by now.
596  EXPECT_FALSE(HasMountPoint("/device/mount_path"));
597
598  // Simulate cros_disks reporting success.
599  fake_cros_disks_client_->SendMountEvent(
600      chromeos::CROS_DISKS_FORMATTING_FINISHED, "/device/source_path");
601
602  // Simulate the device remounting.
603  fake_cros_disks_client_->SendMountCompletedEvent(
604      chromeos::MOUNT_ERROR_NONE,
605      "/device/source_path",
606      chromeos::MOUNT_TYPE_DEVICE,
607      "/device/mount_path");
608
609  EXPECT_TRUE(HasMountPoint("/device/mount_path"));
610
611  // Try formatting again.
612  DiskMountManager::GetInstance()->FormatMountedDevice("/device/mount_path");
613
614  // Wait for Unmount and FormatDevice calls to end.
615  message_loop_.RunUntilIdle();
616
617  EXPECT_EQ(2, fake_cros_disks_client_->unmount_call_count());
618  EXPECT_EQ("/device/mount_path",
619            fake_cros_disks_client_->last_unmount_device_path());
620  EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_NONE,
621            fake_cros_disks_client_->last_unmount_options());
622  EXPECT_EQ(2, fake_cros_disks_client_->format_device_call_count());
623  EXPECT_EQ("/device/source_path",
624            fake_cros_disks_client_->last_format_device_device_path());
625  EXPECT_EQ("vfat",
626            fake_cros_disks_client_->last_format_device_filesystem());
627
628  // Simulate cros_disks reporting success.
629  fake_cros_disks_client_->SendMountEvent(
630      chromeos::CROS_DISKS_FORMATTING_FINISHED, "/device/source_path");
631}
632
633}  // namespace
634
635