blob: 7cd2d523c8ca0029def7210a45a1777a1c4d22e1 [file] [edit]
/*
* SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION &
* AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
/**
* Branch coverage for platform-environmental.c — batch 4.
*
* Targets:
* L2794 decode_get_clock_limit_req: hdr.data_size < sizeof(clock_id)
* L2919 decode_get_curr_clock_freq_req: same
* L2982 decode_get_curr_clock_freq_resp: command != expected
* L2988 decode_get_curr_clock_freq_resp: data_size < sizeof(uint32_t)
* L3903 decode_set_clock_limit_req: msg_len != expected
* L3911 decode_set_clock_limit_req: hdr.data_size != expected
* L3991 decode_nsm_xid_event: msg_len too short
* L4094 decode_get_supported_gpm_metrics_resp: NULL bitmask arg
* L4128 decode_get_supported_gpm_metrics_resp: msg_len too short
* L4152 decode_get_supported_gpm_metrics_resp: data_size < min_data_size
* L4168 encode_query_aggregate_gpm_metrics_req: pack_nsm_header fail
* L4219 decode_query_aggregate_gpm_metrics_req: NULL args
* L4225 decode_query_aggregate_gpm_metrics_req: msg_len too short
* L4233 decode_query_aggregate_gpm_metrics_req: hdr.data_size too small
*/
#include "base.h"
#include "platform-environmental.h"
#include <gtest/gtest.h>
#include <vector>
// ===========================================================================
// L2794 TRUE: decode_get_clock_limit_req — hdr.data_size=0 < sizeof(clock_id)
// No decode_common_req in this function; zero-filled buffer is fine.
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetClockLimitReq_DataSizeTooSmall)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_get_clock_limit_req);
std::vector<uint8_t> buf(msgLen, 0);
// hdr.data_size = 0 (default) < sizeof(clock_id) = 1
uint8_t clock_id = 0;
auto rc = decode_get_clock_limit_req(
reinterpret_cast<const nsm_msg *>(buf.data()), msgLen, &clock_id);
EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}
// ===========================================================================
// L2919 TRUE: decode_get_curr_clock_freq_req — hdr.data_size=0 <
// sizeof(clock_id)
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetCurrClockFreqReq_DataSizeTooSmall)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_get_curr_clock_freq_req);
std::vector<uint8_t> buf(msgLen, 0);
// hdr.data_size = 0 < sizeof(clock_id) = 1
uint8_t clock_id = 0;
auto rc = decode_get_curr_clock_freq_req(
reinterpret_cast<const nsm_msg *>(buf.data()), msgLen, &clock_id);
EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}
// ===========================================================================
// L2982 TRUE: decode_get_curr_clock_freq_resp — command !=
// NSM_GET_CURRENT_CLOCK_FREQUENCY Uses zero-filled buffer of exact size; cc=0
// (NSM_SUCCESS), command=0 != 0x0B
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetCurrClockFreqResp_CommandMismatch)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_get_curr_clock_freq_resp);
std::vector<uint8_t> buf(msgLen, 0);
// payload[1] = cc = 0 (NSM_SUCCESS), payload[0] = command = 0 != 0x0B
uint8_t cc = 0;
uint16_t data_size = 0, reason_code = 0;
uint32_t freq = 0;
auto rc = decode_get_curr_clock_freq_resp(
reinterpret_cast<const nsm_msg *>(buf.data()), msgLen, &cc,
&data_size, &reason_code, &freq);
EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}
// ===========================================================================
// L2988 TRUE: decode_get_curr_clock_freq_resp — data_size < sizeof(uint32_t)
// Encode a valid resp, then corrupt hdr.data_size to 0.
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetCurrClockFreqResp_DataSizeTooSmall)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_get_curr_clock_freq_resp);
std::vector<uint8_t> buf(msgLen, 0);
auto *msg = reinterpret_cast<nsm_msg *>(buf.data());
uint32_t freq_in = 1000;
encode_get_curr_clock_freq_resp(0, NSM_SUCCESS, 0, &freq_in, msg);
// Corrupt data_size in nsm_common_resp to 0 (< sizeof(uint32_t)=4)
auto *resp =
reinterpret_cast<nsm_get_curr_clock_freq_resp *>(msg->payload);
resp->hdr.data_size = 0;
uint8_t cc = 0;
uint16_t data_size = 0, reason_code = 0;
uint32_t freq_out = 0;
auto rc = decode_get_curr_clock_freq_resp(
reinterpret_cast<const nsm_msg *>(msg), msgLen, &cc, &data_size,
&reason_code, &freq_out);
EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}
// ===========================================================================
// L3903 TRUE: decode_set_clock_limit_req — msg_len != expected
// ===========================================================================
TEST(PlatEnvBranch4, DecodeSetClockLimitReq_WrongMsgLen)
{
const size_t correctLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_set_clock_limit_req);
std::vector<uint8_t> buf(correctLen, 0);
uint8_t clock_id = 0, flags = 0;
uint32_t lmin = 0, lmax = 0;
// Pass correctLen - 1 to trigger != check
auto rc = decode_set_clock_limit_req(
reinterpret_cast<const nsm_msg *>(buf.data()), correctLen - 1,
&clock_id, &flags, &lmin, &lmax);
EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}
// ===========================================================================
// L3911 TRUE: decode_set_clock_limit_req — hdr.data_size != expected
// Correct msg_len but data_size = 0
// ===========================================================================
TEST(PlatEnvBranch4, DecodeSetClockLimitReq_WrongDataSize)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_set_clock_limit_req);
std::vector<uint8_t> buf(msgLen, 0);
// hdr.data_size = 0 (default) != expected non-zero value
uint8_t clock_id = 0, flags = 0;
uint32_t lmin = 0, lmax = 0;
auto rc = decode_set_clock_limit_req(
reinterpret_cast<const nsm_msg *>(buf.data()), msgLen, &clock_id,
&flags, &lmin, &lmax);
EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}
// ===========================================================================
// L3991 TRUE: decode_nsm_xid_event — msg_len < nsm_msg_hdr + NSM_EVENT_MIN_LEN
// ===========================================================================
TEST(PlatEnvBranch4, DecodeNsmXidEvent_MsgTooShort)
{
// NSM_EVENT_MIN_LEN=6; minimum would be 11; use 5 bytes (only header)
std::vector<uint8_t> buf(5, 0);
uint8_t event_class = 0;
uint16_t event_state = 0;
nsm_xid_event_payload payload{};
char msg_text[64] = {};
size_t msg_text_size = sizeof(msg_text);
auto rc = decode_nsm_xid_event(
reinterpret_cast<const nsm_msg *>(buf.data()), buf.size(),
&event_class, &event_state, &payload, msg_text, &msg_text_size);
EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}
// ===========================================================================
// L4094 TRUE: decode_get_supported_gpm_metrics_resp — NULL bitmask arg
// cc=NSM_SUCCESS (payload[1]=0); buf large enough for decode_common_resp
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetSupportedGpmMetricsResp_NullBitmask)
{
// Size: nsm_msg_hdr(5) + nsm_common_resp(6) = 11, cc=0, data_size=4
std::vector<uint8_t> buf(11, 0);
buf[sizeof(nsm_msg_hdr) + 4] = 4; // data_size = 4 (>= min_data_size)
uint8_t cc = 0;
uint16_t reason_code = 0, mask_size = 0, max_metrics = 0;
uint16_t bitmask_size = 0;
auto rc = decode_get_supported_gpm_metrics_resp(
reinterpret_cast<const nsm_msg *>(buf.data()), buf.size(), &cc,
&reason_code, &mask_size, &max_metrics, nullptr, &bitmask_size);
EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}
// ===========================================================================
// L4128 TRUE: decode_get_supported_gpm_metrics_resp — msg_len too short
// cc=NSM_SUCCESS; NULL checks pass; but msg_len < min required
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetSupportedGpmMetricsResp_MsgTooShort)
{
// nsm_msg_hdr(5) + nsm_get_supported_gpm_metrics_resp-1 = 5+10 = 15
// Use 14 bytes (< 15) with cc=0, enough for decode_common_resp (>=11)
std::vector<uint8_t> buf(14, 0);
uint8_t cc = 0;
uint16_t reason_code = 0, mask_size = 0, max_metrics = 0;
uint16_t bitmask_size = 0;
uint8_t bitmask[64] = {};
auto rc = decode_get_supported_gpm_metrics_resp(
reinterpret_cast<const nsm_msg *>(buf.data()), buf.size(), &cc,
&reason_code, &mask_size, &max_metrics, bitmask, &bitmask_size);
EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}
// ===========================================================================
// L4152 TRUE: decode_get_supported_gpm_metrics_resp — data_size < min_data_size
// cc=NSM_SUCCESS; msg_len >= 15; data_size=0 < min_data_size(4)
// ===========================================================================
TEST(PlatEnvBranch4, DecodeGetSupportedGpmMetricsResp_DataSizeTooSmall)
{
// 15 bytes: nsm_msg_hdr(5) + nsm_get_supported_gpm_metrics_resp-1(10)
std::vector<uint8_t> buf(15, 0);
// cc=0 (NSM_SUCCESS), data_size=0 (payload[4..5]=0) < min_data_size=4
uint8_t cc = 0;
uint16_t reason_code = 0, mask_size = 0, max_metrics = 0;
uint16_t bitmask_size = 0;
uint8_t bitmask[64] = {};
auto rc = decode_get_supported_gpm_metrics_resp(
reinterpret_cast<const nsm_msg *>(buf.data()), buf.size(), &cc,
&reason_code, &mask_size, &max_metrics, bitmask, &bitmask_size);
EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}
// ===========================================================================
// L4168 TRUE: encode_query_aggregate_gpm_metrics_req — pack_nsm_header fail
// instance_id=32 > NSM_INSTANCE_MAX(31)
// ===========================================================================
TEST(PlatEnvBranch4, EncodeQueryAggregateGpmMetricsReq_PackFail)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_query_aggregate_gpm_metrics_req);
std::vector<uint8_t> buf(msgLen, 0);
auto *msg = reinterpret_cast<nsm_msg *>(buf.data());
uint8_t bitfield = 0;
auto rc = encode_query_aggregate_gpm_metrics_req(32, 0, 0, 0, &bitfield,
1, msg);
EXPECT_NE(rc, NSM_SW_SUCCESS);
}
// ===========================================================================
// L4219 TRUE: decode_query_aggregate_gpm_metrics_req — NULL args
// ===========================================================================
TEST(PlatEnvBranch4, DecodeQueryAggregateGpmMetricsReq_NullArgs)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_query_aggregate_gpm_metrics_req);
std::vector<uint8_t> buf(msgLen, 0);
const uint8_t *bitfield = nullptr;
size_t bfLen = 0;
auto rc = decode_query_aggregate_gpm_metrics_req(
reinterpret_cast<const nsm_msg *>(buf.data()), msgLen, nullptr,
nullptr, nullptr, &bitfield, &bfLen);
EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}
// ===========================================================================
// L4225 TRUE: decode_query_aggregate_gpm_metrics_req — msg_len too short
// ===========================================================================
TEST(PlatEnvBranch4, DecodeQueryAggregateGpmMetricsReq_MsgTooShort)
{
const size_t fullLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_query_aggregate_gpm_metrics_req);
std::vector<uint8_t> buf(fullLen, 0);
uint8_t src = 0, gpu = 0, ci = 0;
const uint8_t *bitfield = nullptr;
size_t bfLen = 0;
auto rc = decode_query_aggregate_gpm_metrics_req(
reinterpret_cast<const nsm_msg *>(buf.data()), fullLen - 1, &src,
&gpu, &ci, &bitfield, &bfLen);
EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}
// ===========================================================================
// L4233 TRUE: decode_query_aggregate_gpm_metrics_req — hdr.data_size too small
// Correct msg_len; hdr.data_size=0 < (sizeof(req)-sizeof(common_req))
// ===========================================================================
TEST(PlatEnvBranch4, DecodeQueryAggregateGpmMetricsReq_DataSizeTooSmall)
{
const size_t msgLen =
sizeof(nsm_msg_hdr) + sizeof(nsm_query_aggregate_gpm_metrics_req);
std::vector<uint8_t> buf(msgLen, 0);
// hdr.data_size=0 (default) < sizeof(req)-sizeof(nsm_common_req)
uint8_t src = 0, gpu = 0, ci = 0;
const uint8_t *bitfield = nullptr;
size_t bfLen = 0;
auto rc = decode_query_aggregate_gpm_metrics_req(
reinterpret_cast<const nsm_msg *>(buf.data()), msgLen, &src, &gpu,
&ci, &bitfield, &bfLen);
EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}