blob: b379f59cacc31f3c6bd67645c5a3b793b6589f12 [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 Broadbent7f2ab642021-11-11 21:00:38 -080013#include <system_error>
14
15#include <gmock/gmock-matchers.h>
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
18
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -080019namespace estoraged_test
20{
21
22using estoraged::Pattern;
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080023using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070024using testing::_;
25using testing::Invoke;
26using testing::Return;
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080027
28TEST(pattern, patternPass)
29{
John Edward Broadbent69786762022-01-21 14:16:23 -080030 std::string testFileName = "patternPass";
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080031 uint64_t size = 4096;
John Edward Broadbent69786762022-01-21 14:16:23 -080032 std::ofstream testFile;
33 testFile.open(testFileName,
34 std::ios::out | std::ios::binary | std::ios::trunc);
35 testFile.close();
36
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070037 stdplus::fd::Fd&& writeFd =
38 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly);
39
John Edward Broadbent69786762022-01-21 14:16:23 -080040 Pattern pass(testFileName);
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070041 EXPECT_NO_THROW(pass.writePattern(size, writeFd));
42
43 stdplus::fd::Fd&& readFd =
44 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly);
45
46 EXPECT_NO_THROW(pass.verifyPattern(size, readFd));
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080047}
48
49/* This test that pattern writes the correct number of bytes even if
50 * size of the drive is not divisable by the block size
51 */
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070052
John Edward Broadbent69786762022-01-21 14:16:23 -080053TEST(pattern, patternNotDivisible)
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080054{
John Edward Broadbent69786762022-01-21 14:16:23 -080055 std::string testFileName = "notDivisible";
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080056 uint64_t size = 4097;
57 // 4097 is not divisible by the block size, and we expect no errors
John Edward Broadbent69786762022-01-21 14:16:23 -080058 std::ofstream testFile;
59 testFile.open(testFileName,
60 std::ios::out | std::ios::binary | std::ios::trunc);
61 testFile.close();
62
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070063 stdplus::fd::Fd&& writeFd =
64 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly);
John Edward Broadbent69786762022-01-21 14:16:23 -080065 Pattern pass(testFileName);
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070066 EXPECT_NO_THROW(pass.writePattern(size, writeFd));
67
68 stdplus::fd::Fd&& readFd =
69 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly);
70 EXPECT_NO_THROW(pass.verifyPattern(size, readFd));
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080071}
72
73TEST(pattern, patternsDontMatch)
74{
John Edward Broadbent69786762022-01-21 14:16:23 -080075 std::string testFileName = "patternsDontMatch";
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080076 uint64_t size = 4096;
John Edward Broadbent69786762022-01-21 14:16:23 -080077 std::ofstream testFile;
78
79 Pattern pass(testFileName);
80
John Edward Broadbent7f2ab642021-11-11 21:00:38 -080081 int dummyValue = 88;
John Edward Broadbent69786762022-01-21 14:16:23 -080082 testFile.open(testFileName, std::ios::binary | std::ios::out);
Ed Tanous82897c32022-02-21 14:11:59 -080083 testFile.write((reinterpret_cast<const char*>(&dummyValue)),
84 sizeof(dummyValue));
John Edward Broadbent69786762022-01-21 14:16:23 -080085 testFile.close();
86
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070087 stdplus::fd::Fd&& writeFd =
88 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly);
89
90 EXPECT_NO_THROW(pass.writePattern(size - sizeof(dummyValue), writeFd));
91
92 stdplus::fd::Fd&& readFd =
93 stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly);
94
95 EXPECT_THROW(pass.verifyPattern(size, readFd), InternalFailure);
96}
97
John Edward Broadbentd6071fc2022-03-31 19:33:21 -070098TEST(pattern, shortReadWritePass)
99{
100 std::string testFileName = "testfile_shortRead";
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700101 uint64_t size = 4096;
John Edward Broadbent34a75f02022-04-14 18:59:40 -0700102 size_t shortSize = 128;
103 static auto shortData1 = std::vector<std::byte>(shortSize);
104 static auto shortData2 = std::vector<std::byte>(shortSize);
105 static auto restOfData = std::vector<std::byte>(size - shortSize * 2);
John Edward Broadbentd6071fc2022-03-31 19:33:21 -0700106 Pattern pass(testFileName);
107 stdplus::fd::FdMock mock;
108
109 testing::Sequence s;
110
111 // test write pattern with short blocks
112 EXPECT_CALL(mock, write(_))
113 .WillOnce(Invoke([](std::span<const std::byte> x) {
114 std::copy_n(x.begin(), shortData1.size(), shortData1.begin());
115 return shortData1;
116 }))
117 .RetiresOnSaturation();
118 EXPECT_CALL(mock, write(_))
119 .WillOnce(Invoke([](std::span<const std::byte> x) {
120 std::copy_n(x.begin(), restOfData.size(), restOfData.begin());
121 return restOfData;
122 }))
123 .RetiresOnSaturation();
124 EXPECT_CALL(mock, write(_))
125 .WillOnce(Invoke([](std::span<const std::byte> x) {
126 std::copy_n(x.begin(), shortData2.size(), shortData2.begin());
127 return shortData2;
128 }))
129 .RetiresOnSaturation();
130
131 // test read pattern
132 EXPECT_CALL(mock, read(_))
133 .WillOnce(Invoke([](nonstd::span<std::byte> x) {
134 std::copy_n(shortData1.begin(), shortData1.size(), x.data());
135 nonstd::span ret(shortData1);
136 return ret;
137 }))
138 .RetiresOnSaturation();
139
140 EXPECT_CALL(mock, read(_))
141 .WillOnce(Invoke([](nonstd::span<std::byte> x) {
142 std::copy_n(restOfData.begin(), restOfData.size(), x.data());
143 nonstd::span ret(restOfData);
144 return ret;
145 }))
146 .RetiresOnSaturation();
147
148 EXPECT_CALL(mock, read(_))
149 .WillOnce(Invoke([](nonstd::span<std::byte> x) {
150 std::copy_n(shortData2.begin(), shortData2.size(), x.data());
151 nonstd::span ret(shortData2);
152 return ret;
153 }))
154 .RetiresOnSaturation();
155
156 EXPECT_NO_THROW(pass.writePattern(size, mock));
157 EXPECT_NO_THROW(pass.verifyPattern(size, mock));
158}
159
160TEST(Zeros, shortReadWriteFail)
161{
162 std::string testFileName = "testfile_shortRead";
163
164 uint64_t size = 4096;
165 size_t shortSize = 128;
166 Pattern tryPattern(testFileName);
167 auto shortData = std::vector<std::byte>(shortSize, std::byte{0});
168 auto restOfData =
169 std::vector<std::byte>(size - shortSize * 3, std::byte{0});
170 // open the file and write none to it
171
172 stdplus::fd::FdMock mock;
173
174 // test writes
175 EXPECT_CALL(mock, write(_))
176 .WillOnce(Return(shortData))
177 .WillOnce(Return(shortData))
178 .WillOnce(Return(restOfData))
179 .WillOnce(Return(restOfData)); // return too much data!
180
181 EXPECT_THROW(tryPattern.writePattern(size, mock), InternalFailure);
182
183 // test reads
184 EXPECT_CALL(mock, read(_))
185 .WillOnce(Return(shortData))
186 .WillOnce(Return(shortData))
187 .WillOnce(Return(restOfData))
188 .WillOnce(Return(restOfData)); // return too much data!
189
190 EXPECT_THROW(tryPattern.verifyPattern(size, mock), InternalFailure);
191}
192
193TEST(pattern, driveIsSmaller)
194{
195 std::string testFileName = "testfile_driveIsSmaller";
196
197 uint64_t size = 4096;
198 Pattern tryPattern(testFileName);
199
200 stdplus::fd::FdMock mocks;
201 testing::InSequence s;
202
203 // test writes
204 EXPECT_CALL(mocks, write(_))
205 .Times(33)
206 .WillRepeatedly(Return(std::vector<std::byte>{}))
207 .RetiresOnSaturation();
208
209 EXPECT_THROW(tryPattern.writePattern(size, mocks), InternalFailure);
210
211 // test reads
212 EXPECT_CALL(mocks, read(_))
213 .Times(33)
214 .WillRepeatedly(Return(std::vector<std::byte>{}))
215 .RetiresOnSaturation();
216
217 EXPECT_THROW(tryPattern.verifyPattern(size, mocks), InternalFailure);
John Edward Broadbent7f2ab642021-11-11 21:00:38 -0800218}
John Edward Broadbentd3bfa7b2022-01-13 17:41:32 -0800219
220} // namespace estoraged_test