| Lei YU | 9ab6d75 | 2019-10-28 17:03:20 +0800 | [diff] [blame] | 1 | /** | 
 | 2 |  * Copyright © 2019 IBM Corporation | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 | #include "../updater.hpp" | 
| Shawn McCarney | b1216b9 | 2020-01-21 15:22:32 -0600 | [diff] [blame] | 17 | #include "mocked_i2c_interface.hpp" | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 18 |  | 
 | 19 | #include <filesystem> | 
| Lei YU | 9ab6d75 | 2019-10-28 17:03:20 +0800 | [diff] [blame] | 20 |  | 
 | 21 | #include <gtest/gtest.h> | 
 | 22 |  | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 23 | namespace fs = std::filesystem; | 
 | 24 |  | 
 | 25 | using ::testing::_; | 
 | 26 | using ::testing::An; | 
| Lei YU | 34fb8bd | 2019-11-07 14:24:20 +0800 | [diff] [blame] | 27 | using ::testing::Pointee; | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 28 |  | 
| Lei YU | 9ab6d75 | 2019-10-28 17:03:20 +0800 | [diff] [blame] | 29 | namespace updater | 
 | 30 | { | 
 | 31 | namespace internal | 
 | 32 | { | 
 | 33 |  | 
 | 34 | std::string getDeviceName(std::string devPath); | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 35 | std::pair<uint8_t, uint8_t> parseDeviceName(const std::string& devName); | 
| Lei YU | 9ab6d75 | 2019-10-28 17:03:20 +0800 | [diff] [blame] | 36 |  | 
 | 37 | } // namespace internal | 
 | 38 | } // namespace updater | 
 | 39 |  | 
 | 40 | using namespace updater; | 
 | 41 |  | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 42 | class TestUpdater : public ::testing::Test | 
 | 43 | { | 
 | 44 |   public: | 
 | 45 |     using MockedI2CInterface = i2c::MockedI2CInterface; | 
 | 46 |     using I2CInterface = i2c::I2CInterface; | 
 | 47 |  | 
 | 48 |     TestUpdater() | 
 | 49 |     { | 
 | 50 |         setupDeviceSysfs(); | 
 | 51 |     } | 
 | 52 |     ~TestUpdater() | 
 | 53 |     { | 
 | 54 |         fs::remove_all(tmpDir); | 
 | 55 |     } | 
 | 56 |  | 
 | 57 |     void setupDeviceSysfs() | 
 | 58 |     { | 
 | 59 |         auto tmpPath = fs::temp_directory_path(); | 
 | 60 |         tmpDir = (tmpPath / "test_XXXXXX"); | 
 | 61 |         if (!mkdtemp(tmpDir.data())) | 
 | 62 |         { | 
 | 63 |             throw "Failed to create temp dir"; | 
 | 64 |         } | 
 | 65 |         // Create device path with symbol link | 
 | 66 |         realDevicePath = fs::path(tmpDir) / "devices/3-0068"; | 
 | 67 |         devPath = fs::path(tmpDir) / "i2c"; | 
 | 68 |         fs::create_directories(realDevicePath); | 
 | 69 |         fs::create_directories(realDevicePath / "driver"); | 
 | 70 |         fs::create_directories(devPath); | 
 | 71 |         devPath /= "3-0068"; | 
 | 72 |         fs::create_directory_symlink(realDevicePath, devPath); | 
 | 73 |     } | 
 | 74 |  | 
 | 75 |     MockedI2CInterface& getMockedI2c() | 
 | 76 |     { | 
 | 77 |         return *reinterpret_cast<MockedI2CInterface*>(updater->i2c.get()); | 
 | 78 |     } | 
 | 79 |  | 
 | 80 |     std::shared_ptr<I2CInterface> stolenI2C; | 
 | 81 |     std::unique_ptr<Updater> updater; | 
 | 82 |     fs::path realDevicePath; | 
 | 83 |     fs::path devPath; | 
 | 84 |     std::string tmpDir; | 
 | 85 |     std::string psuInventoryPath = "/com/example/psu"; | 
 | 86 |     std::string imageDir = "/tmp/image/xxx"; | 
 | 87 | }; | 
 | 88 |  | 
 | 89 | TEST_F(TestUpdater, ctordtor) | 
 | 90 | { | 
 | 91 |     updater = std::make_unique<Updater>(psuInventoryPath, devPath, imageDir); | 
 | 92 | } | 
 | 93 |  | 
 | 94 | TEST_F(TestUpdater, doUpdate) | 
 | 95 | { | 
 | 96 |     updater = std::make_unique<Updater>(psuInventoryPath, devPath, imageDir); | 
 | 97 |     updater->createI2CDevice(); | 
 | 98 |     auto& i2c = getMockedI2c(); | 
| Lei YU | 34fb8bd | 2019-11-07 14:24:20 +0800 | [diff] [blame] | 99 |  | 
| Lei YU | 1d10342 | 2019-11-29 14:00:02 +0800 | [diff] [blame] | 100 |     EXPECT_CALL(i2c, write(0xf0, 12, _, I2CInterface::Mode::SMBUS)); | 
| Lei YU | 34fb8bd | 2019-11-07 14:24:20 +0800 | [diff] [blame] | 101 |     EXPECT_CALL(i2c, write(0xf1, An<uint8_t>())); | 
 | 102 |     EXPECT_CALL(i2c, read(0xf1, An<uint8_t&>())); | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 103 |     updater->doUpdate(); | 
 | 104 | } | 
 | 105 |  | 
 | 106 | TEST_F(TestUpdater, getDeviceName) | 
| Lei YU | 9ab6d75 | 2019-10-28 17:03:20 +0800 | [diff] [blame] | 107 | { | 
 | 108 |     auto ret = internal::getDeviceName(""); | 
 | 109 |     EXPECT_TRUE(ret.empty()); | 
 | 110 |  | 
 | 111 |     ret = internal::getDeviceName("/sys/bus/i2c/devices/3-0069"); | 
 | 112 |     EXPECT_EQ("3-0069", ret); | 
 | 113 |  | 
 | 114 |     ret = internal::getDeviceName("/sys/bus/i2c/devices/3-0069/"); | 
 | 115 |     EXPECT_EQ("3-0069", ret); | 
 | 116 | } | 
| Lei YU | 7c2fbbb | 2019-11-06 14:56:02 +0800 | [diff] [blame] | 117 |  | 
 | 118 | TEST_F(TestUpdater, parseDeviceName) | 
 | 119 | { | 
 | 120 |     auto [id, addr] = internal::parseDeviceName("3-0068"); | 
 | 121 |     EXPECT_EQ(3, id); | 
 | 122 |     EXPECT_EQ(0x68, addr); | 
 | 123 |  | 
 | 124 |     std::tie(id, addr) = internal::parseDeviceName("11-0069"); | 
 | 125 |     EXPECT_EQ(11, id); | 
 | 126 |     EXPECT_EQ(0x69, addr); | 
 | 127 |  | 
 | 128 |     EXPECT_THROW(internal::parseDeviceName("no-number"), std::invalid_argument); | 
 | 129 |  | 
 | 130 |     EXPECT_DEATH(internal::parseDeviceName("invalid"), ""); | 
 | 131 | } |