Add unit tests for mediademuxer API 20/316720/6 tizen
authorGilbok Lee <gilbok.lee@samsung.com>
Tue, 27 Aug 2024 08:13:04 +0000 (17:13 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Wed, 28 Aug 2024 07:04:07 +0000 (16:04 +0900)
- These tests cover various scenarios, including positive cases,
  negative cases with invalid parameters,
  and edge cases where the mediademuxer handle is null or in an invalid state.

- The tests are implemented using Google Test framework
  and are integrated into the existing build system.

- This change improves the overall quality of the mediademuxer library
  by adding automated tests that help catch regressions and ensure
  the correctness of the API implementation.

[Version] 0.1.46
[Issue Type] Add unittest

Change-Id: I2498c1c877d4d15762637bf2826bf6e6657c62a7

CMakeLists.txt
packaging/capi-mediademuxer.spec
unittest/CMakeLists.txt [new file with mode: 0644]
unittest/ut_base.hpp [new file with mode: 0644]
unittest/ut_main.cpp [new file with mode: 0644]
unittest/ut_mediademuxer.cpp [new file with mode: 0644]
unittest/ut_mediademuxer_after_prepare.cpp [new file with mode: 0644]
unittest/ut_mediademuxer_after_set_eos.cpp [new file with mode: 0644]
unittest/ut_mediademuxer_after_start.cpp [new file with mode: 0644]

index fa911352b45476e237cf5659e83bdbcc5c87020d..e8b5b6c8c46de351935fea37d9ca965685d3203b 100644 (file)
@@ -79,6 +79,9 @@ CONFIGURE_FILE(
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
 ADD_SUBDIRECTORY(test)
+IF(BUILD_UNITTEST)
+ADD_SUBDIRECTORY(unittest)
+ENDIF(BUILD_UNITTEST)
 
 IF(UNIX)
 
@@ -110,4 +113,3 @@ ADD_CUSTOM_COMMAND(
 )
 
 ENDIF(UNIX)
-
index cd42ce4268f20a6d821af2610cb659af33539292..ffdae1d33ab67d7c132f0cb08b371d64461b004d 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-mediademuxer
 Summary:    A Media Demuxer library in Tizen Native API
-Version:    0.1.45
+Version:    0.1.46
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -18,6 +18,10 @@ BuildRequires:  pkgconfig(gstreamer-video-1.0)
 BuildRequires:  pkgconfig(gstreamer-app-1.0)
 BuildRequires:  pkgconfig(iniparser)
 
+%if 0%{?gtests:1}
+BuildRequires:  pkgconfig(gmock)
+%endif
+
 %description
 A Media Demuxer library in Tizen Native API
 
@@ -38,6 +42,16 @@ Group: Development/Multimedia
 Collection of files related to Line Coverage. It is tested as gcov for a media demuxer library in Tizen native API
 %endif
 
+%if 0%{?gtests:1}
+%package ut
+Summary: A unittest app for Media Demuxer API
+Group:   Utils/Multimedia
+Requires: %{name} = %{version}-%{release}
+
+%description ut
+A unittest app for Media Demuxer API
+%endif
+
 %prep
 %setup -q
 
@@ -61,8 +75,12 @@ export LDFLAGS+=" -lgcov"
 %endif
 
 MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
-%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
-
+%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \
+%if 0%{?gtests:1}
+  -DBUILD_UNITTEST=YES
+%else
+  -DBUILD_UNITTEST=NO
+%endif
 
 make %{?jobs:-j%jobs}
 
@@ -89,7 +107,7 @@ find . -name '*.gcno' -exec cp --parents '{}' "$gcno_obj_dir" ';'
 %manifest capi-mediademuxer.manifest
 %{_libdir}/libcapi-mediademuxer.so.*
 %license LICENSE.Apache-2.0
-%{_bindir}/*
+%{_bindir}/mediademuxer_test
 
 %files devel
 %{_includedir}/media/*.h
@@ -100,3 +118,10 @@ find . -name '*.gcno' -exec cp --parents '{}' "$gcno_obj_dir" ';'
 %files gcov
 %{_datadir}/gcov/obj/*
 %endif
+
+%if 0%{?gtests:1}
+%files ut
+%manifest %{name}.manifest
+%license LICENSE.Apache-2.0
+%{_bindir}/mediademuxer_ut
+%endif
diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8d4a131
--- /dev/null
@@ -0,0 +1,61 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
+
+SET(fw_test "mediademuxer_ut")
+
+SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
+
+SET(${fw_test}_CXXFLAGS "-Wall -pthread -fPIE -Wl,-z,relro -fstack-protector -fno-delete-null-pointer-checks -DEFL_BETA_API_SUPPORT")
+
+SET(${fw_test}_LDFLAGS)
+
+SET(ADD_LIBS
+  "capi-mediademuxer"
+)
+
+SET(dependents
+  "glib-2.0 gtest"
+)
+
+find_package(GTest REQUIRED)
+set(GTEST_LIBRARY gtest)
+
+INCLUDE(FindPkgConfig)
+
+pkg_check_modules(${fw_test} REQUIRED ${dependents})
+
+FOREACH(flag ${${fw_test}_CFLAGS})
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+SET(EXTRA_CXXFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+FOREACH(flag ${${fw_test}_CXXFLAGS})
+SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+
+INCLUDE_DIRECTORIES(
+  ${PROJECT_SOURCE_DIR}
+)
+
+FILE(GLOB UT_SRC
+  *.cpp
+)
+
+ADD_EXECUTABLE(${fw_test} ${UT_SRC})
+
+LINK_DIRECTORIES(${LIB_INSTALL_DIR})
+
+TARGET_LINK_LIBRARIES(${fw_test}
+  ${GTEST_LIBRARY}
+  ${CMAKE_THREAD_LIBS_INIT}
+  ${ADD_LIBS}
+  ${${fw_test}_LDFLAGS}
+  "-pie"
+)
+
+INSTALL(
+  TARGETS ${fw_test}
+  DESTINATION bin
+)
diff --git a/unittest/ut_base.hpp b/unittest/ut_base.hpp
new file mode 100644 (file)
index 0000000..f758fd3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "mediademuxer.h"
+#include "gtest/gtest.h"
+
+#undef LOG_TAG
+#define LOG_TAG "MTPR_UT"
+
+class MediademuxerBaseTest : public ::testing::Test {
+public:
+       MediademuxerBaseTest() = default;
+       ~MediademuxerBaseTest() = default;
+
+       void SetUp() override {}
+       void TearDown() override {}
+
+protected:
+       mediademuxer_h demuxer { nullptr };
+       const char* valid_path = "/home/owner/mediademuxer/test.mp4";
+       const char* invalid_path = nullptr;
+};
diff --git a/unittest/ut_main.cpp b/unittest/ut_main.cpp
new file mode 100644 (file)
index 0000000..0b8ab3b
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "gtest/gtest.h"
+
+int main(int argc, char *argv[])
+{
+       try {
+               ::testing::InitGoogleTest(&argc, argv);
+               return RUN_ALL_TESTS();
+       } catch (const std::exception &e) {
+               std::cout << "caught exception: " << e.what() << std::endl;
+               return -1;
+       }
+}
diff --git a/unittest/ut_mediademuxer.cpp b/unittest/ut_mediademuxer.cpp
new file mode 100644 (file)
index 0000000..3659de3
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "ut_base.hpp"
+
+TEST(MediademuxerCreateTest, NormalCase_Positive)
+{
+       mediademuxer_h demuxer = nullptr;
+       ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_NE(nullptr, demuxer);
+       mediademuxer_destroy(demuxer); // Clean up resource
+}
+
+TEST(MediademuxerCreateTest, NullPointer_Negative)
+{
+       EXPECT_EQ(mediademuxer_create(nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST(MediademuxerCreateTest, AlreadyCreatedInstance_Negative)
+{
+       mediademuxer_h demuxer = nullptr;
+       ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+       mediademuxer_destroy(demuxer); // Clean up resource
+}
+
+class MediademuxerTest : public ::MediademuxerBaseTest
+{
+protected:
+       virtual void SetUp() {
+               // Initialize the mediademuxer handle
+               ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+       }
+
+       virtual void TearDown() {
+               // Destroy the mediademuxer handle
+               mediademuxer_destroy(demuxer);
+       }
+
+       mediademuxer_eos_cb eos_callback = [](int track_num, void *user_data) { /* Dummy callback */ };
+       mediademuxer_error_cb error_callback = [](mediademuxer_error_e error, void *user_data) { /* Dummy callback */ };
+};
+
+TEST_F(MediademuxerTest, PositiveDestroy)
+{
+       EXPECT_EQ(mediademuxer_destroy(demuxer), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerTest, NegativeDestroyInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_destroy(demuxer), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativeDestroyNullHandle)
+{
+       EXPECT_EQ(mediademuxer_destroy(nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerTest, PositiveSetDataSource)
+{
+       EXPECT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerTest, NegativeSetDataSourceInvalidPath)
+{
+       EXPECT_EQ(mediademuxer_set_data_source(demuxer, invalid_path), MEDIADEMUXER_ERROR_INVALID_PATH);
+}
+
+TEST_F(MediademuxerTest, NegativeSetDataSourceInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE); // Change state to not IDLE
+       EXPECT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_INVALID_STATE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativeSetDataSourceNullHandle)
+{
+       EXPECT_EQ(mediademuxer_set_data_source(nullptr, valid_path), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerTest, PositiveSetEosCb)
+{
+       EXPECT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerTest, PositiveUnsetEosCb)
+{
+       EXPECT_EQ(mediademuxer_unset_eos_cb(demuxer), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerTest, NegativeSetEosCbInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE); // Change state to not IDLE
+       EXPECT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_INVALID_STATE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativeUnsetEosCbInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE); // Change state to not IDLE
+       EXPECT_EQ(mediademuxer_unset_eos_cb(demuxer), MEDIADEMUXER_ERROR_INVALID_STATE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativeSetEosCbNullHandle)
+{
+       EXPECT_EQ(mediademuxer_set_eos_cb(nullptr, eos_callback, this), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerTest, NegativeUnsetEosCbNullHandle)
+{
+       EXPECT_EQ(mediademuxer_unset_eos_cb(nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerTest, PositiveSetErrorCb)
+{
+       EXPECT_EQ(mediademuxer_set_error_cb(demuxer, error_callback, this), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerTest, PositiveUnsetErrorCb)
+{
+       EXPECT_EQ(mediademuxer_unset_error_cb(demuxer), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerTest, NegativeSetErrorCbInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE); // Change state to not IDLE
+       EXPECT_EQ(mediademuxer_set_error_cb(demuxer, error_callback, this), MEDIADEMUXER_ERROR_INVALID_STATE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativeUnsetErrorCbInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE); // Change state to not IDLE
+       EXPECT_EQ(mediademuxer_unset_error_cb(demuxer), MEDIADEMUXER_ERROR_INVALID_STATE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativeSetErrorCbNullHandle)
+{
+       EXPECT_EQ(mediademuxer_set_error_cb(nullptr, error_callback, this), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerTest, NegativeUnsetErrorCbNullHandle)
+{
+       EXPECT_EQ(mediademuxer_unset_error_cb(nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerTest, PositivePrepare)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativePrepareInvalidState)
+{
+       ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE); // Set data source to change state to not IDLE
+       ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE); // Change state to not IDLE
+       EXPECT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_INVALID_STATE);
+       mediademuxer_unprepare(demuxer);
+}
+
+TEST_F(MediademuxerTest, NegativePrepareNoEosCb)
+{
+       EXPECT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+}
+
+TEST_F(MediademuxerTest, NegativePrepareNullHandle)
+{
+       EXPECT_EQ(mediademuxer_prepare(nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
diff --git a/unittest/ut_mediademuxer_after_prepare.cpp b/unittest/ut_mediademuxer_after_prepare.cpp
new file mode 100644 (file)
index 0000000..38eae47
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "ut_base.hpp"
+
+class MediademuxerAfterPrepareTest : public ::MediademuxerBaseTest
+{
+protected:
+       virtual void SetUp() {
+               // Initialize the mediademuxer handle
+               ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE);
+               mediademuxer_eos_cb eos_callback = [](int track_num, void *user_data) { /* Dummy callback */ };
+               ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       }
+
+       virtual void TearDown() {
+               // Destroy the mediademuxer handle
+               mediademuxer_unprepare(demuxer);
+               mediademuxer_destroy(demuxer);
+       }
+};
+
+TEST_F(MediademuxerAfterPrepareTest, PositiveGetTrackInfo)
+{
+       int track_count = 0;
+       ASSERT_EQ(mediademuxer_get_track_count(demuxer, &track_count), MEDIADEMUXER_ERROR_NONE);
+       if (track_count <= 0)
+               GTEST_SKIP() << "No tracks available";
+
+       media_format_h format;
+       EXPECT_EQ(mediademuxer_get_track_info(demuxer, 0, &format), MEDIADEMUXER_ERROR_NONE);
+       media_format_unref(format);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeGetTrackInfoInvalidIndex)
+{
+       media_format_h format;
+       EXPECT_EQ(mediademuxer_get_track_info(demuxer, -1, &format), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeGetTrackInfoNullFormat)
+{
+       EXPECT_EQ(mediademuxer_get_track_info(demuxer, 0, nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeGetTrackInfoInvalidState)
+{
+       mediademuxer_unprepare(demuxer);
+       media_format_h format;
+       EXPECT_EQ(mediademuxer_get_track_info(demuxer, 0, &format), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeGetTrackInfoNullHandle)
+{
+       media_format_h format;
+       EXPECT_EQ(mediademuxer_get_track_info(nullptr, 0, &format), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, PositiveSelectTrack)
+{
+       int track_count = 0;
+       EXPECT_EQ(mediademuxer_get_track_count(demuxer, &track_count), MEDIADEMUXER_ERROR_NONE);
+       if (track_count <= 0)
+               GTEST_SKIP() << "No tracks available";
+
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 0), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeSelectTrackInvalidIndex)
+{
+       EXPECT_EQ(mediademuxer_select_track(demuxer, -1), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeSelectTrackInvalidState)
+{
+       ASSERT_EQ(mediademuxer_unprepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 0), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeSelectTrackNullHandle)
+{
+       EXPECT_EQ(mediademuxer_select_track(nullptr, 0), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, PositiveSelectTracks)
+{
+       int track_count = 0;
+       ASSERT_EQ(mediademuxer_get_track_count(demuxer, &track_count), MEDIADEMUXER_ERROR_NONE);
+       if (track_count < 2)
+               GTEST_SKIP() << "Not enough tracks available";
+
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 0), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 1), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeSelectMultipleTracksInvalidIndex)
+{
+       EXPECT_EQ(mediademuxer_select_track(demuxer, -1), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 2), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeSelectMultipleTracksInvalidState)
+{
+       ASSERT_EQ(mediademuxer_unprepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 0), MEDIADEMUXER_ERROR_INVALID_STATE);
+       EXPECT_EQ(mediademuxer_select_track(demuxer, 1), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeSelectMultipleTracksNullHandle)
+{
+       EXPECT_EQ(mediademuxer_select_track(nullptr, 0), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+       EXPECT_EQ(mediademuxer_select_track(nullptr, 1), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeStartInvalidState)
+{
+       ASSERT_EQ(mediademuxer_unprepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_start(demuxer), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterPrepareTest, NegativeStartNullHandle)
+{
+       EXPECT_EQ(mediademuxer_start(nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
diff --git a/unittest/ut_mediademuxer_after_set_eos.cpp b/unittest/ut_mediademuxer_after_set_eos.cpp
new file mode 100644 (file)
index 0000000..1b07b87
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "ut_base.hpp"
+
+class MediademuxerAfterSetEOSTest : public ::MediademuxerBaseTest
+{
+protected:
+       virtual void SetUp() {
+               // Initialize the mediademuxer handle
+               ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+       }
+
+       virtual void TearDown() {
+               // Destroy the mediademuxer handle
+               mediademuxer_destroy(demuxer);
+       }
+
+       mediademuxer_eos_cb eos_callback = [](int track_num, void *user_data) { /* Dummy callback */ };
+};
+
+TEST_F(MediademuxerAfterSetEOSTest, PositiveGetTrackCount)
+{
+       int count = 0;
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_get_track_count(demuxer, &count), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_GE(count, 0);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, NegativeGetTrackCountInvalidState)
+{
+       int count = 0;
+       EXPECT_EQ(mediademuxer_get_track_count(demuxer, &count), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, NegativeGetTrackCountNullHandle)
+{
+       int count = 0;
+       EXPECT_EQ(mediademuxer_get_track_count(nullptr, &count), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, GetStateIdle)
+{
+       mediademuxer_state state;
+       EXPECT_EQ(mediademuxer_get_state(demuxer, &state), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(state, MEDIADEMUXER_STATE_IDLE);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, GetStateReady)
+{
+       EXPECT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+
+       mediademuxer_state state;
+       EXPECT_EQ(mediademuxer_get_state(demuxer, &state), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(state, MEDIADEMUXER_STATE_READY);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, GetStateDemuxing)
+{
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_start(demuxer), MEDIADEMUXER_ERROR_NONE);
+
+       mediademuxer_state state;
+       EXPECT_EQ(mediademuxer_get_state(demuxer, &state), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(state, MEDIADEMUXER_STATE_DEMUXING);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, GetStateDemuxing2)
+{
+       ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_start(demuxer), MEDIADEMUXER_ERROR_NONE);
+       ASSERT_EQ(mediademuxer_seek(demuxer, 0), MEDIADEMUXER_ERROR_NONE);
+
+       mediademuxer_state state;
+       EXPECT_EQ(mediademuxer_get_state(demuxer, &state), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(state, MEDIADEMUXER_STATE_DEMUXING);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, GetStateNullHandle)
+{
+       mediademuxer_state state;
+       EXPECT_EQ(mediademuxer_get_state(nullptr, &state), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterSetEOSTest, GetStateNullStatePointer)
+{
+       EXPECT_EQ(mediademuxer_get_state(demuxer, nullptr), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+}
diff --git a/unittest/ut_mediademuxer_after_start.cpp b/unittest/ut_mediademuxer_after_start.cpp
new file mode 100644 (file)
index 0000000..cab4bfc
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "ut_base.hpp"
+
+class MediademuxerAfterStartTest : public ::MediademuxerBaseTest
+{
+protected:
+       virtual void SetUp() {
+               // Initialize the mediademuxer handle
+               ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+
+               // Get track count and select the first track
+               int track_count = 0;
+               ASSERT_EQ(mediademuxer_get_track_count(demuxer, &track_count), MEDIADEMUXER_ERROR_NONE);
+               if (track_count <= 0)
+                       GTEST_SKIP() << "No tracks available";
+
+               media_format_h format;
+               ASSERT_EQ(mediademuxer_get_track_info(demuxer, 0, &format), MEDIADEMUXER_ERROR_NONE);
+               media_format_unref(format);
+               ASSERT_EQ(mediademuxer_select_track(demuxer, 0), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_start(demuxer), MEDIADEMUXER_ERROR_NONE);
+       }
+
+       virtual void TearDown() {
+               // Destroy the mediademuxer handle
+               mediademuxer_stop(demuxer);
+               mediademuxer_unprepare(demuxer);
+               mediademuxer_destroy(demuxer);
+       }
+
+       mediademuxer_eos_cb eos_callback = [](int track_num, void *user_data) { /* Dummy callback */ };
+};
+
+TEST_F(MediademuxerAfterStartTest, PositiveReadSample)
+{
+       media_packet_h packet;
+       ASSERT_EQ(mediademuxer_read_sample(demuxer, 0, &packet), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_NE(packet, nullptr);
+       media_packet_destroy(packet);
+}
+
+TEST_F(MediademuxerAfterStartTest, NegativeReadSampleInvalidTrackIndex)
+{
+       media_packet_h packet;
+       EXPECT_EQ(mediademuxer_read_sample(demuxer, -1, &packet), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterStartTest, NegativeReadSampleNullOutputBuffer)
+{
+       EXPECT_EQ(mediademuxer_read_sample(demuxer, 0, nullptr), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterStartTest, NegativeReadSampleInvalidState)
+{
+       mediademuxer_stop(demuxer);
+       media_packet_h packet;
+       EXPECT_EQ(mediademuxer_read_sample(demuxer, 0, &packet), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterStartTest, NegativeReadSampleNullHandle)
+{
+       media_packet_h packet;
+       EXPECT_EQ(mediademuxer_read_sample(nullptr, 0, &packet), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(MediademuxerAfterStartTest, PositiveSeek)
+{
+       EXPECT_EQ(mediademuxer_seek(demuxer, 1000), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerAfterStartTest, NegativeSeekInvalidState)
+{
+       mediademuxer_stop(demuxer);
+       EXPECT_EQ(mediademuxer_seek(demuxer, 1000), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterStartTest, NegativeSeekNullHandle)
+{
+       EXPECT_EQ(mediademuxer_seek(nullptr, 1000), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}
+
+class MediademuxerAfterSelectTrackStartTest : public ::MediademuxerBaseTest
+{
+protected:
+       virtual void SetUp() {
+               // Initialize the mediademuxer handle
+               ASSERT_EQ(mediademuxer_create(&demuxer), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_data_source(demuxer, valid_path), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_set_eos_cb(demuxer, eos_callback, this), MEDIADEMUXER_ERROR_NONE);
+               ASSERT_EQ(mediademuxer_prepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+
+               // Get track count and select the first track
+               int track_count = 0;
+               ASSERT_EQ(mediademuxer_get_track_count(demuxer, &track_count), MEDIADEMUXER_ERROR_NONE);
+               if (track_count <= 0)
+                       GTEST_SKIP() << "No tracks available";
+
+               media_format_h format;
+               ASSERT_EQ(mediademuxer_get_track_info(demuxer, 0, &format), MEDIADEMUXER_ERROR_NONE);
+               media_format_unref(format);
+               ASSERT_EQ(mediademuxer_select_track(demuxer, 0), MEDIADEMUXER_ERROR_NONE);
+       }
+
+       virtual void TearDown() {
+               // Destroy the mediademuxer handle
+               mediademuxer_unprepare(demuxer);
+               mediademuxer_destroy(demuxer);
+       }
+
+       mediademuxer_eos_cb eos_callback = [](int track_num, void *user_data) { /* Dummy callback */ };
+};
+
+TEST_F(MediademuxerAfterSelectTrackStartTest, PositiveUnselectTrack)
+{
+       EXPECT_EQ(mediademuxer_unselect_track(demuxer, 0), MEDIADEMUXER_ERROR_NONE);
+}
+
+TEST_F(MediademuxerAfterSelectTrackStartTest, NegativeUnselectTrackInvalidTrackIndex)
+{
+       EXPECT_EQ(mediademuxer_unselect_track(demuxer, -1), MEDIADEMUXER_ERROR_INVALID_OPERATION);
+}
+
+TEST_F(MediademuxerAfterSelectTrackStartTest, NegativeUnselectTrackInvalidState)
+{
+       ASSERT_EQ(mediademuxer_unprepare(demuxer), MEDIADEMUXER_ERROR_NONE);
+       EXPECT_EQ(mediademuxer_unselect_track(demuxer, 0), MEDIADEMUXER_ERROR_INVALID_STATE);
+}
+
+TEST_F(MediademuxerAfterSelectTrackStartTest, NegativeUnselectTrackNullHandle)
+{
+       EXPECT_EQ(mediademuxer_unselect_track(nullptr, 0), MEDIADEMUXER_ERROR_INVALID_PARAMETER);
+}