| // Copyright 2024 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 "log_collector_util.hpp" |
| |
| #include <fmt/core.h> |
| |
| #include <vector> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| using google::hoth::internal::LogCollectorUtil; |
| using google::hoth::internal::RateLimiter; |
| using google::hoth::internal::RspHeader; |
| |
| class LogCollectorUtilTest : public ::testing::Test |
| { |
| protected: |
| LogCollectorUtilTest() : |
| rateLimiter(kRateLimiterMilliSeconds), |
| logCollectorUtil(rateLimiter, /*async wait time in seconds*/ 1) |
| {} |
| |
| RateLimiter rateLimiter; |
| LogCollectorUtil logCollectorUtil; |
| }; |
| |
| TEST_F(LogCollectorUtilTest, GenerateSnapshotRequest) |
| { |
| std::vector<uint8_t> expectedResponse = {0x03, 0x66, 0x97, 0x00, |
| 0x00, 0x00, 0x00, 0x00}; |
| std::vector<uint8_t> snapshotRequest = |
| google::hoth::internal::LogCollectorUtil::generateSnapshotRequest(); |
| |
| EXPECT_EQ(expectedResponse, snapshotRequest); |
| } |
| |
| TEST_F(LogCollectorUtilTest, GenerateGrabSnapshotRequest) |
| { |
| std::vector<uint8_t> expectedResponse = {0x03, 0x64, 0x98, 0x00, 0x00, |
| 0x00, 0x01, 0x00, 0x00}; |
| |
| std::vector<uint8_t> grabSnapshotRequest = |
| google::hoth::internal::LogCollectorUtil::generateGrabSnapshotRequest(); |
| |
| EXPECT_EQ(expectedResponse, grabSnapshotRequest); |
| } |
| |
| TEST_F(LogCollectorUtilTest, ValidResponseTest) |
| { |
| std::vector<uint8_t> validResponse = {0x03, 0xFD, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00}; |
| bool status = google::hoth::internal::LogCollectorUtil::isResponseValid( |
| validResponse); |
| EXPECT_EQ(true, status); |
| } |
| |
| TEST_F(LogCollectorUtilTest, InvalidResponseTest) |
| { |
| RspHeader rspHeader; |
| rspHeader.result = 1; // invalid response code |
| std::vector<uint8_t> invalidResponse(sizeof(RspHeader)); |
| std::memcpy(invalidResponse.data(), &rspHeader, sizeof(RspHeader)); |
| bool status = google::hoth::internal::LogCollectorUtil::isResponseValid( |
| invalidResponse); |
| EXPECT_EQ(false, status); |
| } |
| |
| TEST_F(LogCollectorUtilTest, RateLimiterAllow) |
| { |
| // No rate limit time |
| RateLimiter rateLimiter(0); |
| LogCollectorUtil logCollectorUtil(rateLimiter, |
| /*Async wait time in seconds*/ 1); |
| bool statusFirstRequest = logCollectorUtil.rateLimiter.allowedByLimiter(); |
| bool statusSecondRequest = logCollectorUtil.rateLimiter.allowedByLimiter(); |
| EXPECT_TRUE(statusFirstRequest); |
| EXPECT_TRUE(statusSecondRequest); |
| } |
| |
| TEST_F(LogCollectorUtilTest, RateLimiterForbids) |
| { |
| bool statusFirstRequest = logCollectorUtil.rateLimiter.allowedByLimiter(); |
| // send second request within 500 milliseconds |
| bool statusSecondRequest = logCollectorUtil.rateLimiter.allowedByLimiter(); |
| EXPECT_TRUE(statusFirstRequest); |
| EXPECT_FALSE(statusSecondRequest); |
| } |
| |
| TEST_F(LogCollectorUtilTest, GenerateUniqueRequestId) |
| { |
| int requestIdOne = logCollectorUtil.generateRequestId(); |
| int requestIdTwo = logCollectorUtil.generateRequestId(); |
| fmt::println(stderr, "{}, {}", requestIdOne, requestIdTwo); |
| } |
| |
| TEST_F(LogCollectorUtilTest, GenerateGetChannelWriteOffsetRequest) |
| { |
| std::vector<uint8_t> expectedRequest = {0x03, 0x53, 0x37, 0x3E, 0x00, 0x00, |
| 0x04, 0x00, 0x43, 0x55, 0x4e, 0x4b}; |
| std::vector<uint8_t> request = google::hoth::internal::LogCollectorUtil:: |
| generateGetChannelWriteOffsetRequest(0x4b4e5543); |
| EXPECT_EQ(request, expectedRequest); |
| } |
| |
| TEST_F(LogCollectorUtilTest, ParseChannelOffsetResponse) |
| { |
| std::vector<uint8_t> writechannelOffsetResponse = { |
| 0x03, 0x37, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x52, 0x44, 0x11, 0x1b}; |
| |
| uint32_t expectedOffset = 0x1b114452; |
| |
| EXPECT_EQ(true, |
| logCollectorUtil.isResponseValid(writechannelOffsetResponse)); |
| struct ec_channel_status_response* channelWriteOffsetResp = |
| reinterpret_cast<struct ec_channel_status_response*>( |
| &writechannelOffsetResponse[sizeof(struct RspHeader)]); |
| little_uint32_t writeOffset = channelWriteOffsetResp->write_offset; |
| EXPECT_EQ(expectedOffset, writeOffset); |
| } |
| |
| TEST_F(LogCollectorUtilTest, GenerateUartLogCollectorRequest) |
| { |
| std::vector<uint8_t> expectedRequest = { |
| 0x03, 0x97, 0x36, 0x3e, 0x00, 0x00, 0x10, 0x00, 0x43, 0x55, 0x4e, 0x4b, |
| 0x52, 0x44, 0x11, 0x1b, 0x00, 0x04, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00}; |
| uint32_t offset = 0x1b114452; |
| std::vector<uint8_t> requestGenerated = google::hoth::internal:: |
| LogCollectorUtil::generateCollectUartLogsRequest(0x4b4e5543, offset); |
| EXPECT_EQ(expectedRequest, requestGenerated); |
| } |
| |
| TEST_F(LogCollectorUtilTest, ParseUartLogCollectorResponse) |
| { |
| std::vector<uint8_t> response = { |
| 0x03, 0x2a, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xda, 0x84, 0x30, 0x1b, |
| 0x78, 0x3a, 0x38, 0x0a, 0x5b, 0x4d, 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, |
| 0x42, 0x45, 0x43, 0x34, 0x41, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, |
| 0x45, 0x52, 0x52, 0x20, 0x53, 0x4d, 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, |
| 0x20, 0x0a, 0x5b, 0x4d, 0x33, 0x31, 0x2d, 0x36, 0x36, 0x36, 0x42, 0x46, |
| 0x45, 0x34, 0x37, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52, |
| 0x52, 0x20, 0x53, 0x4d, 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, 0x20, 0x0a, |
| 0x5b, 0x4d, 0x33, 0x31, 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, 0x36, 0x30, |
| 0x46, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52, 0x52, 0x20, |
| 0x53, 0x4d, 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, 0x20, 0x0a, 0x5b, 0x4d, |
| 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, 0x36, 0x31, 0x37, 0x2d, |
| 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52, 0x52, 0x20, 0x53, 0x4d, |
| 0x42, 0x43, 0x4e, 0x3a, 0x33, 0x35, 0x20, 0x0a, 0x5b, 0x4d, 0x33, 0x30, |
| 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, 0x36, 0x33, 0x30, 0x2d, 0x4e, 0x5d, |
| 0x20, 0x67, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x6a, 0x5f, 0x73, 0x71, 0x65, |
| 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x63, 0x74, 0x78, 0x2e, 0x74, 0x61, |
| 0x69, 0x6c, 0x3a, 0x31, 0x34, 0x2c, 0x20, 0x68, 0x65, 0x61, 0x64, 0x3a, |
| 0x31, 0x34, 0x0a, 0x5b, 0x4d, 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, 0x43, |
| 0x30, 0x36, 0x34, 0x32, 0x2d, 0x41, 0x5d, 0x20, 0x4d, 0x61, 0x73, 0x74, |
| 0x65, 0x72, 0x20, 0x41, 0x52, 0x42, 0x4c, 0x4f, 0x53, 0x54, 0x20, 0x3a, |
| 0x35, 0x0a, 0x5b, 0x4d, 0x33, 0x30, 0x2d, 0x36, 0x36, 0x36, 0x43, 0x30, |
| 0x36, 0x34, 0x32, 0x2d, 0x45, 0x5d, 0x20, 0x4d, 0x3a, 0x20, 0x45, 0x52, |
| 0x52, 0x3a, 0x20, 0x49, 0x4e, 0x43, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x3a, |
| 0x34, 0x30, 0x2c, 0x20, 0x6e, 0x4e, 0x3a, 0x20, 0x32, 0x0a, 0}; |
| |
| uint32_t expectedOffset = 11038; |
| std::span<const uint8_t> output = response; |
| const auto& readResponseBody = |
| stdplus::raw::copyFrom<ec_channel_read_response>(output); |
| uint32_t readOffset = readResponseBody.offset + |
| (output.size() - sizeof(ec_channel_read_response)); |
| EXPECT_EQ(expectedOffset, readOffset); |
| } |