blob: 6a475d587f806809dd1ecd7655d4c61b544f1c40 [file] [log] [blame]
John Edward Broadbent7f2ab642021-11-11 21:00:38 -08001#include "estoraged_conf.hpp"
2#include "pattern.hpp"
3
4#include <fcntl.h>
5#include <unistd.h>
6
7#include <stdplus/fd/create.hpp>
John Edward Broadbentd6071fc2022-03-31 19:33:21 -07008#include <stdplus/fd/gmock.hpp>
John Edward Broadbent7f2ab642021-11-11 21:00:38 -08009#include <stdplus/fd/managed.hpp>
10#include <xyz/openbmc_project/Common/error.hpp>
11
John Edward Broadbent69786762022-01-21 14:16:23 -080012#include <fstream>
John Edward Broadbent4906f4e2022-04-28 17:15:18 -070013#include <span>
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080014#include <system_error>
15
16#include <gmock/gmock-matchers.h>
17#include <gmock/gmock.h>
18#include <gtest/gtest.h>
19
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080020namespace estoraged_test
21{
22
23using estoraged::Pattern;
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080024using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070025using testing::_;
26using testing::Invoke;
27using testing::Return;
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080028
29TEST(pattern, patternPass)
30{
John Edward Broadbent69786762022-01-21 14:16:23 -080031 std::string testFileName = "patternPass";
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080032 uint64_t size = 4096;
John Edward Broadbent69786762022-01-21 14:16:23 -080033 std::ofstream testFile;
34 testFile.open(testFileName,
35 std::ios::out | std::ios::binary | std::ios::trunc);
36 testFile.close();
37
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070038 stdplus::fd::Fd&& writeFd =
39 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly);
40
John Edward Broadbent69786762022-01-21 14:16:23 -080041 Pattern pass(testFileName);
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070042 EXPECT_NO_THROW(pass.writePattern(size, writeFd));
43
44 stdplus::fd::Fd&& readFd =
45 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly);
46
47 EXPECT_NO_THROW(pass.verifyPattern(size, readFd));
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080048}
49
50/* This test that pattern writes the correct number of bytes even if
Manojkiran Edad4554f22024-06-17 14:11:30 +053051 * size of the drive is not divisible by the block size
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080052 */
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070053
John Edward Broadbent69786762022-01-21 14:16:23 -080054TEST(pattern, patternNotDivisible)
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080055{
John Edward Broadbent69786762022-01-21 14:16:23 -080056 std::string testFileName = "notDivisible";
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080057 uint64_t size = 4097;
58 // 4097 is not divisible by the block size, and we expect no errors
John Edward Broadbent69786762022-01-21 14:16:23 -080059 std::ofstream testFile;
60 testFile.open(testFileName,
61 std::ios::out | std::ios::binary | std::ios::trunc);
62 testFile.close();
63
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070064 stdplus::fd::Fd&& writeFd =
65 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly);
John Edward Broadbent69786762022-01-21 14:16:23 -080066 Pattern pass(testFileName);
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070067 EXPECT_NO_THROW(pass.writePattern(size, writeFd));
68
69 stdplus::fd::Fd&& readFd =
70 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly);
71 EXPECT_NO_THROW(pass.verifyPattern(size, readFd));
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080072}
73
74TEST(pattern, patternsDontMatch)
75{
John Edward Broadbent69786762022-01-21 14:16:23 -080076 std::string testFileName = "patternsDontMatch";
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080077 uint64_t size = 4096;
John Edward Broadbent69786762022-01-21 14:16:23 -080078 std::ofstream testFile;
79
80 Pattern pass(testFileName);
81
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080082 int dummyValue = 88;
John Edward Broadbent69786762022-01-21 14:16:23 -080083 testFile.open(testFileName, std::ios::binary | std::ios::out);
Ed Tanous82897c32022-02-21 14:11:59 -080084 testFile.write((reinterpret_cast<const char*>(&dummyValue)),
85 sizeof(dummyValue));
John Edward Broadbent69786762022-01-21 14:16:23 -080086 testFile.close();
87
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070088 stdplus::fd::Fd&& writeFd =
89 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly);
90
91 EXPECT_NO_THROW(pass.writePattern(size - sizeof(dummyValue), writeFd));
92
93 stdplus::fd::Fd&& readFd =
94 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly);
95
96 EXPECT_THROW(pass.verifyPattern(size, readFd), InternalFailure);
97}
98
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070099TEST(pattern, shortReadWritePass)
100{
101 std::string testFileName = "testfile_shortRead";
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700102 uint64_t size = 4096;
John Edward Broadbent34a75f02022-04-14 18:59:40 -0700103 size_t shortSize = 128;
104 static auto shortData1 = std::vector<std::byte>(shortSize);
105 static auto shortData2 = std::vector<std::byte>(shortSize);
106 static auto restOfData = std::vector<std::byte>(size - shortSize * 2);
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700107 Pattern pass(testFileName);
108 stdplus::fd::FdMock mock;
109
110 testing::Sequence s;
111
112 // test write pattern with short blocks
113 EXPECT_CALL(mock, write(_))
114 .WillOnce(Invoke([](std::span<const std::byte> x) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400115 std::copy_n(x.begin(), shortData1.size(), shortData1.begin());
116 return shortData1;
117 }))
118 .RetiresOnSaturation();
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700119 EXPECT_CALL(mock, write(_))
120 .WillOnce(Invoke([](std::span<const std::byte> x) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400121 std::copy_n(x.begin(), restOfData.size(), restOfData.begin());
122 return restOfData;
123 }))
124 .RetiresOnSaturation();
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700125 EXPECT_CALL(mock, write(_))
126 .WillOnce(Invoke([](std::span<const std::byte> x) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400127 std::copy_n(x.begin(), shortData2.size(), shortData2.begin());
128 return shortData2;
129 }))
130 .RetiresOnSaturation();
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700131
132 // test read pattern
133 EXPECT_CALL(mock, read(_))
John Edward Broadbent4906f4e2022-04-28 17:15:18 -0700134 .WillOnce(Invoke([](std::span<std::byte> x) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400135 std::copy_n(shortData1.begin(), shortData1.size(), x.data());
136 std::span ret(shortData1);
137 return ret;
138 }))
139 .RetiresOnSaturation();
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700140
141 EXPECT_CALL(mock, read(_))
John Edward Broadbent4906f4e2022-04-28 17:15:18 -0700142 .WillOnce(Invoke([](std::span<std::byte> x) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400143 std::copy_n(restOfData.begin(), restOfData.size(), x.data());
144 std::span ret(restOfData);
145 return ret;
146 }))
147 .RetiresOnSaturation();
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700148
149 EXPECT_CALL(mock, read(_))
John Edward Broadbent4906f4e2022-04-28 17:15:18 -0700150 .WillOnce(Invoke([](std::span<std::byte> x) {
Patrick Williams15b63e12024-08-16 15:22:01 -0400151 std::copy_n(shortData2.begin(), shortData2.size(), x.data());
152 std::span ret(shortData2);
153 return ret;
154 }))
155 .RetiresOnSaturation();
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700156
157 EXPECT_NO_THROW(pass.writePattern(size, mock));
158 EXPECT_NO_THROW(pass.verifyPattern(size, mock));
159}
160
161TEST(Zeros, shortReadWriteFail)
162{
163 std::string testFileName = "testfile_shortRead";
164
165 uint64_t size = 4096;
166 size_t shortSize = 128;
167 Pattern tryPattern(testFileName);
168 auto shortData = std::vector<std::byte>(shortSize, std::byte{0});
Patrick Williams15b63e12024-08-16 15:22:01 -0400169 auto restOfData =
170 std::vector<std::byte>(size - shortSize * 3, std::byte{0});
John Wedigbe47c8f2022-09-30 16:40:08 -0700171 std::span shortDataSpan{shortData};
172 std::span restOfDataSpan{restOfData};
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700173 // open the file and write none to it
174
175 stdplus::fd::FdMock mock;
176
177 // test writes
178 EXPECT_CALL(mock, write(_))
John Wedigbe47c8f2022-09-30 16:40:08 -0700179 .WillOnce(Return(shortDataSpan))
180 .WillOnce(Return(shortDataSpan))
181 .WillOnce(Return(restOfDataSpan))
182 .WillOnce(Return(restOfDataSpan)); // return too much data!
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700183
184 EXPECT_THROW(tryPattern.writePattern(size, mock), InternalFailure);
185
186 // test reads
187 EXPECT_CALL(mock, read(_))
John Wedigbe47c8f2022-09-30 16:40:08 -0700188 .WillOnce(Return(shortDataSpan))
189 .WillOnce(Return(shortDataSpan))
190 .WillOnce(Return(restOfDataSpan))
191 .WillOnce(Return(restOfDataSpan)); // return too much data!
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700192
193 EXPECT_THROW(tryPattern.verifyPattern(size, mock), InternalFailure);
194}
195
196TEST(pattern, driveIsSmaller)
197{
198 std::string testFileName = "testfile_driveIsSmaller";
199
200 uint64_t size = 4096;
201 Pattern tryPattern(testFileName);
202
203 stdplus::fd::FdMock mocks;
204 testing::InSequence s;
205
206 // test writes
207 EXPECT_CALL(mocks, write(_))
208 .Times(33)
John Wedigbe47c8f2022-09-30 16:40:08 -0700209 .WillRepeatedly(Return(std::span<std::byte>{}))
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700210 .RetiresOnSaturation();
211
212 EXPECT_THROW(tryPattern.writePattern(size, mocks), InternalFailure);
213
214 // test reads
215 EXPECT_CALL(mocks, read(_))
216 .Times(33)
John Wedigbe47c8f2022-09-30 16:40:08 -0700217 .WillRepeatedly(Return(std::span<std::byte>{}))
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700218 .RetiresOnSaturation();
219
220 EXPECT_THROW(tryPattern.verifyPattern(size, mocks), InternalFailure);
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800221}
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -0800222
223} // namespace estoraged_test