17f2ab643SJohn Edward Broadbent #include "estoraged_conf.hpp" 27f2ab643SJohn Edward Broadbent #include "pattern.hpp" 37f2ab643SJohn Edward Broadbent 47f2ab643SJohn Edward Broadbent #include <fcntl.h> 57f2ab643SJohn Edward Broadbent #include <unistd.h> 67f2ab643SJohn Edward Broadbent 77f2ab643SJohn Edward Broadbent #include <stdplus/fd/create.hpp> 8d6071fc2SJohn Edward Broadbent #include <stdplus/fd/gmock.hpp> 97f2ab643SJohn Edward Broadbent #include <stdplus/fd/managed.hpp> 107f2ab643SJohn Edward Broadbent #include <xyz/openbmc_project/Common/error.hpp> 117f2ab643SJohn Edward Broadbent 1269786761SJohn Edward Broadbent #include <fstream> 137f2ab643SJohn Edward Broadbent #include <system_error> 147f2ab643SJohn Edward Broadbent 157f2ab643SJohn Edward Broadbent #include <gmock/gmock-matchers.h> 167f2ab643SJohn Edward Broadbent #include <gmock/gmock.h> 177f2ab643SJohn Edward Broadbent #include <gtest/gtest.h> 187f2ab643SJohn Edward Broadbent 19d3bfa7bbSJohn Edward Broadbent namespace estoraged_test 20d3bfa7bbSJohn Edward Broadbent { 21d3bfa7bbSJohn Edward Broadbent 22d3bfa7bbSJohn Edward Broadbent using estoraged::Pattern; 237f2ab643SJohn Edward Broadbent using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 24d6071fc2SJohn Edward Broadbent using testing::_; 25d6071fc2SJohn Edward Broadbent using testing::Invoke; 26d6071fc2SJohn Edward Broadbent using testing::Return; 277f2ab643SJohn Edward Broadbent 287f2ab643SJohn Edward Broadbent TEST(pattern, patternPass) 297f2ab643SJohn Edward Broadbent { 3069786761SJohn Edward Broadbent std::string testFileName = "patternPass"; 317f2ab643SJohn Edward Broadbent uint64_t size = 4096; 3269786761SJohn Edward Broadbent std::ofstream testFile; 3369786761SJohn Edward Broadbent testFile.open(testFileName, 3469786761SJohn Edward Broadbent std::ios::out | std::ios::binary | std::ios::trunc); 3569786761SJohn Edward Broadbent testFile.close(); 3669786761SJohn Edward Broadbent 37d6071fc2SJohn Edward Broadbent stdplus::fd::Fd&& writeFd = 38d6071fc2SJohn Edward Broadbent stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly); 39d6071fc2SJohn Edward Broadbent 4069786761SJohn Edward Broadbent Pattern pass(testFileName); 41d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.writePattern(size, writeFd)); 42d6071fc2SJohn Edward Broadbent 43d6071fc2SJohn Edward Broadbent stdplus::fd::Fd&& readFd = 44d6071fc2SJohn Edward Broadbent stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly); 45d6071fc2SJohn Edward Broadbent 46d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.verifyPattern(size, readFd)); 477f2ab643SJohn Edward Broadbent } 487f2ab643SJohn Edward Broadbent 497f2ab643SJohn Edward Broadbent /* This test that pattern writes the correct number of bytes even if 507f2ab643SJohn Edward Broadbent * size of the drive is not divisable by the block size 517f2ab643SJohn Edward Broadbent */ 52d6071fc2SJohn Edward Broadbent 5369786761SJohn Edward Broadbent TEST(pattern, patternNotDivisible) 547f2ab643SJohn Edward Broadbent { 5569786761SJohn Edward Broadbent std::string testFileName = "notDivisible"; 567f2ab643SJohn Edward Broadbent uint64_t size = 4097; 577f2ab643SJohn Edward Broadbent // 4097 is not divisible by the block size, and we expect no errors 5869786761SJohn Edward Broadbent std::ofstream testFile; 5969786761SJohn Edward Broadbent testFile.open(testFileName, 6069786761SJohn Edward Broadbent std::ios::out | std::ios::binary | std::ios::trunc); 6169786761SJohn Edward Broadbent testFile.close(); 6269786761SJohn Edward Broadbent 63d6071fc2SJohn Edward Broadbent stdplus::fd::Fd&& writeFd = 64d6071fc2SJohn Edward Broadbent stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly); 6569786761SJohn Edward Broadbent Pattern pass(testFileName); 66d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.writePattern(size, writeFd)); 67d6071fc2SJohn Edward Broadbent 68d6071fc2SJohn Edward Broadbent stdplus::fd::Fd&& readFd = 69d6071fc2SJohn Edward Broadbent stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly); 70d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.verifyPattern(size, readFd)); 717f2ab643SJohn Edward Broadbent } 727f2ab643SJohn Edward Broadbent 737f2ab643SJohn Edward Broadbent TEST(pattern, patternsDontMatch) 747f2ab643SJohn Edward Broadbent { 7569786761SJohn Edward Broadbent std::string testFileName = "patternsDontMatch"; 767f2ab643SJohn Edward Broadbent uint64_t size = 4096; 7769786761SJohn Edward Broadbent std::ofstream testFile; 7869786761SJohn Edward Broadbent 7969786761SJohn Edward Broadbent Pattern pass(testFileName); 8069786761SJohn Edward Broadbent 817f2ab643SJohn Edward Broadbent int dummyValue = 88; 8269786761SJohn Edward Broadbent testFile.open(testFileName, std::ios::binary | std::ios::out); 8382897c35SEd Tanous testFile.write((reinterpret_cast<const char*>(&dummyValue)), 8482897c35SEd Tanous sizeof(dummyValue)); 8569786761SJohn Edward Broadbent testFile.close(); 8669786761SJohn Edward Broadbent 87d6071fc2SJohn Edward Broadbent stdplus::fd::Fd&& writeFd = 88d6071fc2SJohn Edward Broadbent stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::WriteOnly); 89d6071fc2SJohn Edward Broadbent 90d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.writePattern(size - sizeof(dummyValue), writeFd)); 91d6071fc2SJohn Edward Broadbent 92d6071fc2SJohn Edward Broadbent stdplus::fd::Fd&& readFd = 93d6071fc2SJohn Edward Broadbent stdplus::fd::open(testFileName, stdplus::fd::OpenAccess::ReadOnly); 94d6071fc2SJohn Edward Broadbent 95d6071fc2SJohn Edward Broadbent EXPECT_THROW(pass.verifyPattern(size, readFd), InternalFailure); 96d6071fc2SJohn Edward Broadbent } 97d6071fc2SJohn Edward Broadbent 98*34a75f05SJohn Edward Broadbent TEST(pattern, shortReadWritePass) 99*34a75f05SJohn Edward Broadbent { 100*34a75f05SJohn Edward Broadbent std::string testFileName = "testfile_shortRead"; 101d6071fc2SJohn Edward Broadbent uint64_t size = 4096; 102d6071fc2SJohn Edward Broadbent size_t shortSize = 128; 103d6071fc2SJohn Edward Broadbent static auto shortData1 = std::vector<std::byte>(shortSize); 104d6071fc2SJohn Edward Broadbent static auto shortData2 = std::vector<std::byte>(shortSize); 105d6071fc2SJohn Edward Broadbent static auto restOfData = std::vector<std::byte>(size - shortSize * 2); 106d6071fc2SJohn Edward Broadbent Pattern pass(testFileName); 107d6071fc2SJohn Edward Broadbent stdplus::fd::FdMock mock; 108d6071fc2SJohn Edward Broadbent 109d6071fc2SJohn Edward Broadbent testing::Sequence s; 110d6071fc2SJohn Edward Broadbent 111d6071fc2SJohn Edward Broadbent // test write pattern with short blocks 112d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, write(_)) 113d6071fc2SJohn Edward Broadbent .WillOnce(Invoke([](std::span<const std::byte> x) { 114d6071fc2SJohn Edward Broadbent std::copy_n(x.begin(), shortData1.size(), shortData1.begin()); 115d6071fc2SJohn Edward Broadbent return shortData1; 116d6071fc2SJohn Edward Broadbent })) 117d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 118d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, write(_)) 119d6071fc2SJohn Edward Broadbent .WillOnce(Invoke([](std::span<const std::byte> x) { 120d6071fc2SJohn Edward Broadbent std::copy_n(x.begin(), restOfData.size(), restOfData.begin()); 121d6071fc2SJohn Edward Broadbent return restOfData; 122d6071fc2SJohn Edward Broadbent })) 123d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 124d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, write(_)) 125d6071fc2SJohn Edward Broadbent .WillOnce(Invoke([](std::span<const std::byte> x) { 126d6071fc2SJohn Edward Broadbent std::copy_n(x.begin(), shortData2.size(), shortData2.begin()); 127d6071fc2SJohn Edward Broadbent return shortData2; 128d6071fc2SJohn Edward Broadbent })) 129d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 130d6071fc2SJohn Edward Broadbent 131d6071fc2SJohn Edward Broadbent // test read pattern 132d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, read(_)) 133d6071fc2SJohn Edward Broadbent .WillOnce(Invoke([](nonstd::span<std::byte> x) { 134d6071fc2SJohn Edward Broadbent std::copy_n(shortData1.begin(), shortData1.size(), x.data()); 135d6071fc2SJohn Edward Broadbent nonstd::span ret(shortData1); 136d6071fc2SJohn Edward Broadbent return ret; 137d6071fc2SJohn Edward Broadbent })) 138d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 139d6071fc2SJohn Edward Broadbent 140d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, read(_)) 141d6071fc2SJohn Edward Broadbent .WillOnce(Invoke([](nonstd::span<std::byte> x) { 142d6071fc2SJohn Edward Broadbent std::copy_n(restOfData.begin(), restOfData.size(), x.data()); 143d6071fc2SJohn Edward Broadbent nonstd::span ret(restOfData); 144d6071fc2SJohn Edward Broadbent return ret; 145d6071fc2SJohn Edward Broadbent })) 146d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 147d6071fc2SJohn Edward Broadbent 148d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, read(_)) 149d6071fc2SJohn Edward Broadbent .WillOnce(Invoke([](nonstd::span<std::byte> x) { 150d6071fc2SJohn Edward Broadbent std::copy_n(shortData2.begin(), shortData2.size(), x.data()); 151d6071fc2SJohn Edward Broadbent nonstd::span ret(shortData2); 152d6071fc2SJohn Edward Broadbent return ret; 153d6071fc2SJohn Edward Broadbent })) 154d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 155d6071fc2SJohn Edward Broadbent 156d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.writePattern(size, mock)); 157d6071fc2SJohn Edward Broadbent EXPECT_NO_THROW(pass.verifyPattern(size, mock)); 158d6071fc2SJohn Edward Broadbent } 159d6071fc2SJohn Edward Broadbent 160d6071fc2SJohn Edward Broadbent TEST(Zeros, shortReadWriteFail) 161d6071fc2SJohn Edward Broadbent { 162d6071fc2SJohn Edward Broadbent std::string testFileName = "testfile_shortRead"; 163d6071fc2SJohn Edward Broadbent 164d6071fc2SJohn Edward Broadbent uint64_t size = 4096; 165d6071fc2SJohn Edward Broadbent size_t shortSize = 128; 166d6071fc2SJohn Edward Broadbent Pattern tryPattern(testFileName); 167d6071fc2SJohn Edward Broadbent auto shortData = std::vector<std::byte>(shortSize, std::byte{0}); 168d6071fc2SJohn Edward Broadbent auto restOfData = 169d6071fc2SJohn Edward Broadbent std::vector<std::byte>(size - shortSize * 3, std::byte{0}); 170d6071fc2SJohn Edward Broadbent // open the file and write none to it 171d6071fc2SJohn Edward Broadbent 172d6071fc2SJohn Edward Broadbent stdplus::fd::FdMock mock; 173d6071fc2SJohn Edward Broadbent 174d6071fc2SJohn Edward Broadbent // test writes 175d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, write(_)) 176d6071fc2SJohn Edward Broadbent .WillOnce(Return(shortData)) 177d6071fc2SJohn Edward Broadbent .WillOnce(Return(shortData)) 178d6071fc2SJohn Edward Broadbent .WillOnce(Return(restOfData)) 179d6071fc2SJohn Edward Broadbent .WillOnce(Return(restOfData)); // return too much data! 180d6071fc2SJohn Edward Broadbent 181d6071fc2SJohn Edward Broadbent EXPECT_THROW(tryPattern.writePattern(size, mock), InternalFailure); 182d6071fc2SJohn Edward Broadbent 183d6071fc2SJohn Edward Broadbent // test reads 184d6071fc2SJohn Edward Broadbent EXPECT_CALL(mock, read(_)) 185d6071fc2SJohn Edward Broadbent .WillOnce(Return(shortData)) 186d6071fc2SJohn Edward Broadbent .WillOnce(Return(shortData)) 187d6071fc2SJohn Edward Broadbent .WillOnce(Return(restOfData)) 188d6071fc2SJohn Edward Broadbent .WillOnce(Return(restOfData)); // return too much data! 189d6071fc2SJohn Edward Broadbent 190d6071fc2SJohn Edward Broadbent EXPECT_THROW(tryPattern.verifyPattern(size, mock), InternalFailure); 191d6071fc2SJohn Edward Broadbent } 192d6071fc2SJohn Edward Broadbent 193d6071fc2SJohn Edward Broadbent TEST(pattern, driveIsSmaller) 194d6071fc2SJohn Edward Broadbent { 195d6071fc2SJohn Edward Broadbent std::string testFileName = "testfile_driveIsSmaller"; 196d6071fc2SJohn Edward Broadbent 197d6071fc2SJohn Edward Broadbent uint64_t size = 4096; 198d6071fc2SJohn Edward Broadbent Pattern tryPattern(testFileName); 199d6071fc2SJohn Edward Broadbent 200d6071fc2SJohn Edward Broadbent stdplus::fd::FdMock mocks; 201d6071fc2SJohn Edward Broadbent testing::InSequence s; 202d6071fc2SJohn Edward Broadbent 203d6071fc2SJohn Edward Broadbent // test writes 204d6071fc2SJohn Edward Broadbent EXPECT_CALL(mocks, write(_)) 205d6071fc2SJohn Edward Broadbent .Times(33) 206d6071fc2SJohn Edward Broadbent .WillRepeatedly(Return(std::vector<std::byte>{})) 207d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 208d6071fc2SJohn Edward Broadbent 209d6071fc2SJohn Edward Broadbent EXPECT_THROW(tryPattern.writePattern(size, mocks), InternalFailure); 210d6071fc2SJohn Edward Broadbent 211d6071fc2SJohn Edward Broadbent // test reads 212d6071fc2SJohn Edward Broadbent EXPECT_CALL(mocks, read(_)) 213d6071fc2SJohn Edward Broadbent .Times(33) 214d6071fc2SJohn Edward Broadbent .WillRepeatedly(Return(std::vector<std::byte>{})) 215d6071fc2SJohn Edward Broadbent .RetiresOnSaturation(); 216d6071fc2SJohn Edward Broadbent 217d6071fc2SJohn Edward Broadbent EXPECT_THROW(tryPattern.verifyPattern(size, mocks), InternalFailure); 2187f2ab643SJohn Edward Broadbent } 219d3bfa7bbSJohn Edward Broadbent 220d3bfa7bbSJohn Edward Broadbent } // namespace estoraged_test 221