| // Copyright 2021 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <flasher/device.hpp> |
| #include <flasher/device/mock.hpp> |
| |
| #include <utility> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| namespace flasher |
| { |
| |
| TEST(OpenDevice, Missing) |
| { |
| ModArgs args(""); |
| args.arr.clear(); |
| EXPECT_THROW(openDevice(args), std::invalid_argument); |
| } |
| |
| TEST(OpenDevice, Invalid) |
| { |
| ModArgs args("invalid"); |
| EXPECT_THROW(openDevice(args), std::invalid_argument); |
| } |
| |
| TEST(OpenDevice, Valid) |
| { |
| ModArgs args("mtd,/dev/null"); |
| EXPECT_THROW(openDevice(args), std::system_error); |
| } |
| |
| TEST(Device, Type) |
| { |
| EXPECT_EQ(Device::Type::Nor, Device::toType("nor")); |
| EXPECT_EQ(Device::Type::Simple, Device::toType("simple")); |
| } |
| |
| TEST(Device, Nor) |
| { |
| EXPECT_THROW(device::Mock(Device::Type::Nor, 4097, 4096), |
| std::invalid_argument); |
| EXPECT_THROW(device::Mock(Device::Type::Nor, 8192, 0), |
| std::invalid_argument); |
| |
| device::Mock dev(Device::Type::Nor, 8192, 4096); |
| EXPECT_EQ(8192, dev.getSize()); |
| EXPECT_EQ(4096, dev.getEraseSize()); |
| |
| EXPECT_EQ(0, dev.eraseAlignStart(4095)); |
| EXPECT_EQ(4096, dev.eraseAlignStart(4096)); |
| EXPECT_EQ(4096, dev.eraseAlignStart(4097)); |
| EXPECT_EQ(4096, dev.eraseAlignStart(8191)); |
| |
| EXPECT_EQ(4096, dev.eraseAlignEnd(15)); |
| EXPECT_EQ(4096, dev.eraseAlignEnd(4095)); |
| EXPECT_EQ(4096, dev.eraseAlignEnd(4096)); |
| EXPECT_EQ(8192, dev.eraseAlignEnd(4097)); |
| EXPECT_EQ(8192, dev.eraseAlignEnd(8191)); |
| |
| EXPECT_FALSE(dev.needsErase({}, {})); |
| std::byte a[] = {std::byte{0x10}}; |
| std::byte b[] = {std::byte{0x30}}; |
| std::byte c[] = {std::byte{0x01}}; |
| EXPECT_THROW(dev.needsErase({}, a), std::invalid_argument); |
| EXPECT_TRUE(dev.needsErase(a, b)); |
| EXPECT_TRUE(dev.needsErase(c, a)); |
| EXPECT_TRUE(dev.needsErase(a, c)); |
| EXPECT_FALSE(dev.needsErase(b, b)); |
| EXPECT_FALSE(dev.needsErase(b, a)); |
| |
| EXPECT_EQ(1, dev.shrinkWritePre(a, b)); |
| EXPECT_EQ(0, dev.shrinkWritePre(b, a)); |
| EXPECT_EQ(0, dev.shrinkWritePost(a, b)); |
| EXPECT_EQ(1, dev.shrinkWritePost(b, a)); |
| std::byte d[] = {std::byte{0x30}, std::byte{0x10}}; |
| std::byte e[] = {std::byte{0x10}, std::byte{0x30}}; |
| std::byte f[] = {std::byte{0x50}, std::byte{0x50}}; |
| EXPECT_EQ(0, dev.shrinkWritePre(d, e)); |
| EXPECT_EQ(1, dev.shrinkWritePre(e, d)); |
| EXPECT_EQ(2, dev.shrinkWritePre(e, e)); |
| EXPECT_EQ(1, dev.shrinkWritePre(e, f)); |
| EXPECT_EQ(2, dev.shrinkWritePost(e, d)); |
| EXPECT_EQ(1, dev.shrinkWritePost(d, e)); |
| EXPECT_EQ(0, dev.shrinkWritePost(e, e)); |
| EXPECT_EQ(1, dev.shrinkWritePost(d, f)); |
| |
| dev.mockErase(a); |
| EXPECT_EQ(std::byte{0xff}, a[0]); |
| } |
| |
| TEST(Device, Simple) |
| { |
| EXPECT_THROW(device::Mock(Device::Type::Simple, 8192, 1), |
| std::invalid_argument); |
| device::Mock dev(Device::Type::Simple, 8192, 0); |
| EXPECT_EQ(8192, dev.getSize()); |
| EXPECT_EQ(0, dev.getEraseSize()); |
| |
| EXPECT_EQ(4095, dev.eraseAlignStart(4095)); |
| EXPECT_EQ(4096, dev.eraseAlignStart(4096)); |
| EXPECT_EQ(4097, dev.eraseAlignStart(4097)); |
| EXPECT_EQ(8191, dev.eraseAlignStart(8191)); |
| |
| EXPECT_EQ(15, dev.eraseAlignEnd(15)); |
| EXPECT_EQ(4095, dev.eraseAlignEnd(4095)); |
| EXPECT_EQ(4096, dev.eraseAlignEnd(4096)); |
| EXPECT_EQ(4097, dev.eraseAlignEnd(4097)); |
| EXPECT_EQ(8191, dev.eraseAlignEnd(8191)); |
| |
| EXPECT_FALSE(dev.needsErase({}, {})); |
| std::byte a[] = {std::byte{0x10}}; |
| std::byte b[] = {std::byte{0x01}}; |
| EXPECT_FALSE(dev.needsErase(b, b)); |
| EXPECT_FALSE(dev.needsErase(a, a)); |
| EXPECT_FALSE(dev.needsErase(a, b)); |
| |
| std::byte c[] = {std::byte{0x30}, std::byte{0x10}}; |
| std::byte d[] = {std::byte{0x30}, std::byte{0x11}}; |
| std::byte e[] = {std::byte{0x11}, std::byte{0x10}}; |
| EXPECT_EQ(0, dev.shrinkWritePre(c, e)); |
| EXPECT_EQ(1, dev.shrinkWritePre(c, d)); |
| EXPECT_EQ(2, dev.shrinkWritePre(c, c)); |
| EXPECT_EQ(2, dev.shrinkWritePost(c, d)); |
| EXPECT_EQ(1, dev.shrinkWritePost(c, e)); |
| EXPECT_EQ(0, dev.shrinkWritePost(c, c)); |
| |
| EXPECT_EQ(0, dev.shrinkWritePre(c, a)); |
| EXPECT_EQ(1, dev.shrinkWritePost(c, a)); |
| |
| dev.mockErase(a); |
| EXPECT_EQ(std::byte{0x10}, a[0]); |
| } |
| |
| } // namespace flasher |