Skip to content

Commit

Permalink
Merge pull request #2755 from soheibthriber/buildbot-embedded-unittests
Browse files Browse the repository at this point in the history
Buildbot embedded unittests
  • Loading branch information
jeanlf committed May 6, 2024
2 parents 8de5d85 + 0e41abc commit b7c020d
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 25 deletions.
51 changes: 49 additions & 2 deletions Makefile
Expand Up @@ -9,7 +9,7 @@ endif

vpath %.c $(SRC_PATH)

all: version
all: version unit_tests
$(MAKE) -C src all
$(MAKE) -C applications all
ifneq ($(STATIC_BINARY),yes)
Expand Down Expand Up @@ -54,7 +54,7 @@ depend:
$(MAKE) -C applications dep
$(MAKE) -C modules dep

clean:
clean: unit_tests_clean
$(MAKE) -C src clean
$(MAKE) -C applications clean
$(MAKE) -C modules clean
Expand All @@ -77,6 +77,53 @@ doc:
man:
@cd $(SRC_PATH)/share/doc/man && MP4Box -genman && gpac -genman


UT_CFG_PATH:=unittests/build/config

unit_tests:
ifeq ($(UNIT_TESTS),yes)
@echo "Unit Tests:"
@echo "- configuring"
@mkdir -p unittests/build/bin/gcc

@cp config.mak unittests/build/
@sed 's|BUILD_PATH=$(BUILD_PATH)|BUILD_PATH=$(BUILD_PATH)/unittests/build|g' config.mak | \
sed 's|-I"$(BUILD_PATH)"|-I"$(BUILD_PATH)/unittests/build"|g' > $(UT_CFG_PATH).mak.new
@if [ -e $(UT_CFG_PATH).mak ]; then \
if ! diff -q $(UT_CFG_PATH).mak $(UT_CFG_PATH).mak.new >/dev/null ; then \
mv $(UT_CFG_PATH).mak.new $(UT_CFG_PATH).mak; \
fi; \
else \
mv $(UT_CFG_PATH).mak.new $(UT_CFG_PATH).mak; \
fi

@sed 's/GF_STATIC static/GF_STATIC GF_EXPORT/' config.h > $(UT_CFG_PATH).h.new
@if [ -e $(UT_CFG_PATH).h ]; then \
if ! diff -q $(UT_CFG_PATH).h $(UT_CFG_PATH).h.new >/dev/null ; then \
mv $(UT_CFG_PATH).h.new $(UT_CFG_PATH).h; \
fi; \
else \
mv $(UT_CFG_PATH).h.new $(UT_CFG_PATH).h; \
fi

@$(SRC_PATH)/unittests/build.sh > unittests/build/bin/gcc/unittests.c

@echo "- building"
@cd unittests/build && $(MAKE) -C src && $(MAKE) -C src unit_tests

@echo "- executing"
$(SRC_PATH)/unittests/launch.sh

@echo "- done"
endif

unit_tests_clean:
ifeq ($(UNIT_TESTS),yes)
@echo "Cleaning unit tests artifacts"
@rm -rf unittests/build/bin
@cd unittests/build && $(MAKE) -C src clean
endif

test_suite:
@cd $(SRC_PATH)/testsuite && ./make_tests.sh -precommit -p=0

Expand Down
1 change: 1 addition & 0 deletions build/android/jni/libgpac/config.h
Expand Up @@ -3,6 +3,7 @@
#define GF_CONFIG_H

