blob: 35e344ce91b43265c02f7cbf3e2fcb0a397abba6 [file] [log] [blame]
// 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);
}