* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* MindIE is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <gtest/gtest.h>
#include <nlohmann/json.hpp>
#include "base64_util.h"
#include "basic_types.h"
#include "config_manager.h"
#include "config_manager/config_manager_impl.h"
#include "infer_param.h"
#include "mock_util.h"
#include "mockcpp/mockcpp.hpp"
#include "request.h"
using OrderedJson = nlohmann::ordered_json;
namespace mindie_llm {
MOCKER_CPP_OVERLOAD_EQ(ScheduleConfig)
MOCKER_CPP_OVERLOAD_EQ(ServerConfig)
class InferParamTest : public testing::Test {
protected:
InferParamTest() = default;
void SetUp() override {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj = OrderedJson::object();
inferParam = std::make_shared<InferParam>();
}
void TearDown() override { GlobalMockObject::verify(); }
RequestSPtr request;
InferParamSPtr inferParam;
std::string error;
OrderedJson jsonObj;
ScheduleConfig mockScheduleConfig_;
ServerConfig mockServerConfig_;
};
TEST_F(InferParamTest, testAssignDoSample) {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["do_sample"] = true;
EXPECT_EQ(AssignDoSample(jsonObj, request, error), true);
EXPECT_EQ(request->doSample.value(), true);
jsonObj["do_sample"] = false;
EXPECT_EQ(AssignDoSample(jsonObj, request, error), true);
EXPECT_EQ(request->doSample.value(), false);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["do_sample"] = "something-not-boolean";
EXPECT_EQ(AssignDoSample(jsonObj, request, error), false);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_EQ(AssignDoSample(jsonObj, request, error), true);
EXPECT_EQ(request->doSample.has_value(), false);
}
TEST_F(InferParamTest, testAssignRepetitionPenalty) {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["repetition_penalty"] = 1.0;
EXPECT_TRUE(AssignRepetitionPenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->repetitionPenalty.value(), 1.0);
jsonObj["repetition_penalty"] = 1.5;
EXPECT_TRUE(AssignRepetitionPenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->repetitionPenalty.value(), 1.5);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["repetition_penalty"] = 0.0;
EXPECT_FALSE(AssignRepetitionPenalty(jsonObj, request, error));
EXPECT_FALSE(request->repetitionPenalty.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["repetition_penalty"] = -1;
EXPECT_FALSE(AssignRepetitionPenalty(jsonObj, request, error));
EXPECT_FALSE(request->repetitionPenalty.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignRepetitionPenalty(jsonObj, request, error));
EXPECT_FALSE(request->repetitionPenalty.has_value());
}
TEST_F(InferParamTest, testAssignSeed) {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["seed"] = static_cast<uint64_t>(1234);
EXPECT_TRUE(AssignSeed(jsonObj, request, error));
EXPECT_EQ(request->seed, 1234);
jsonObj["seed"] = -1;
EXPECT_FALSE(AssignSeed(jsonObj, request, error));
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignSeed(jsonObj, request, error));
}
TEST_F(InferParamTest, testAssignStopStrings) {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["stop"] = {"stop", "end"};
EXPECT_TRUE(AssignStopStrings(jsonObj, request, error));
EXPECT_TRUE(request->stopStrings.has_value());
EXPECT_EQ(request->stopStrings.value(), Base64Util::Encode("[\"stop\",\"end\"]"));
jsonObj["stop"] = "stop";
EXPECT_TRUE(AssignStopStrings(jsonObj, request, error));
EXPECT_TRUE(request->stopStrings.has_value());
EXPECT_EQ(request->stopStrings.value(), Base64Util::Encode("[\"stop\"]"));
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["stop"] = {};
EXPECT_TRUE(AssignStopStrings(jsonObj, request, error));
EXPECT_FALSE(request->stopStrings.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["stop"] = "";
EXPECT_FALSE(AssignStopStrings(jsonObj, request, error));
EXPECT_FALSE(request->stopStrings.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["stop"] = std::string(48 * 1024, 'a');
EXPECT_FALSE(AssignStopStrings(jsonObj, request, error));
EXPECT_FALSE(request->stopStrings.has_value());
}
TEST_F(InferParamTest, testAssignPresencePenalty) {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["presence_penalty"] = 0.8;
EXPECT_TRUE(AssignPresencePenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->presencyPenalty.value(), 0.8);
jsonObj["presence_penalty"] = -2.0;
EXPECT_TRUE(AssignPresencePenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->presencyPenalty.value(), -2.0);
jsonObj["presence_penalty"] = 2.0;
EXPECT_TRUE(AssignPresencePenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->presencyPenalty.value(), 2.0);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["presence_penalty"] = 2.1;
EXPECT_FALSE(AssignPresencePenalty(jsonObj, request, error));
EXPECT_FALSE(request->presencyPenalty.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["presence_penalty"] = -2.1;
EXPECT_FALSE(AssignPresencePenalty(jsonObj, request, error));
EXPECT_FALSE(request->presencyPenalty.has_value());
}
TEST_F(InferParamTest, testAssignN) {
mockScheduleConfig_.maxBatchSize = 128;
mockScheduleConfig_.maxPrefillBatchSize = 128;
mockScheduleConfig_.maxN = 128;
MOCKER_CPP(GetScheduleConfig, const ScheduleConfig &(*)()).stubs().will(returnValue(mockScheduleConfig_));
MOCKER_CPP(GetServerConfig, const ServerConfig &(*)()).stubs().will(returnValue(mockServerConfig_));
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["n"] = static_cast<uint32_t>(2);
EXPECT_TRUE(AssignN(jsonObj, request, error));
EXPECT_TRUE(request->n.has_value());
EXPECT_EQ(request->n.value(), 2);
jsonObj["n"] = static_cast<uint32_t>(1);
EXPECT_TRUE(AssignN(jsonObj, request, error));
EXPECT_TRUE(request->n.has_value());
EXPECT_EQ(request->n.value(), 1);
jsonObj["n"] = static_cast<uint32_t>(128);
EXPECT_TRUE(AssignN(jsonObj, request, error));
EXPECT_TRUE(request->n.has_value());
EXPECT_EQ(request->n.value(), 128);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["n"] = 0;
EXPECT_FALSE(AssignN(jsonObj, request, error));
EXPECT_FALSE(request->n.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignN(jsonObj, request, error));
EXPECT_FALSE(request->n.has_value());
}
TEST_F(InferParamTest, testAssignBestOf) {
ServerConfig mockServerConfig;
MOCKER_CPP(GetServerConfig, const ServerConfig &(*)()).stubs().will(returnValue(mockServerConfig));
jsonObj["best_of"] = static_cast<uint32_t>(3);
EXPECT_TRUE(AssignBestOf(jsonObj, request, error));
EXPECT_TRUE(request->bestOf.has_value());
EXPECT_EQ(request->bestOf.value(), 3);
jsonObj["best_of"] = static_cast<uint32_t>(1);
EXPECT_TRUE(AssignBestOf(jsonObj, request, error));
EXPECT_TRUE(request->bestOf.has_value());
EXPECT_EQ(request->bestOf.value(), 1);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["best_of"] = 0;
EXPECT_FALSE(AssignBestOf(jsonObj, request, error));
EXPECT_FALSE(request->bestOf.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignBestOf(jsonObj, request, error));
EXPECT_FALSE(request->bestOf.has_value());
}
TEST_F(InferParamTest, testAssignFrequencyPenalty) {
jsonObj["frequency_penalty"] = 0.5;
EXPECT_TRUE(AssignFrequencyPenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->frequencyPenalty.value(), 0.5);
jsonObj["frequency_penalty"] = 2.0;
EXPECT_TRUE(AssignFrequencyPenalty(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->frequencyPenalty.value(), 2.0);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["frequency_penalty"] = 2.1;
EXPECT_FALSE(AssignFrequencyPenalty(jsonObj, request, error));
EXPECT_FALSE(request->frequencyPenalty.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignFrequencyPenalty(jsonObj, request, error));
EXPECT_FALSE(request->frequencyPenalty.has_value());
}
TEST_F(InferParamTest, testAssignTemperature) {
jsonObj["temperature"] = 0.7;
EXPECT_TRUE(AssignTemperature(jsonObj, request, error));
EXPECT_TRUE(request->temperature.has_value());
EXPECT_FLOAT_EQ(request->temperature.value(), 0.7);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["temperature"] = 0.0;
EXPECT_FALSE(AssignTemperature(jsonObj, request, error));
EXPECT_FALSE(request->temperature.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["temperature"] = 0.0;
EXPECT_TRUE(AssignTemperature(jsonObj, request, error, true));
EXPECT_TRUE(request->temperature.has_value());
EXPECT_FLOAT_EQ(request->temperature.value(), 0.0);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["temperature"] = 2.1;
EXPECT_TRUE(AssignTemperature(jsonObj, request, error));
EXPECT_TRUE(request->temperature.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignTemperature(jsonObj, request, error));
EXPECT_FALSE(request->temperature.has_value());
}
TEST_F(InferParamTest, testAssignTopK) {
jsonObj["top_k"] = 50;
EXPECT_TRUE(AssignTopK(jsonObj, request, error));
EXPECT_EQ(request->topK.value(), 50);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["top_k"] = 0;
EXPECT_FALSE(AssignTopK(jsonObj, request, error));
EXPECT_FALSE(request->topK.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["top_k"] = 0;
EXPECT_TRUE(AssignTopK(jsonObj, request, error, true));
EXPECT_EQ(request->topK.value(), 0);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["top_k"] = -1;
EXPECT_FALSE(AssignTopK(jsonObj, request, error));
EXPECT_FALSE(request->topK.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignTopK(jsonObj, request, error));
EXPECT_FALSE(request->topK.has_value());
}
TEST_F(InferParamTest, testAssignTopP) {
jsonObj["top_p"] = 0.9;
EXPECT_TRUE(AssignTopP(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->topP.value(), 0.9);
jsonObj["top_p"] = 1.0;
EXPECT_TRUE(AssignTopP(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->topP.value(), 1.0);
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["top_p"] = 1.1;
EXPECT_FALSE(AssignTopP(jsonObj, request, error));
EXPECT_FALSE(request->topP.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignTopP(jsonObj, request, error));
EXPECT_FALSE(request->topP.has_value());
}
TEST_F(InferParamTest, testAssignStopTokenIds) {
jsonObj["stop_token_ids"] = std::vector<int64_t>{1, 2, 3};
EXPECT_TRUE(AssignStopTokenIds(jsonObj, request, error));
EXPECT_TRUE(request->stopTokenIds.has_value());
EXPECT_EQ(request->stopTokenIds.value(), std::vector<int64_t>({1, 2, 3}));
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["stop_token_ids"] = "[1, 2, 3]";
EXPECT_FALSE(AssignStopTokenIds(jsonObj, request, error));
EXPECT_FALSE(request->stopTokenIds.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.erase("stop_token_ids");
EXPECT_TRUE(AssignStopTokenIds(jsonObj, request, error));
EXPECT_FALSE(request->stopTokenIds.has_value());
}
TEST_F(InferParamTest, testAssignStream) {
inferParam = std::make_shared<InferParam>();
jsonObj["stream"] = true;
EXPECT_TRUE(AssignStream(jsonObj, inferParam, error));
EXPECT_TRUE(inferParam->streamMode);
inferParam = std::make_shared<InferParam>();
jsonObj["stream"] = false;
EXPECT_TRUE(AssignStream(jsonObj, inferParam, error));
EXPECT_FALSE(inferParam->streamMode);
inferParam = std::make_shared<InferParam>();
jsonObj.erase("stream");
EXPECT_TRUE(AssignStream(jsonObj, inferParam, error));
EXPECT_FALSE(inferParam->streamMode);
inferParam = std::make_shared<InferParam>();
jsonObj["stream"] = "something-not-boolean";
EXPECT_FALSE(AssignStream(jsonObj, inferParam, error));
EXPECT_FALSE(inferParam->streamMode);
}
TEST_F(InferParamTest, testCheckMultimodalUrlFromJson) {
jsonObj = OrderedJson::array({{"image_url", "http://example.com/image.jpg"}});
EXPECT_TRUE(CheckMultimodalUrlFromJson(jsonObj, error));
EXPECT_TRUE(error.empty());
jsonObj = OrderedJson::array({{"video_url", "http://example.com/video.mp4"}});
EXPECT_TRUE(CheckMultimodalUrlFromJson(jsonObj, error));
EXPECT_TRUE(error.empty());
jsonObj = OrderedJson::array({{"audio_url", "http://example.com/audio.mp3"}});
EXPECT_TRUE(CheckMultimodalUrlFromJson(jsonObj, error));
EXPECT_TRUE(error.empty());
jsonObj = OrderedJson::array({{"image_url", "http://example.com/image1.jpg"},
{"video_url", "http://example.com/video1.mp4"},
{"audio_url", "http://example.com/audio1.mp3"}});
EXPECT_TRUE(CheckMultimodalUrlFromJson(jsonObj, error));
EXPECT_TRUE(error.empty());
jsonObj.clear();
EXPECT_TRUE(CheckMultimodalUrlFromJson(jsonObj, error));
EXPECT_TRUE(error.empty());
}
TEST_F(InferParamTest, testDoSample) {
jsonObj["do_sample"] = true;
EXPECT_TRUE(AssignDoSample(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->doSample.value(), true);
jsonObj["do_sample"] = "true";
EXPECT_FALSE(AssignDoSample(jsonObj, request, error));
}
TEST_F(InferParamTest, testTypicalP) {
jsonObj["typical_p"] = 0.9;
EXPECT_TRUE(AssignTypicalP(jsonObj, request, error));
EXPECT_FLOAT_EQ(request->typicalP.value(), 0.9);
jsonObj["typical_p"] = 1.1;
EXPECT_FALSE(AssignTypicalP(jsonObj, request, error));
}
TEST_F(InferParamTest, testAssignMaxNewTokens) {
inferParam = std::make_shared<InferParam>();
jsonObj["max_new_tokens"] = 100;
EXPECT_TRUE(AssignMaxNewTokens(jsonObj, inferParam, error));
EXPECT_EQ(inferParam->maxNewTokens, 100);
inferParam = std::make_shared<InferParam>();
jsonObj["max_new_tokens"] = -1;
EXPECT_FALSE(AssignMaxNewTokens(jsonObj, inferParam, error));
EXPECT_EQ(inferParam->maxNewTokens, MAX_NEW_TOKENS_DFT);
}
TEST_F(InferParamTest, testAssignResponseFormat) {
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj.clear();
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = nullptr;
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_object"}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
EXPECT_EQ(request->responseFormat.value(), R"({"type":"json_object"})");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", "test_schema"}, {"schema", {{"type", "object"}}}}}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", "my-test_schema_123"}, {"schema", {{"type", "object"}}}}}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = "not_an_object";
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format must be an object");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = OrderedJson::array({"text"});
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"other_field", "value"}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format must contain 'type' field");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", nullptr}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format must contain 'type' field");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", 123}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.type must be a string");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "invalid_type"}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error,
"Parameter response_format.type must be 'json_object', 'json_schema' or 'text', got 'invalid_type'");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "text"}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema is required when type is 'json_schema'");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"}, {"json_schema", nullptr}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema is required when type is 'json_schema'");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"}, {"json_schema", "not_an_object"}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema must be an object");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"}, {"json_schema", {{"schema", {{"type", "object"}}}}}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema.name is required");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", nullptr}, {"schema", {{"type", "object"}}}}}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema.name is required");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", 123}, {"schema", {{"type", "object"}}}}}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema.name must be a string");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", ""}, {"schema", {{"type", "object"}}}}}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema.name must be 1-64 characters");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", std::string(65, 'a')}, {"schema", {{"type", "object"}}}}}};
EXPECT_FALSE(AssignResponseFormat(jsonObj, request, error));
EXPECT_FALSE(request->responseFormat.has_value());
EXPECT_EQ(error, "Parameter response_format.json_schema.name must be 1-64 characters");
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", std::string(64, 'a')}, {"schema", {{"type", "object"}}}}}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", "invalid name"}, {"schema", {{"type", "object"}}}}}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", "invalid.name"}, {"schema", {{"type", "object"}}}}}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
request = std::make_shared<Request>(RequestIdNew("mockRequest"));
jsonObj["response_format"] = {{"type", "json_schema"},
{"json_schema", {{"name", "invalid@name"}, {"schema", {{"type", "object"}}}}}};
EXPECT_TRUE(AssignResponseFormat(jsonObj, request, error));
EXPECT_TRUE(request->responseFormat.has_value());
}
TEST_F(InferParamTest, testValidateFeatureCompatibilityMtpWithStructuredOutput) {
InferParam::ValidationContext ctx;
ctx.mtpEnabled = true;
ctx.reqStructuredOutput = false;
error.clear();
EXPECT_TRUE(inferParam->ValidateFeatureCompatibility(ctx, error));
EXPECT_TRUE(error.empty());
ctx.reqStructuredOutput = true;
error.clear();
EXPECT_FALSE(inferParam->ValidateFeatureCompatibility(ctx, error));
EXPECT_EQ(error, "structured output (response_format) cannot be used with mtp");
}
}