xref: /openbmc/estoraged/src/test/estoraged_test.cpp (revision 4bc8a10caff8d7154d9ad789b9d0fc01499fa02e)
1 
2 #include "cryptsetupInterface.hpp"
3 #include "estoraged.hpp"
4 #include "filesystemInterface.hpp"
5 
6 #include <unistd.h>
7 
8 #include <sdbusplus/bus.hpp>
9 #include <sdbusplus/test/sdbus_mock.hpp>
10 #include <xyz/openbmc_project/Common/error.hpp>
11 
12 #include <exception>
13 #include <filesystem>
14 #include <fstream>
15 #include <iterator>
16 #include <string>
17 #include <vector>
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 namespace estoraged_test
23 {
24 
25 class MockFilesystemInterface : public estoraged::FilesystemInterface
26 {
27   public:
28     MOCK_METHOD(int, runMkfs, (const std::string& logicalVolume), (override));
29 
30     MOCK_METHOD(int, doMount,
31                 (const char* source, const char* target,
32                  const char* filesystemtype, unsigned long mountflags,
33                  const void* data),
34                 (override));
35 
36     MOCK_METHOD(int, doUnmount, (const char* target), (override));
37 
38     MOCK_METHOD(bool, createDirectory, (const std::filesystem::path& p),
39                 (override));
40 
41     MOCK_METHOD(bool, removeDirectory, (const std::filesystem::path& p),
42                 (override));
43 
44     MOCK_METHOD(bool, directoryExists, (const std::filesystem::path& p),
45                 (override));
46 };
47 
48 class MockCryptsetupInterface : public estoraged::CryptsetupInterface
49 {
50   public:
51     MOCK_METHOD(int, cryptFormat,
52                 (struct crypt_device * cd, const char* type, const char* cipher,
53                  const char* cipher_mode, const char* uuid,
54                  const char* volume_key, size_t volume_key_size, void* params),
55                 (override));
56 
57     MOCK_METHOD(int, cryptKeyslotAddByVolumeKey,
58                 (struct crypt_device * cd, int keyslot, const char* volume_key,
59                  size_t volume_key_size, const char* passphrase,
60                  size_t passphrase_size),
61                 (override));
62 
63     MOCK_METHOD(int, cryptLoad,
64                 (struct crypt_device * cd, const char* requested_type,
65                  void* params),
66                 (override));
67 
68     MOCK_METHOD(int, cryptActivateByPassphrase,
69                 (struct crypt_device * cd, const char* name, int keyslot,
70                  const char* passphrase, size_t passphrase_size,
71                  uint32_t flags),
72                 (override));
73 
74     MOCK_METHOD(int, cryptDeactivate,
75                 (struct crypt_device * cd, const char* name), (override));
76 };
77 
78 using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
79 using sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;
80 using sdbusplus::xyz::openbmc_project::Inventory::Item::server::Volume;
81 using std::filesystem::path;
82 using ::testing::_;
83 using ::testing::ContainsRegex;
84 using ::testing::IsNull;
85 using ::testing::Return;
86 using ::testing::StrEq;
87 
88 /*
89  * This sdbus mock object gets used in the destructor of one of the parent
90  * classes for the MockeStoraged object, so this can't be part of the
91  * eStoragedTest class.
92  */
93 sdbusplus::SdBusMock sdbusMock;
94 
95 class eStoragedTest : public testing::Test
96 {
97   public:
98     static constexpr char testFileName[] = "testfile";
99     static constexpr char testLuksDevName[] = "testfile_luksDev";
100     std::ofstream testFile;
101     std::unique_ptr<estoraged::eStoraged> esObject;
102     static constexpr auto TEST_PATH = "/test/openbmc_project/storage/test_dev";
103     static constexpr auto ESTORAGED_INTERFACE =
104         "xyz.openbmc_project.Inventory.Item.Volume";
105     sdbusplus::bus::bus bus;
106     std::string passwordString;
107     std::vector<uint8_t> password;
108     MockCryptsetupInterface* mockCryptIface;
109     MockFilesystemInterface* mockFsIface;
110 
111     eStoragedTest() :
112         bus(sdbusplus::get_mocked_new(&sdbusMock)), passwordString("password"),
113         password(passwordString.begin(), passwordString.end())
114     {}
115 
116     void SetUp() override
117     {
118         /* Create an empty file that we'll pretend is a 'storage device'. */
119         testFile.open(testFileName,
120                       std::ios::out | std::ios::binary | std::ios::trunc);
121         testFile.close();
122         if (testFile.fail())
123         {
124             throw std::runtime_error("Failed to open test file");
125         }
126 
127         EXPECT_CALL(sdbusMock,
128                     sd_bus_add_object_vtable(IsNull(), _, StrEq(TEST_PATH),
129                                              StrEq(ESTORAGED_INTERFACE), _, _))
130             .WillRepeatedly(Return(0));
131 
132         EXPECT_CALL(sdbusMock,
133                     sd_bus_emit_object_added(IsNull(), StrEq(TEST_PATH)))
134             .WillRepeatedly(Return(0));
135 
136         EXPECT_CALL(sdbusMock,
137                     sd_bus_emit_object_removed(IsNull(), StrEq(TEST_PATH)))
138             .WillRepeatedly(Return(0));
139 
140         std::unique_ptr<MockCryptsetupInterface> cryptIface =
141             std::make_unique<MockCryptsetupInterface>();
142         mockCryptIface = cryptIface.get();
143         std::unique_ptr<MockFilesystemInterface> fsIface =
144             std::make_unique<MockFilesystemInterface>();
145         mockFsIface = fsIface.get();
146 
147         esObject = std::make_unique<estoraged::eStoraged>(
148             bus, TEST_PATH, std::string(testFileName),
149             std::string(testLuksDevName), std::move(cryptIface),
150             std::move(fsIface));
151     }
152 
153     void TearDown() override
154     {
155         EXPECT_EQ(0, unlink(testFileName));
156     }
157 };
158 
159 /* Test case to format and then lock the LUKS device. */
160 TEST_F(eStoragedTest, FormatPass)
161 {
162     EXPECT_CALL(sdbusMock,
163                 sd_bus_emit_properties_changed_strv(
164                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
165         .WillRepeatedly(Return(0));
166 
167     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
168 
169     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
170         .Times(1);
171 
172     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
173 
174     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
175         .Times(1);
176 
177     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
178 
179     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
180         .WillOnce(Return(false));
181 
182     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
183         .WillOnce(Return(true));
184 
185     EXPECT_CALL(*mockFsIface,
186                 doMount(ContainsRegex("/dev/mapper/"),
187                         StrEq(esObject->getMountPoint()), _, _, _))
188         .WillOnce(Return(0));
189 
190     EXPECT_CALL(*mockFsIface, doUnmount(StrEq(esObject->getMountPoint())))
191         .WillOnce(Return(0));
192 
193     EXPECT_CALL(*mockFsIface, removeDirectory(path(esObject->getMountPoint())))
194         .WillOnce(Return(true));
195 
196     EXPECT_CALL(*mockCryptIface, cryptDeactivate(_, _)).Times(1);
197 
198     /* Format the encrypted device. */
199     esObject->formatLuks(password, Volume::FilesystemType::ext4);
200     EXPECT_FALSE(esObject->isLocked());
201 
202     esObject->lock();
203     EXPECT_TRUE(esObject->isLocked());
204 }
205 
206 /*
207  * Test case where the mount point directory already exists, so it shouldn't
208  * try to create it.
209  */
210 TEST_F(eStoragedTest, MountPointExistsPass)
211 {
212     EXPECT_CALL(sdbusMock,
213                 sd_bus_emit_properties_changed_strv(
214                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
215         .WillRepeatedly(Return(0));
216 
217     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
218 
219     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
220         .Times(1);
221 
222     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
223 
224     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
225         .Times(1);
226 
227     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
228 
229     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
230         .WillOnce(Return(true));
231 
232     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
233         .Times(0);
234 
235     EXPECT_CALL(*mockFsIface,
236                 doMount(ContainsRegex("/dev/mapper/"),
237                         StrEq(esObject->getMountPoint()), _, _, _))
238         .WillOnce(Return(0));
239 
240     EXPECT_CALL(*mockFsIface, doUnmount(StrEq(esObject->getMountPoint())))
241         .WillOnce(Return(0));
242 
243     EXPECT_CALL(*mockFsIface, removeDirectory(path(esObject->getMountPoint())))
244         .WillOnce(Return(true));
245 
246     EXPECT_CALL(*mockCryptIface, cryptDeactivate(_, _)).Times(1);
247 
248     /* Format the encrypted device. */
249     esObject->formatLuks(password, Volume::FilesystemType::ext4);
250     EXPECT_FALSE(esObject->isLocked());
251 
252     esObject->lock();
253     EXPECT_TRUE(esObject->isLocked());
254 }
255 
256 /* Test case where the device/file doesn't exist. */
257 TEST_F(eStoragedTest, FormatNoDeviceFail)
258 {
259     /* Delete the test file. */
260     EXPECT_EQ(0, unlink(testFileName));
261 
262     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
263                  ResourceNotFound);
264     EXPECT_FALSE(esObject->isLocked());
265 
266     /* Create the test file again, so that the TearDown function works. */
267     testFile.open(testFileName,
268                   std::ios::out | std::ios::binary | std::ios::trunc);
269     testFile.close();
270 }
271 
272 /* Test case where we fail to format the LUKS device. */
273 TEST_F(eStoragedTest, FormatFail)
274 {
275     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _))
276         .WillOnce(Return(-1));
277 
278     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
279                  InternalFailure);
280     EXPECT_FALSE(esObject->isLocked());
281 }
282 
283 /* Test case where we fail to set the password for the LUKS device. */
284 TEST_F(eStoragedTest, AddKeyslotFail)
285 {
286     EXPECT_CALL(sdbusMock,
287                 sd_bus_emit_properties_changed_strv(
288                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
289         .WillRepeatedly(Return(0));
290 
291     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
292 
293     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
294         .WillOnce(Return(-1));
295 
296     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
297                  InternalFailure);
298     EXPECT_TRUE(esObject->isLocked());
299 }
300 
301 /* Test case where we fail to load the LUKS header. */
302 TEST_F(eStoragedTest, LoadLuksHeaderFail)
303 {
304     EXPECT_CALL(sdbusMock,
305                 sd_bus_emit_properties_changed_strv(
306                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
307         .WillRepeatedly(Return(0));
308 
309     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
310 
311     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
312         .Times(1);
313 
314     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).WillOnce(Return(-1));
315 
316     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
317                  InternalFailure);
318     EXPECT_TRUE(esObject->isLocked());
319 }
320 
321 /* Test case where we fail to activate the LUKS device. */
322 TEST_F(eStoragedTest, ActivateFail)
323 {
324     EXPECT_CALL(sdbusMock,
325                 sd_bus_emit_properties_changed_strv(
326                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
327         .WillRepeatedly(Return(0));
328 
329     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
330 
331     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
332         .Times(1);
333 
334     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
335 
336     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
337         .WillOnce(Return(-1));
338 
339     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
340                  InternalFailure);
341     EXPECT_TRUE(esObject->isLocked());
342 }
343 
344 /* Test case where we fail to create the filesystem. */
345 TEST_F(eStoragedTest, CreateFilesystemFail)
346 {
347     EXPECT_CALL(sdbusMock,
348                 sd_bus_emit_properties_changed_strv(
349                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
350         .WillRepeatedly(Return(0));
351 
352     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
353 
354     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
355         .Times(1);
356 
357     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
358 
359     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
360         .Times(1);
361 
362     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(-1));
363 
364     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
365                  InternalFailure);
366     EXPECT_FALSE(esObject->isLocked());
367 }
368 
369 /* Test case where we fail to create the mount point. */
370 TEST_F(eStoragedTest, CreateMountPointFail)
371 {
372     EXPECT_CALL(sdbusMock,
373                 sd_bus_emit_properties_changed_strv(
374                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
375         .WillRepeatedly(Return(0));
376 
377     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
378 
379     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
380         .Times(1);
381 
382     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
383 
384     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
385         .Times(1);
386 
387     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
388 
389     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
390         .WillOnce(Return(false));
391 
392     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
393         .WillOnce(Return(false));
394 
395     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
396                  InternalFailure);
397     EXPECT_FALSE(esObject->isLocked());
398 }
399 
400 /* Test case where we fail to mount the filesystem. */
401 TEST_F(eStoragedTest, MountFail)
402 {
403     EXPECT_CALL(sdbusMock,
404                 sd_bus_emit_properties_changed_strv(
405                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
406         .WillRepeatedly(Return(0));
407 
408     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
409 
410     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
411         .Times(1);
412 
413     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
414 
415     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
416         .Times(1);
417 
418     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
419 
420     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
421         .WillOnce(Return(false));
422 
423     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
424         .WillOnce(Return(true));
425 
426     EXPECT_CALL(*mockFsIface,
427                 doMount(ContainsRegex("/dev/mapper/"),
428                         StrEq(esObject->getMountPoint()), _, _, _))
429         .WillOnce(Return(-1));
430 
431     EXPECT_CALL(*mockFsIface, removeDirectory(path(esObject->getMountPoint())))
432         .WillOnce(Return(true));
433 
434     EXPECT_THROW(esObject->formatLuks(password, Volume::FilesystemType::ext4),
435                  InternalFailure);
436     EXPECT_FALSE(esObject->isLocked());
437 }
438 
439 /* Test case where we fail to unmount the filesystem. */
440 TEST_F(eStoragedTest, UnmountFail)
441 {
442     EXPECT_CALL(sdbusMock,
443                 sd_bus_emit_properties_changed_strv(
444                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
445         .WillRepeatedly(Return(0));
446 
447     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
448 
449     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
450         .Times(1);
451 
452     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
453 
454     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
455         .Times(1);
456 
457     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
458 
459     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
460         .WillOnce(Return(false));
461 
462     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
463         .WillOnce(Return(true));
464 
465     EXPECT_CALL(*mockFsIface,
466                 doMount(ContainsRegex("/dev/mapper/"),
467                         StrEq(esObject->getMountPoint()), _, _, _))
468         .WillOnce(Return(0));
469 
470     EXPECT_CALL(*mockFsIface, doUnmount(StrEq(esObject->getMountPoint())))
471         .WillOnce(Return(-1));
472 
473     esObject->formatLuks(password, Volume::FilesystemType::ext4);
474     EXPECT_FALSE(esObject->isLocked());
475 
476     EXPECT_THROW(esObject->lock(), InternalFailure);
477     EXPECT_FALSE(esObject->isLocked());
478 }
479 
480 /* Test case where we fail to remove the mount point. */
481 TEST_F(eStoragedTest, RemoveMountPointFail)
482 {
483     EXPECT_CALL(sdbusMock,
484                 sd_bus_emit_properties_changed_strv(
485                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
486         .WillRepeatedly(Return(0));
487 
488     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
489 
490     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
491         .Times(1);
492 
493     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
494 
495     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
496         .Times(1);
497 
498     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
499 
500     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
501         .WillOnce(Return(false));
502 
503     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
504         .WillOnce(Return(true));
505 
506     EXPECT_CALL(*mockFsIface,
507                 doMount(ContainsRegex("/dev/mapper/"),
508                         StrEq(esObject->getMountPoint()), _, _, _))
509         .WillOnce(Return(0));
510 
511     EXPECT_CALL(*mockFsIface, doUnmount(StrEq(esObject->getMountPoint())))
512         .WillOnce(Return(0));
513 
514     EXPECT_CALL(*mockFsIface, removeDirectory(path(esObject->getMountPoint())))
515         .WillOnce(Return(false));
516 
517     esObject->formatLuks(password, Volume::FilesystemType::ext4);
518     EXPECT_FALSE(esObject->isLocked());
519 
520     /* This will fail to remove the mount point. */
521     EXPECT_THROW(esObject->lock(), InternalFailure);
522     EXPECT_FALSE(esObject->isLocked());
523 }
524 
525 /* Test case where we fail to deactivate the LUKS device. */
526 TEST_F(eStoragedTest, DeactivateFail)
527 {
528     EXPECT_CALL(sdbusMock,
529                 sd_bus_emit_properties_changed_strv(
530                     IsNull(), StrEq(TEST_PATH), StrEq(ESTORAGED_INTERFACE), _))
531         .WillRepeatedly(Return(0));
532 
533     EXPECT_CALL(*mockCryptIface, cryptFormat(_, _, _, _, _, _, _, _)).Times(1);
534 
535     EXPECT_CALL(*mockCryptIface, cryptKeyslotAddByVolumeKey(_, _, _, _, _, _))
536         .Times(1);
537 
538     EXPECT_CALL(*mockCryptIface, cryptLoad(_, _, _)).Times(1);
539 
540     EXPECT_CALL(*mockCryptIface, cryptActivateByPassphrase(_, _, _, _, _, _))
541         .Times(1);
542 
543     EXPECT_CALL(*mockFsIface, runMkfs(testLuksDevName)).WillOnce(Return(0));
544 
545     EXPECT_CALL(*mockFsIface, directoryExists(path(esObject->getMountPoint())))
546         .WillOnce(Return(false));
547 
548     EXPECT_CALL(*mockFsIface, createDirectory(path(esObject->getMountPoint())))
549         .WillOnce(Return(true));
550 
551     EXPECT_CALL(*mockFsIface,
552                 doMount(ContainsRegex("/dev/mapper/"),
553                         StrEq(esObject->getMountPoint()), _, _, _))
554         .WillOnce(Return(0));
555 
556     EXPECT_CALL(*mockFsIface, doUnmount(StrEq(esObject->getMountPoint())))
557         .WillOnce(Return(0));
558 
559     EXPECT_CALL(*mockFsIface, removeDirectory(path(esObject->getMountPoint())))
560         .WillOnce(Return(true));
561 
562     EXPECT_CALL(*mockCryptIface, cryptDeactivate(_, _)).WillOnce(Return(-1));
563 
564     /* Format the encrypted device. */
565     esObject->formatLuks(password, Volume::FilesystemType::ext4);
566     EXPECT_FALSE(esObject->isLocked());
567 
568     EXPECT_THROW(esObject->lock(), InternalFailure);
569     EXPECT_FALSE(esObject->isLocked());
570 }
571 
572 } // namespace estoraged_test
573