* -------------------------------------------------------------------------
* This file is part of the Vision SDK project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* Vision SDK 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.
* -------------------------------------------------------------------------
* Description: MxGstBaseTest.
* Author: Mind SDK
* Create: 2025
* History: NA
*/
#include <gtest/gtest.h>
#include <mockcpp/mockcpp.hpp>
#include <gst/gst.h>
#include <string>
#include "MxTools/PluginToolkit/base/MxGstBase.h"
#include "MxTools/PluginToolkit/base/MxPluginBase.h"
#include "MxTools/PluginToolkit/base/MxpiBufferDump.h"
#include "MxTools/PluginToolkit/PerformanceStatistics/PerformanceStatisticsManager.h"
#include "MxTools/PluginToolkit/buffer/MxpiBufferManager.h"
#include "MxTools/PluginToolkit/metadata/MxpiMetadataManager.h"
#include "MxTools/Proto/MxpiDataType.pb.h"
#include "MxTools/PluginToolkit/base/MxGstBase.h"
#include "MxPluginBaseDptr.hpp"
#include "MxBase/Utils/StringUtils.h"
#include "MxBase/DeviceManager/DeviceManager.h"
#include "MxBase/MemoryHelper/MemoryHelper.h"
using namespace MxTools;
using namespace MxBase;
namespace MxTools {
extern void InitProperty(const MxGstBase *filter, const GParamSpec *param);
extern void MxGstBaseInit(MxGstBase *filter, MxGstBaseClass *klass);
extern GstPad *MxGstBaseRequestNewPad(
GstElement *element, GstPadTemplate *templ, const gchar *nameTempl, const GstCaps *caps);
extern void MxGstBaseReleasePad(GstElement *element, GstPad *pad);
extern void MxGstBaseFinalize(GObject *object);
extern void ClearFilterWhenReadyToNull(MxGstBase *filter);
extern gboolean MxGstBaseDefaultEvent(GstPad *pad, GstObject *parent, GstEvent *event);
extern int GetPadIndex(GstPad *pad, std::vector<GstPad *> padVector);
extern gboolean MxGstBaseDefaultQuery(GstPad *pad, GstObject *parent, GstQuery *query);
extern gboolean HandleSrcPadCustomQuery(GstPad *pad, MxGstBase *filter, const std::string &elementName,
GstStructure *queryStructure, const gchar *structName);
extern bool HandleSinkPadCustomQuery(GstPad *pad, MxGstBase *filter, const std::string &elementName,
GstStructure *queryStructure, const gchar *structName);
extern gboolean HandleCustomQuery(GstPad *pad, GstObject *parent, GstQuery *query);
extern gboolean HandleCustomQuery(GstPad *pad, GstObject *parent, GstQuery *query);
extern gboolean MxGstBasePadQuery(GstPad *pad, GstObject *parent, GstQuery *query);
extern GstFlowReturn SyncBufferProcess(MxGstBase &filter, MxpiBuffer &mxpiBuffer, int index);
extern bool JudgeBufSize(const std::vector<MxpiBuffer *> &input, int index);
extern GstFlowReturn BufferProcess(MxGstBase *filter, GstBuffer *gstBuffer, int index);
extern GstFlowReturn MxGstBaseChain(GstPad *pad, GstObject *parent, GstBuffer *gstBuffer);
extern APP_ERROR SetDevice(const int &deviceId);
extern gboolean SetDynamicImageSize(MxGstBase *filter);
}
namespace {
constexpr int TWICE = 2;
constexpr int THREE_TIMES = 3;
constexpr int INIT_DEVICEID = -1;
constexpr int INIT_DATASIZE = 1;
MxTools::InputParam g_bufferParam = {"", INIT_DEVICEID, INIT_DATASIZE};
class MxGstBaseTest : public testing::Test {
public:
virtual void TearDown()
{
GlobalMockObject::verify();
}
};
class MxPluginBaseDerived : public MxPluginBase {
public:
APP_ERROR Init(std::map<std::string, std::shared_ptr<void>> &configParamMap)
{
return APP_ERR_OK;
}
APP_ERROR DeInit()
{
return APP_ERR_OK;
}
APP_ERROR Process(std::vector<MxpiBuffer *> &mxpiBuffer)
{
return APP_ERR_OK;
}
APP_ERROR RunProcess(std::vector<MxpiBuffer *> &mxpiBuffer)
{
return APP_ERR_OK;
}
};
MxPluginBase *StubCreatePluginInstance()
{
return nullptr;
}
void StubLock(GMutex *mutex)
{}
void StubUnlock(GMutex *mutex)
{}
void StubClearFilterWhenReadyToNull(MxGstBase *filter)
{}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseInit_Should_Fail_When_Input_Nullptr)
{
APP_ERROR ret = APP_ERR_OK;
MxGstBase base;
MxGstBaseClass param;
try {
MxGstBaseInit(nullptr, ¶m);
} catch (std::exception &e) {
ret = APP_ERR_COMM_FAILURE;
}
EXPECT_EQ(ret, APP_ERR_COMM_FAILURE);
ret = APP_ERR_OK;
try {
MxGstBaseInit(&base, nullptr);
} catch (std::exception &e) {
ret = APP_ERR_COMM_FAILURE;
}
EXPECT_EQ(ret, APP_ERR_COMM_FAILURE);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseInit_Should_Fail_When_CreatePluginInstance_Fail)
{
APP_ERROR ret = APP_ERR_OK;
MxGstBase base;
MxGstBaseClass klass;
klass.CreatePluginInstance = StubCreatePluginInstance;
try {
MxGstBaseInit(&base, &klass);
} catch (std::exception &e) {
ret = APP_ERR_COMM_FAILURE;
}
EXPECT_EQ(ret, APP_ERR_COMM_FAILURE);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_InitProperty_Should_Sucess_When_Different_Type)
{
MxGstBase base;
base.configParam = std::make_unique<std::map<std::string, std::shared_ptr<void>>>();
GParamSpec *pspec = g_param_spec_long("long", "long", "long", 0, 1, 0, G_PARAM_READWRITE);
InitProperty(&base, pspec);
std::shared_ptr<void> ret = (*base.configParam)[pspec->name];
EXPECT_NE(ret, nullptr);
g_param_spec_unref(pspec);
pspec = g_param_spec_ulong("ulong", "ulong", "ulong", 0, 1, 0, G_PARAM_READWRITE);
InitProperty(&base, pspec);
ret = (*base.configParam)[pspec->name];
EXPECT_NE(ret, nullptr);
g_param_spec_unref(pspec);
pspec = g_param_spec_float("float", "float", "float", 0.0, 1.0, 0, G_PARAM_READWRITE);
InitProperty(&base, pspec);
ret = (*base.configParam)[pspec->name];
EXPECT_NE(ret, nullptr);
g_param_spec_unref(pspec);
pspec = g_param_spec_double("double", "double", "double", 0.0, 1.0, 0, G_PARAM_READWRITE);
InitProperty(&base, pspec);
ret = (*base.configParam)[pspec->name];
EXPECT_NE(ret, nullptr);
g_param_spec_unref(pspec);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseRequestNewPad_Should_Sucess_When_Pad_Is_Src)
{
MOCKER_CPP(&g_mutex_lock).stubs().will(invoke(StubLock));
MOCKER_CPP(&g_mutex_unlock).stubs().will(invoke(StubUnlock));
MxGstBase base;
GstPadTemplate *templ = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, gst_caps_new_any());
GstCaps *caps = gst_caps_new_any();
gchar *nameTempl = "test";
GstPad *ret = MxGstBaseRequestNewPad(GST_ELEMENT(&base), templ, nameTempl, caps);
EXPECT_NE(ret, nullptr);
gst_caps_unref(caps);
gst_object_unref(ret);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseReleasePad_Should_Sucess_When_Pad_Is_Src)
{
MOCKER_CPP(&g_mutex_lock).stubs().will(invoke(StubLock));
MOCKER_CPP(&g_mutex_unlock).stubs().will(invoke(StubUnlock));
MOCKER_CPP(&ClearFilterWhenReadyToNull).stubs().will(invoke(StubClearFilterWhenReadyToNull));
constexpr int padNum = 2;
MxGstBase base;
base.padIdx = padNum;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
MxGstBaseReleasePad(GST_ELEMENT(&base), pad);
EXPECT_EQ(base.padIdx, 1);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseDefaultEvent_Should_Sucess_With_Different_Event_CAPS)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstCaps *caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "I420", "width", G_TYPE_INT, 1280,
"height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
GstEvent *event = gst_event_new_caps(caps);
gboolean retValue = true;
MOCKER_CPP(&gst_pad_event_default).stubs().will(returnValue(retValue));
gboolean ret = MxGstBaseDefaultEvent(pad, GST_OBJECT(&base), event);
EXPECT_EQ(ret, true);
gst_caps_unref(caps);
gst_event_unref(event);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseDefaultEvent_Should_Sucess_With_Different_Event_FLUSH_START)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
gboolean retValue = true;
MOCKER_CPP(&gst_pad_event_default).stubs().will(returnValue(retValue));
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
plugin.pluginName_ = "osd";
base.flushStartNum = 1;
base.sinkPadVec = {};
GstEvent *event = gst_event_new_flush_start();
gboolean ret = MxGstBaseDefaultEvent(pad, GST_OBJECT(&base), event);
EXPECT_EQ(ret, true);
gst_event_unref(event);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseDefaultEvent_Should_Sucess_With_Different_Event_FLUSH_STOP)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
gboolean retValue = true;
MOCKER_CPP(&gst_pad_event_default).stubs().will(returnValue(retValue));
base.flushStopNum = 1;
base.sinkPadVec = {};
GstEvent *event = gst_event_new_flush_stop(true);
gboolean ret = MxGstBaseDefaultEvent(pad, GST_OBJECT(&base), event);
EXPECT_EQ(ret, true);
gst_event_unref(event);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_GetPadIndex_Should_Sucess_When_Valid_Input)
{
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
std::vector<GstPad *> padVector = {nullptr, nullptr, pad};
int ret = GetPadIndex(pad, padVector);
constexpr int expectedIdx = 2;
EXPECT_EQ(ret, expectedIdx);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseDefaultQuery_Should_Sucess_When_Valid_Input)
{
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
MxGstBase base;
GstQuery *query = gst_query_new_position(GST_FORMAT_TIME);
gboolean retValue = true;
MOCKER_CPP(&gst_pad_query_default).stubs().will(returnValue(retValue));
gboolean ret = MxGstBaseDefaultQuery(pad, GST_OBJECT(&base), query);
EXPECT_EQ(ret, true);
gst_object_unref(pad);
gst_query_unref(query);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleSrcPadCustomQuery_Should_Fail_With_Error_Size)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
plugin.outputDataKeys_ = {};
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstStructure *structure = gst_structure_new_empty("test");
MOCKER_CPP(&GetPadIndex).stubs().will(returnValue(1));
gboolean ret = HandleSrcPadCustomQuery(pad, &base, "test", structure, "test");
EXPECT_EQ(ret, false);
gst_object_unref(pad);
gst_structure_free(structure);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleSrcPadCustomQuery_Should_Success_With_Valid_Input)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
plugin.outputDataKeys_ = {"test", "test"};
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstStructure *structure = gst_structure_new_empty("test");
MOCKER_CPP(&GetPadIndex).stubs().will(returnValue(0));
MOCKER_CPP(&strcasecmp).stubs().will(returnValue(0));
gboolean ret = HandleSrcPadCustomQuery(pad, &base, "test", structure, "test");
EXPECT_EQ(ret, true);
gst_object_unref(pad);
gst_structure_free(structure);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleSinkPadCustomQuery_Should_Fail_With_Error_Name)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstStructure *structure = gst_structure_new_empty("test");
MOCKER_CPP(&strcasecmp).stubs().will(returnValue(1));
bool ret = HandleSinkPadCustomQuery(pad, &base, "test", structure, "test");
EXPECT_EQ(ret, false);
gst_object_unref(pad);
gst_structure_free(structure);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleSinkPadCustomQuery_Should_Fail_With_Error_Addr)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
plugin.elementDynamicImageSize_ = {};
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstStructure *structure = gst_structure_new_empty("test");
MOCKER_CPP(&strcasecmp).stubs().will(returnValue(0));
const std::string retStr = "test";
MOCKER_CPP(&MxPluginBase::GetElementNameWithObjectAddr).stubs().will(returnValue(retStr));
bool ret = HandleSinkPadCustomQuery(pad, &base, "test", structure, "test");
EXPECT_EQ(ret, false);
plugin.elementDynamicImageSize_ = {{"test", {}}};
constexpr int retInt = -1;
MOCKER_CPP(&GetPadIndex).stubs().will(returnValue(retInt));
ret = HandleSinkPadCustomQuery(pad, &base, "test", structure, "test");
EXPECT_EQ(ret, false);
gst_object_unref(pad);
gst_structure_free(structure);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleSinkPadCustomQuery_Should_Success_With_Vaild_Input)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
ImageSize size(1, 1);
plugin.elementDynamicImageSize_ = {{"test", {size}}};
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstStructure *structure = gst_structure_new_empty("test");
MOCKER_CPP(&strcasecmp).stubs().will(returnValue(0));
MOCKER_CPP(&GetPadIndex).stubs().will(returnValue(0));
const std::string retStr = "test";
MOCKER_CPP(&MxPluginBase::GetElementNameWithObjectAddr).stubs().will(returnValue(retStr));
bool ret = HandleSinkPadCustomQuery(pad, &base, "test", structure, "test");
EXPECT_EQ(ret, true);
gst_object_unref(pad);
gst_structure_free(structure);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleCustomQuery_Should_Fail_When_Get_Name_Fail)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstQuery *query = gst_query_new_position(GST_FORMAT_TIME);
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
const gchar *rerPtr = nullptr;
MOCKER_CPP(&gst_structure_get_name).stubs().will(returnValue(rerPtr));
gboolean ret = HandleCustomQuery(pad, GST_OBJECT(&base), query);
EXPECT_EQ(ret, false);
gst_object_unref(pad);
gst_query_unref(query);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleCustomQuery_Should_Success_With_Src_Pad)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstQuery *query = gst_query_new_position(GST_FORMAT_TIME);
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
const gchar *rerPtr = "test";
MOCKER_CPP(&gst_structure_get_name).stubs().will(returnValue(rerPtr));
MOCKER_CPP(&strcasecmp).times(TWICE).will(returnValue(0)).then(returnValue(1));
gboolean retValue = true;
MOCKER_CPP(&gst_pad_query_default).stubs().will(returnValue(retValue));
gboolean ret = HandleCustomQuery(pad, GST_OBJECT(&base), query);
EXPECT_EQ(ret, true);
MOCKER_CPP(&HandleSrcPadCustomQuery).stubs().will(returnValue(retValue));
ret = HandleCustomQuery(pad, GST_OBJECT(&base), query);
EXPECT_EQ(ret, true);
gst_object_unref(pad);
gst_query_unref(query);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_HandleCustomQuery_Should_Success_With_Sink_Pad)
{
MxGstBase base;
GstPad *pad = gst_pad_new("src", GST_PAD_SINK);
GstQuery *query = gst_query_new_position(GST_FORMAT_TIME);
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
const gchar *rerPtr = "test";
MOCKER_CPP(&gst_structure_get_name).stubs().will(returnValue(rerPtr));
MOCKER_CPP(&HandleSinkPadCustomQuery).stubs().will(returnValue(true));
gboolean ret = HandleCustomQuery(pad, GST_OBJECT(&base), query);
EXPECT_EQ(ret, true);
gst_object_unref(pad);
gst_query_unref(query);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBasePadQuery_Should_Success_With_CUSTOM)
{
MxGstBase base;
GstStructure *structure = gst_structure_new_empty("test");
GstPad *pad = gst_pad_new("src", GST_PAD_SRC);
GstQuery *query = gst_query_new_custom(GST_QUERY_CUSTOM, structure);
gboolean retValue = true;
MOCKER_CPP(&HandleCustomQuery).stubs().will(returnValue(retValue));
gboolean ret = MxGstBasePadQuery(pad, GST_OBJECT(&base), query);
EXPECT_EQ(ret, true);
gst_structure_free(structure);
gst_object_unref(pad);
gst_query_unref(query);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_SyncBufferProcess_Should_Success_When_JudgeBufSize_True)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
MxpiBuffer *buffer = MxpiBufferManager::CreateHostBuffer(g_bufferParam);
base.input = {buffer, buffer};
base.inputQueue = {nullptr, nullptr};
MOCKER_CPP(&IsStreamElementNameExist).stubs().will(returnValue(true));
GstFlowReturn ret = SyncBufferProcess(base, *buffer, 0);
EXPECT_EQ(ret, GST_FLOW_OK);
MxpiBufferManager::DestroyBuffer(buffer);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_SyncBufferProcess_Should_Success_When_JudgeBufSize_False)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
MxpiBuffer *buffer = MxpiBufferManager::CreateHostBuffer(g_bufferParam);
base.input = {nullptr, buffer};
MxpiBuffer *buffer1 = new MxpiBuffer();
base.inputQueue = {buffer1, nullptr};
MOCKER_CPP(&IsStreamElementNameExist).stubs().will(returnValue(true));
MOCKER_CPP(&JudgeBufSize).stubs().will(returnValue(false));
GstFlowReturn ret = SyncBufferProcess(base, *buffer, 0);
EXPECT_EQ(ret, GST_FLOW_OK);
MxpiBufferManager::DestroyBuffer(buffer);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_BufferProcess_Should_Success_When_Status_SYNC)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
plugin.status_ = SYNC;
GstBuffer gstBuffer;
GstFlowReturn retErr = GST_FLOW_OK;
MOCKER_CPP(&SyncBufferProcess).stubs().will(returnValue(retErr));
GstFlowReturn ret = BufferProcess(&base, &gstBuffer, 0);
EXPECT_EQ(ret, GST_FLOW_OK);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_BufferProcess_Should_Success_When_Status_ASYNC_And_Data_InValid)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
base.input = {nullptr, nullptr};
plugin.status_ = ASYNC;
plugin.srcPadNum_ = 1;
GstBuffer gstBuffer;
MOCKER_CPP(&strcasecmp).times(TWICE).will(returnValue(1));
std::shared_ptr<std::map<std::string, MxpiErrorInfo>> errorRet =
std::make_shared<std::map<std::string, MxpiErrorInfo>>();
MxpiErrorInfo info = {APP_ERR_COMM_FAILURE, "error"};
errorRet->insert({"error", info});
MOCKER_CPP(&MxpiMetadataManager::GetErrorInfo).times(1).will(returnValue(errorRet));
GstFlowReturn ret = BufferProcess(&base, &gstBuffer, 0);
EXPECT_EQ(ret, GST_FLOW_OK);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_BufferProcess_Should_Success_When_Status_ASYNC_And_Data_Valid)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
base.input = {nullptr, nullptr};
plugin.status_ = ASYNC;
plugin.srcPadNum_ = 0;
GstBuffer gstBuffer;
MOCKER_CPP(&IsStreamElementNameExist).stubs().will(returnValue(true));
std::shared_ptr<std::map<std::string, MxpiErrorInfo>> errorRet =
std::make_shared<std::map<std::string, MxpiErrorInfo>>();
MxpiErrorInfo info = {APP_ERR_COMM_FAILURE, "error"};
errorRet->insert({"error", info});
GstFlowReturn ret = BufferProcess(&base, &gstBuffer, 0);
EXPECT_EQ(ret, GST_FLOW_OK);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseChain_Should_Fail_With_Error_Idx)
{
GstPad *pad = gst_pad_new("src", GST_PAD_SINK);
MxGstBase base;
GstBuffer buffer;
constexpr int retVal = -1;
MOCKER_CPP(&GetPadIndex).stubs().will(returnValue(retVal));
GstFlowReturn ret = MxGstBaseChain(pad, GST_OBJECT(&base), &buffer);
EXPECT_EQ(ret, GST_FLOW_ERROR);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseChain_Should_Fail_When_SetDevice_Fail)
{
GstPad *pad = gst_pad_new("src", GST_PAD_SINK);
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
plugin.useDevice_ = true;
GstBuffer buffer;
APP_ERROR retVal = APP_ERR_COMM_FAILURE;
MOCKER_CPP(&SetDevice).stubs().will(returnValue(retVal));
GstFlowReturn ret = MxGstBaseChain(pad, GST_OBJECT(&base), &buffer);
EXPECT_EQ(ret, GST_FLOW_ERROR);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_MxGstBaseChain_Should_Success_With_Valid_Input)
{
GstPad *pad = gst_pad_new("src", GST_PAD_SINK);
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
GstBuffer buffer;
MOCKER_CPP(&GetPadIndex).stubs().will(returnValue(0));
MOCKER_CPP(&SetDevice).stubs().will(returnValue(0));
MOCKER_CPP(&BufferProcess).stubs().will(returnValue(0));
GstFlowReturn ret = MxGstBaseChain(pad, GST_OBJECT(&base), &buffer);
EXPECT_EQ(ret, GST_FLOW_OK);
gst_object_unref(pad);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_SetDynamicImageSize_Should_Success_When_Query_Fail)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
base.configParam = std::make_unique<std::map<std::string, std::shared_ptr<void>>>();
(*base.configParam)["resizeHeight"] = nullptr;
(*base.configParam)["resizeWidth"] = nullptr;
base.srcPadVec = {nullptr};
gboolean retVal = false;
MOCKER_CPP(&gst_pad_peer_query).stubs().will(returnValue(retVal));
gboolean ret = SetDynamicImageSize(&base);
EXPECT_EQ(ret, true);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_SetDynamicImageSize_Should_Success_When_Get_Value_Fail)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
base.configParam = std::make_unique<std::map<std::string, std::shared_ptr<void>>>();
(*base.configParam)["resizeHeight"] = nullptr;
(*base.configParam)["resizeWidth"] = nullptr;
base.srcPadVec = {nullptr};
gboolean retVal = true;
MOCKER_CPP(&gst_pad_peer_query).stubs().will(returnValue(retVal));
const GValue *retPtr = nullptr;
MOCKER_CPP(&gst_structure_get_value).stubs().will(returnValue(retPtr));
gboolean ret = SetDynamicImageSize(&base);
EXPECT_EQ(ret, true);
}
TEST_F(MxGstBaseTest, Test_MxGstBase_SetDynamicImageSize_Should_Success_When_Valid_Input)
{
MxGstBase base;
MxPluginBaseDerived plugin;
base.pluginInstance = &plugin;
base.configParam = std::make_unique<std::map<std::string, std::shared_ptr<void>>>();
(*base.configParam)["resizeHeight"] = nullptr;
(*base.configParam)["resizeWidth"] = nullptr;
base.srcPadVec = {nullptr};
gboolean retVal = true;
MOCKER_CPP(&gst_pad_peer_query).stubs().will(returnValue(retVal));
const GValue *retPtr = new GValue();
MOCKER_CPP(&gst_structure_get_value).stubs().will(returnValue(retPtr));
const gchar *retStr = "test";
MOCKER_CPP(&g_value_get_string).stubs().will(returnValue(retStr));
std::vector<std::string> retVec = {"1", "1"};
MOCKER_CPP(&StringUtils::Split).stubs().will(returnValue(retVec));
gboolean ret = SetDynamicImageSize(&base);
EXPECT_EQ(ret, true);
}
}
int main(int argc, char *argv[])
{
gst_init(&argc, &argv);
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}