#define GPAC_CONFIG_LINUX 1
#define GF_STATIC static
#define GPAC_HAS_QJS 1
#define GPAC_HAS_MEDIACODEC
#define GPAC_HAS_JPEG 1
Expand Down
51 changes: 33 additions & 18 deletions configure
Expand Up @@ -91,6 +91,7 @@ libgpac_cflags=""
libgpac_extralibs=""
static_build="no"
static_bin="no"
unit_tests="no"
static_modules="no"
lm_lib=""
has_directx="no"
Expand Down Expand Up @@ -390,6 +391,7 @@ GPAC build options:
--disable-opt disable GCC optimizations
--static-build link statically against libgpac but still allow dependencies to shared libraries (enable --static-modules)
--static-bin enable static linking of MP4Box and gpac only (will enable --static-build), disable all libraries not linkable statically.
--unittests enable unit tests [default=no]
--sdl-cfg=SDL_PATH specify path to sdl-config for local install [$sdl_path]
--enable-sdl-static use static SDL linking [default=no]
--X11-path=X11_PATH specify path for X11 includes and libraries [$X11_PATH]
Expand Down Expand Up @@ -648,6 +650,8 @@ for opt do
;;
--enable-sanitizer) enable_sanitizer="yes"
;;
--unittests) unit_tests="yes"
;;
--static-modules) static_modules="yes"
;;
--sdl-cfg=*) sdl_path=`echo $opt | cut -d '=' -f 2`; sdl_local="yes"
Expand Down Expand Up @@ -2171,6 +2175,8 @@ if test $cpu = "mips"; then
fi
echo ""
echo "** GPAC $version rev$revision Core Configuration **"
echo "Unit Tests: $unit_tests ('make unit_tests')"
echo "#define GF_STATIC static" >> $TMPH
if test "$static_bin" = "yes" ; then
echo "Static binaries enabled"
echo "#define GPAC_STATIC_BIN" >> $TMPH
Expand Down Expand Up @@ -2635,6 +2641,9 @@ man_dir=${mandir#"$pf"}
echo "man_dir=$man_dir" >> config.mak


echo "UNIT_TESTS=$unit_tests" >> config.mak


echo "STATIC_MODULES=$static_modules" >> config.mak

#for cross-compilation
Expand Down Expand Up @@ -3082,57 +3091,63 @@ fi
echo "PKG_CONFIG=$pkg_config" >> config.mak


#build tree in object directory if source path is different from current one
if test "$source_path_used" = "yes" ; then

echo "Creating compilation tree image"
build_object_files_directory_tree()
{
SRC_DIRS="src src/utils src/isomedia src/ietf src/odf src/bifs src/scenegraph src/filter_core src/filters src/crypto src/media_tools src/scene_manager src/compositor src/laser src/evg src/quickjs src/jsmods"

APP_DIRS="applications/gpac applications/mp4box"

for dir in $SRC_DIRS ; do
mkdir -p "$dir"
done
ln -sf "$source_path/Makefile" Makefile
ln -sf "$source_path/static.mak" static.mak
ln -sf "$source_path/src/Makefile" src/Makefile
ln -sf "$1/Makefile" Makefile
ln -sf "$1/static.mak" static.mak
ln -sf "$1/src/Makefile" src/Makefile

mkdir -p applications
ln -sf "$source_path/applications/Makefile" applications/Makefile
ln -sf "$1/applications/Makefile" applications/Makefile
mkdir -p applications/testapps

for dir in $APP_DIRS ; do
mkdir -p "$dir"
ln -sf "$source_path/$dir/Makefile" "$dir/Makefile"
ln -sf "$1/$dir/Makefile" "$dir/Makefile"
done


cur_dir="`pwd`"
cd "$cur_dir"

mkdir -p modules
ln -sf "$source_path/modules/Makefile" modules/Makefile
ln -sf "$1/modules/Makefile" modules/Makefile

for moddir in "$source_path/modules/"* ; do
for moddir in "$1/modules/"* ; do
if [ -d "$moddir" -a -f "$moddir/Makefile" ]; then
dir="${moddir#"$source_path/"}"
dir="${moddir#"$1/"}"
mkdir -p "$dir"
ln -sf "$moddir/Makefile" "$dir/Makefile"
fi
done
if test "$has_directx" = "yes"; then
ln -sf "$source_path/modules/dx_hw/hand.cur" modules/dx_hw/hand.cur
ln -sf "$source_path/modules/dx_hw/collide.cur" modules/dx_hw/collide.cur
ln -sf "$1/modules/dx_hw/hand.cur" modules/dx_hw/hand.cur
ln -sf "$1/modules/dx_hw/collide.cur" modules/dx_hw/collide.cur
fi
}

cd "$cur_dir"
#build tree in object directory if source path is different from current one
if test "$source_path_used" = "yes" ; then
echo "Creating compilation tree image"
build_object_files_directory_tree "$source_path"
fi

echo "SRC_PATH=$source_path" >> config.mak
echo "BUILD_PATH=$build_path" >> config.mak
echo "LOCAL_INC_PATH=$local_inc" >> config.mak


if test "$unit_tests" = "yes" ; then
mkdir -p unittests/build && cd unittests/build
build_object_files_directory_tree "$source_path"
cd -
fi


echo "#endif" >> $TMPH


Expand Down
4 changes: 2 additions & 2 deletions include/gpac/configuration.h
Expand Up @@ -70,8 +70,6 @@ This section documents the base data types of GPAC.
#define GPAC_HAS_MPEGHDECODER
#define GPAC_HAS_LIBCACA

/*IPv6 enabled - for win32, this is evaluated at compile time, !! do not uncomment !!*/

#define GPAC_MEMORY_TRACKING

/*Win32 IPv6 is evaluated at compile time, !! do not uncomment !!*/
Expand Down Expand Up @@ -223,6 +221,8 @@ This section documents the base data types of GPAC.
#error "Unknown target platform used with static configuration file"
#endif

/*needed for unittests (disabled)*/
#define GF_STATIC static

/*disables player */
//#define GPAC_DISABLE_COMPOSITOR
Expand Down
32 changes: 32 additions & 0 deletions include/tests.h
@@ -0,0 +1,32 @@
#pragma once

#include <gpac/setup.h>

#define unittest(suffix) void test_##suffix(void)

extern int checks_passed;
extern int checks_failed;

static Bool verbose_ut = GF_FALSE;
static Bool fatal_ut = GF_TRUE;

#define assert_true(expr) \
do { \
if (expr) { \
if (verbose_ut) printf("Assertion passed: \"%s\", File: \"%s\", Line: %d, Function: \"%s\"\n", #expr, __FILE__, __LINE__, __ASSERT_FUNCTION); \
checks_passed++; \
} else { \
checks_failed++; \
if (fatal_ut) checks_failed|=0x8000000; \
} \
} while (0)

#define assert_false(expr) assert_true(!(expr))
#define assert_equal_str(str1, str2) assert_true(!strcmp((str1), (str2)))
#define assert_not_equal_str(str1, str2) assert_true(strcmp((str1), (str2)))
#define assert_equal(a, b) assert_true((a) == (b))
#define assert_greater(a, b) assert_true((a) > (b))
#define assert_greater_equal(a, b) assert_true((a) >= (b))
#define assert_less(a, b) assert_true((a) < (b))
#define assert_less_equal(a, b) assert_true((a) <= (b))
#define assert_not_null(ptr) assert_true((ptr) != NULL)
11 changes: 11 additions & 0 deletions src/Makefile
Expand Up @@ -397,6 +397,17 @@ ifeq ($(shell fgrep "Libs.private:" ../gpac.pc 1>&2 2> /dev/null ; echo $$?),1)
@echo "Libs.private: -lgpac_static $(ALL_LIBS)" >> ../gpac.pc
endif


unit_tests:
ifeq ($(UNIT_TESTS),yes)
$(CC) -I.. -I$(SRC_PATH)/include -DGPAC_HAVE_CONFIG_H \
-o ../bin/gcc/unittests \
../bin/gcc/unittests.c \
$(shell find $(SRC_PATH) -path "*/unittests/*.c" | grep -v bin | sort) \
-Wl,-rpath=$(realpath ../bin/gcc) -L../bin/gcc -lgpac
endif


dep:

DEPS := $(SRCS:%.c=.deps/%.dep)
Expand Down
15 changes: 13 additions & 2 deletions src/utils/os_config_init.c
Expand Up @@ -2618,10 +2618,21 @@ Bool gf_sys_word_match(const char *orig, const char *dst)
s32 dist = 0;
u32 match = 0;
u32 i;
u32 olen = (u32) strlen(orig);
u32 dlen = (u32) strlen(dst);
u32 olen, dlen;
u32 *run;

if (orig == NULL && dst == NULL) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, (" gf_sys_word_match: NULL arguments \n"));
return GF_TRUE;
}
if (orig == NULL || dst == NULL) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, (" gf_sys_word_match: NULL argument \n"));
return GF_FALSE;
}

