]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / librbd / crypto / luks / test_mock_FormatRequest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "test/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7
8 namespace librbd {
9 namespace util {
10
11 inline ImageCtx *get_image_ctx(MockImageCtx *image_ctx) {
12 return image_ctx->image_ctx;
13 }
14
15 } // namespace util
16 } // namespace librbd
17
18 #include "librbd/crypto/luks/FormatRequest.cc"
19
20 namespace librbd {
21 namespace crypto {
22 namespace luks {
23
24 using ::testing::_;
25 using ::testing::Invoke;
26 using ::testing::Return;
27
28 struct TestMockCryptoLuksFormatRequest : public TestMockFixture {
29 typedef FormatRequest<librbd::MockImageCtx> MockFormatRequest;
30
31 const size_t OBJECT_SIZE = 4 * 1024 * 1024;
32 const size_t IMAGE_SIZE = 1024 * 1024 * 1024;
33 const char* passphrase_cstr = "password";
34 std::string passphrase = passphrase_cstr;
35
36 MockImageCtx* mock_image_ctx;
37 C_SaferCond finished_cond;
38 Context *on_finish = &finished_cond;
39 io::AioCompletion* aio_comp;
40 ceph::bufferlist header_bl;
41 ceph::ref_t<CryptoInterface> crypto;
42
43 void SetUp() override {
44 TestMockFixture::SetUp();
45
46 librbd::ImageCtx *ictx;
47 ASSERT_EQ(0, open_image(m_image_name, &ictx));
48 mock_image_ctx = new MockImageCtx(*ictx);
49 }
50
51 void TearDown() override {
52 delete mock_image_ctx;
53 TestMockFixture::TearDown();
54 }
55
56 void expect_get_object_size() {
57 EXPECT_CALL(*mock_image_ctx, get_object_size()).WillOnce(Return(
58 OBJECT_SIZE));
59 }
60
61 void expect_get_image_size(uint64_t image_size) {
62 EXPECT_CALL(*mock_image_ctx, get_image_size(CEPH_NOSNAP)).WillOnce(Return(
63 image_size));
64 }
65
66 void expect_image_write() {
67 EXPECT_CALL(*mock_image_ctx->io_image_dispatcher, send(_))
68 .WillOnce(Invoke([this](io::ImageDispatchSpec* spec) {
69 auto* write = boost::get<io::ImageDispatchSpec::Write>(
70 &spec->request);
71 ASSERT_TRUE(write != nullptr);
72
73 ASSERT_EQ(1, spec->image_extents.size());
74 ASSERT_EQ(0, spec->image_extents[0].first);
75 ASSERT_GT(spec->image_extents[0].second, 0);
76
77 spec->dispatch_result = io::DISPATCH_RESULT_COMPLETE;
78 aio_comp = spec->aio_comp;
79 header_bl = write->bl;
80 }));
81 }
82
83 void complete_aio(int r) {
84 if (r < 0) {
85 aio_comp->fail(r);
86 } else {
87 aio_comp->set_request_count(1);
88 aio_comp->add_request();
89 aio_comp->complete_request(r);
90 }
91 }
92
93 void verify_header(const char* expected_format, size_t expected_key_length,
94 uint64_t expected_sector_size) {
95 Header header(mock_image_ctx->cct);
96
97 ASSERT_EQ(0, header.init());
98 ASSERT_EQ(0, header.write(header_bl));
99 ASSERT_EQ(0, header.load(expected_format));
100
101 ASSERT_EQ(expected_sector_size, header.get_sector_size());
102 ASSERT_EQ(0, header.get_data_offset() % OBJECT_SIZE);
103
104 char volume_key[64];
105 size_t volume_key_size = sizeof(volume_key);
106 ASSERT_EQ(0, header.read_volume_key(
107 passphrase_cstr, strlen(passphrase_cstr),
108 reinterpret_cast<char*>(volume_key), &volume_key_size));
109
110 ASSERT_EQ(expected_key_length, crypto->get_key_length());
111 ASSERT_EQ(0, std::memcmp(
112 volume_key, crypto->get_key(), expected_key_length));
113 ASSERT_EQ(expected_sector_size, crypto->get_block_size());
114 ASSERT_EQ(header.get_data_offset(), crypto->get_data_offset());
115 }
116 };
117
118 TEST_F(TestMockCryptoLuksFormatRequest, LUKS1) {
119 auto mock_format_request = MockFormatRequest::create(
120 mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS1,
121 RBD_ENCRYPTION_ALGORITHM_AES128, std::move(passphrase), &crypto,
122 on_finish, true);
123 expect_get_object_size();
124 expect_get_image_size(IMAGE_SIZE);
125 expect_image_write();
126 mock_format_request->send();
127 ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
128 complete_aio(0);
129 ASSERT_EQ(0, finished_cond.wait());
130 ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS1, 32, 512));
131 }
132
133 TEST_F(TestMockCryptoLuksFormatRequest, AES128) {
134 auto mock_format_request = MockFormatRequest::create(
135 mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS2,
136 RBD_ENCRYPTION_ALGORITHM_AES128, std::move(passphrase), &crypto,
137 on_finish, true);
138 expect_get_object_size();
139 expect_get_image_size(IMAGE_SIZE);
140 expect_image_write();
141 mock_format_request->send();
142 ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
143 complete_aio(0);
144 ASSERT_EQ(0, finished_cond.wait());
145 ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 32, 4096));
146 }
147
148 TEST_F(TestMockCryptoLuksFormatRequest, AES256) {
149 auto mock_format_request = MockFormatRequest::create(
150 mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS2,
151 RBD_ENCRYPTION_ALGORITHM_AES256, std::move(passphrase), &crypto,
152 on_finish, true);
153 expect_get_object_size();
154 expect_get_image_size(IMAGE_SIZE);
155 expect_image_write();
156 mock_format_request->send();
157 ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
158 complete_aio(0);
159 ASSERT_EQ(0, finished_cond.wait());
160 ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 64, 4096));
161 }
162
163 TEST_F(TestMockCryptoLuksFormatRequest, ImageTooSmall) {
164 auto mock_format_request = MockFormatRequest::create(
165 mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS2,
166 RBD_ENCRYPTION_ALGORITHM_AES256, std::move(passphrase), &crypto,
167 on_finish, true);
168 expect_get_object_size();
169 expect_get_image_size(1024*1024);
170 mock_format_request->send();
171 ASSERT_EQ(-ENOSPC, finished_cond.wait());
172 }
173
174 TEST_F(TestMockCryptoLuksFormatRequest, WriteFail) {
175 auto mock_format_request = MockFormatRequest::create(
176 mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS2,
177 RBD_ENCRYPTION_ALGORITHM_AES256, std::move(passphrase), &crypto,
178 on_finish, true);
179 expect_get_object_size();
180 expect_get_image_size(IMAGE_SIZE);
181 expect_image_write();
182 mock_format_request->send();
183 ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
184 complete_aio(-123);
185 ASSERT_EQ(-123, finished_cond.wait());
186 }
187
188 } // namespace luks
189 } // namespace crypto
190 } // namespace librbd