olen = (u32) strlen(orig);
dlen = (u32) strlen(dst);

if ((olen>=3) && (olen<dlen) && !strncmp(orig, dst, olen))
return GF_TRUE;
if ((dlen>=3) && (dlen<olen) && !strncmp(orig, dst, dlen))
Expand Down
58 changes: 58 additions & 0 deletions src/utils/unittests/ut_os_config_init.c
@@ -0,0 +1,58 @@
#include <gpac/main.h>
#include "tests.h"

unittest(gf_sys_word_match)
{
// Test exact match scenario
assert_true(gf_sys_word_match("abc", "abc"));

// Test short orig, longer dst scenario
assert_true(gf_sys_word_match("abc", "abcd"));

// Test short dst, longer orig scenario
assert_true(gf_sys_word_match("abcd", "abc"));

// Test scenario with ':' in orig but not in dst
assert_false(gf_sys_word_match("a:b:c", "xyz"));

// Test scenario with ':' in dst but not in orig
assert_false(gf_sys_word_match("abc", "x:y:z"));

// Test strnistr match scenario
assert_true(gf_sys_word_match("abc", "xabcz"));

// Test repeated characters scenario
assert_false(gf_sys_word_match("aabbc", "axayabaz"));

// Test match*2 < olen scenario
assert_false(gf_sys_word_match("abc", "xyz"));

// Test half characters in order scenario
assert_true(gf_sys_word_match("abcd", "aebfcd"));

// Test null pointer
assert_true(gf_sys_word_match(NULL, NULL));
assert_false(gf_sys_word_match("abc", NULL));
assert_false(gf_sys_word_match(NULL, "abc"));

// Test empty string
assert_true(gf_sys_word_match("", ""));
assert_false(gf_sys_word_match("abc", ""));
assert_false(gf_sys_word_match("", "abc"));

// Test a very long string
const char *longString = "a very long string that exceeds the normal limit of the function, it may go further and further until it can break the behaviour of the function apparently not easy so lets write more and more";
assert_true(gf_sys_word_match(longString, longString));
assert_false(gf_sys_word_match("abc", longString));
assert_false(gf_sys_word_match(longString, "abc"));

// Test a non-ASCII buffer
const char *nonAsciiBuffer = "\x01\x02\x03\xFF\xFE\xFD";
assert_false(gf_sys_word_match("abc", nonAsciiBuffer));
assert_false(gf_sys_word_match(nonAsciiBuffer, "abc"));
assert_true(gf_sys_word_match(nonAsciiBuffer, nonAsciiBuffer));

// Test non-string: will crash because this exported function doesn't provide a str max len argument
char str[3] = {'a', 'b', 'c'};
//DISABLED: gf_sys_word_match("abc", str);
}
7 changes: 7 additions & 0 deletions src/utils/unittests/ut_xml_parser.c
@@ -0,0 +1,7 @@
#include "tests.h"

char *xml_translate_xml_string(char *str);
unittest(xml_translate_xml_string)
{
assert_equal_str(xml_translate_xml_string("&amp;"), "&");
}
2 changes: 1 addition & 1 deletion src/utils/xml_parser.c
Expand Up @@ -44,7 +44,7 @@

static GF_Err gf_xml_sax_parse_intern(GF_SAXParser *parser, char *current);

static char *xml_translate_xml_string(char *str)
GF_STATIC char *xml_translate_xml_string(char *str)
{
char *value;
u32 size, i, j;
Expand Down

0 comments on commit b7c020d

Please sign in to comment.