From a742a736550c4fc1120c06832749bced0a209e1b Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 25 Jun 2012 09:58:09 -0700 Subject: [PATCH] Enable unit test framework in experimental branch. Change-Id: I27c98025b2857e2911005a52dd57c46e2524e815 --- libs.mk | 83 +++++++++++++++++++++++++-------- test/boolcoder_test.cc | 102 +++++++++++++++++++++++++++++++++++++++++ test/test.mk | 3 ++ test/test_libvpx.cc | 46 +++++++++++++++++++ 4 files changed, 214 insertions(+), 20 deletions(-) create mode 100644 test/boolcoder_test.cc create mode 100644 test/test.mk create mode 100644 test/test_libvpx.cc diff --git a/libs.mk b/libs.mk index 9794b3e81..bc9e888d8 100644 --- a/libs.mk +++ b/libs.mk @@ -17,6 +17,7 @@ else ASM:=.asm endif +CODEC_SRCS-yes += CHANGELOG CODEC_SRCS-yes += libs.mk include $(SRC_PATH_BARE)/vpx/vpx_codec.mk @@ -48,7 +49,6 @@ ifeq ($(CONFIG_VP8_DECODER),yes) CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_DX_SRCS)) CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_DX_EXPORTS)) CODEC_SRCS-yes += $(VP8_PREFIX)vp8dx.mk vpx/vp8.h vpx/vp8dx.h - CODEC_SRCS-$(ARCH_ARM) += $(VP8_PREFIX)vp8dx_arm.mk INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/% CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h @@ -66,6 +66,7 @@ endif ifeq ($(CONFIG_MSVS),yes) CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd) +GTEST_LIB=$(if $(CONFIG_STATIC_MSVCRT),gtestmt,gtestmd) # This variable uses deferred expansion intentionally, since the results of # $(wildcard) may change during the course of the Make. VS_PLATFORMS = $(foreach d,$(wildcard */Release/$(CODEC_LIB).lib),$(word 1,$(subst /, ,$(d)))) @@ -233,7 +234,7 @@ vpx.pc: config.mk libs.mk $(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@ $(qexec)echo 'prefix=$(PREFIX)' >> $@ $(qexec)echo 'exec_prefix=$${prefix}' >> $@ - $(qexec)echo 'libdir=$${prefix}/lib' >> $@ + $(qexec)echo 'libdir=$${prefix}/$(LIBSUBDIR)' >> $@ $(qexec)echo 'includedir=$${prefix}/include' >> $@ $(qexec)echo '' >> $@ $(qexec)echo 'Name: vpx' >> $@ @@ -241,7 +242,7 @@ vpx.pc: config.mk libs.mk $(qexec)echo 'Version: $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)' >> $@ $(qexec)echo 'Requires:' >> $@ $(qexec)echo 'Conflicts:' >> $@ - $(qexec)echo 'Libs: -L$${libdir} -lvpx' >> $@ + $(qexec)echo 'Libs: -L$${libdir} -lvpx -lm' >> $@ $(qexec)echo 'Cflags: -I$${includedir}' >> $@ INSTALL-LIBS-yes += $(LIBSUBDIR)/pkgconfig/vpx.pc INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc @@ -280,40 +281,48 @@ $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm # Calculate platform- and compiler-specific offsets for hand coded assembly # +OFFSET_PATTERN:='^[a-zA-Z0-9_]* EQU' + ifeq ($(filter icc gcc,$(TGT_CC)), $(TGT_CC)) $(BUILD_PFX)asm_com_offsets.asm: $(BUILD_PFX)$(VP8_PREFIX)common/asm_com_offsets.c.S - grep -w EQU $< | tr -d '$$\#' $(ADS2GAS) > $@ + @echo " [CREATE] $@" + $(qexec)LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@ $(BUILD_PFX)$(VP8_PREFIX)common/asm_com_offsets.c.S: $(VP8_PREFIX)common/asm_com_offsets.c CLEAN-OBJS += $(BUILD_PFX)asm_com_offsets.asm $(BUILD_PFX)$(VP8_PREFIX)common/asm_com_offsets.c.S $(BUILD_PFX)asm_enc_offsets.asm: $(BUILD_PFX)$(VP8_PREFIX)encoder/asm_enc_offsets.c.S - grep -w EQU $< | tr -d '$$\#' $(ADS2GAS) > $@ + @echo " [CREATE] $@" + $(qexec)LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@ $(BUILD_PFX)$(VP8_PREFIX)encoder/asm_enc_offsets.c.S: $(VP8_PREFIX)encoder/asm_enc_offsets.c CLEAN-OBJS += $(BUILD_PFX)asm_enc_offsets.asm $(BUILD_PFX)$(VP8_PREFIX)encoder/asm_enc_offsets.c.S $(BUILD_PFX)asm_dec_offsets.asm: $(BUILD_PFX)$(VP8_PREFIX)decoder/asm_dec_offsets.c.S - grep -w EQU $< | tr -d '$$\#' $(ADS2GAS) > $@ + @echo " [CREATE] $@" + $(qexec)LC_ALL=C grep $(OFFSET_PATTERN) $< | tr -d '$$\#' $(ADS2GAS) > $@ $(BUILD_PFX)$(VP8_PREFIX)decoder/asm_dec_offsets.c.S: $(VP8_PREFIX)decoder/asm_dec_offsets.c CLEAN-OBJS += $(BUILD_PFX)asm_dec_offsets.asm $(BUILD_PFX)$(VP8_PREFIX)decoder/asm_dec_offsets.c.S else ifeq ($(filter rvct,$(TGT_CC)), $(TGT_CC)) asm_com_offsets.asm: obj_int_extract asm_com_offsets.asm: $(VP8_PREFIX)common/asm_com_offsets.c.o - ./obj_int_extract rvds $< $(ADS2GAS) > $@ + @echo " [CREATE] $@" + $(qexec)./obj_int_extract rvds $< $(ADS2GAS) > $@ OBJS-yes += $(VP8_PREFIX)common/asm_com_offsets.c.o CLEAN-OBJS += asm_com_offsets.asm $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)asm_com_offsets.asm asm_enc_offsets.asm: obj_int_extract asm_enc_offsets.asm: $(VP8_PREFIX)encoder/asm_enc_offsets.c.o - ./obj_int_extract rvds $< $(ADS2GAS) > $@ + @echo " [CREATE] $@" + $(qexec)./obj_int_extract rvds $< $(ADS2GAS) > $@ OBJS-yes += $(VP8_PREFIX)encoder/asm_enc_offsets.c.o CLEAN-OBJS += asm_enc_offsets.asm $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)asm_enc_offsets.asm asm_dec_offsets.asm: obj_int_extract asm_dec_offsets.asm: $(VP8_PREFIX)decoder/asm_dec_offsets.c.o - ./obj_int_extract rvds $< $(ADS2GAS) > $@ + @echo " [CREATE] $@" + $(qexec)./obj_int_extract rvds $< $(ADS2GAS) > $@ OBJS-yes += $(VP8_PREFIX)decoder/asm_dec_offsets.c.o CLEAN-OBJS += asm_dec_offsets.asm $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)asm_dec_offsets.asm @@ -333,12 +342,32 @@ CODEC_DOC_SRCS += vpx/vpx_codec.h \ ## ifeq ($(CONFIG_UNIT_TESTS),yes) +LIBVPX_TEST_DATA_PATH ?= . + +include $(SRC_PATH_BARE)/test/test.mk +LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS)) +LIBVPX_TEST_BINS=./test_libvpx +LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\ + $(call enabled,LIBVPX_TEST_DATA)) +libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1) + +$(LIBVPX_TEST_DATA): + @echo " [DOWNLOAD] $@" + $(qexec)trap 'rm -f $@' INT TERM &&\ + curl -L -o $@ $(call libvpx_test_data_url,$(@F)) + +testdata:: $(LIBVPX_TEST_DATA) + $(qexec)if [ -x "$$(which sha1sum)" ]; then\ + echo "Checking test data:";\ + (cd $(LIBVPX_TEST_DATA_PATH); sha1sum -c)\ + < $(SRC_PATH_BARE)/test/test-data.sha1; \ + else\ + echo "Skipping test data integrity check, sha1sum not found.";\ + fi + ifeq ($(CONFIG_EXTERNAL_BUILD),yes) ifeq ($(CONFIG_MSVS),yes) -LIBVPX_TEST_SRCS=$(filter %_test.cc,$(call enabled,CODEC_SRCS)) -LIBVPX_TEST_BINS=$(sort $(LIBVPX_TEST_SRCS:.cc.o=)) - gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc @echo " [CREATE] $@" $(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ @@ -354,6 +383,18 @@ gtest.vcproj: $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc PROJECTS-$(CONFIG_MSVS) += gtest.vcproj +test_libvpx.vcproj: $(LIBVPX_TEST_SRCS) + @echo " [CREATE] $@" + $(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh \ + --exe \ + --target=$(TOOLCHAIN) \ + --name=test_libvpx \ + --proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \ + --ver=$(CONFIG_VS_VERSION) \ + $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ + --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ + -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ + -L. -l$(CODEC_LIB) -lwinmm -l$(GTEST_LIB) $^ ifeq ($(CONFIG_STATIC_MSVCRT),--static-crt) lib_sfx=mt else @@ -377,10 +418,9 @@ endef $(foreach proj,$(LIBVPX_TEST_BINS),\ $(eval $(call unit_test_vcproj_template,$(proj)))) -PROJECTS-$(CONFIG_MSVS) += $(foreach proj,$(LIBVPX_TEST_BINS),\ - $(notdir $(proj:.cc=.vcproj))) +PROJECTS-$(CONFIG_MSVS) += test_libvpx.vcproj -test:: +test:: testdata @set -e; for t in $(addprefix Win32/Release/,$(notdir $(LIBVPX_TEST_BINS:.cc=.exe))); do $$t; done endif else @@ -394,22 +434,25 @@ OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS) LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a $(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS) -LIBVPX_TEST_SRCS=$(filter %_test.cc,$(call enabled,CODEC_SRCS)) -LIBVPX_TEST_OBJS=$(call objs,$(LIBVPX_TEST_SRCS)) +LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS))) $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include -LIBVPX_TEST_BINS=$(sort $(LIBVPX_TEST_OBJS:.cc.o=)) OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS) +# Install test sources only if codec source is included +INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\ + $(shell find $(SRC_PATH_BARE)/third_party/googletest -type f)) +INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS) + $(foreach bin,$(LIBVPX_TEST_BINS),\ $(if $(BUILD_LIBVPX),$(eval $(bin): libvpx.a libgtest.a ))\ $(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\ - $(bin).cc.o \ + $(LIBVPX_TEST_OBJS) \ -L. -lvpx -lgtest -lpthread -lm)\ )))\ $(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\ -test:: $(LIBVPX_TEST_BINS) +test:: $(LIBVPX_TEST_BINS) testdata @set -e; for t in $(LIBVPX_TEST_BINS); do $$t; done endif diff --git a/test/boolcoder_test.cc b/test/boolcoder_test.cc new file mode 100644 index 000000000..0c7e2201f --- /dev/null +++ b/test/boolcoder_test.cc @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +extern "C" { +#include "vp8/encoder/boolhuff.h" +#include "vp8/decoder/dboolhuff.h" +} + +#include +#include +#include +#include +#include +#include + +#include "third_party/googletest/src/include/gtest/gtest.h" +#include "vpx/vpx_integer.h" + +namespace { +const int num_tests = 10; + +class ACMRandom { + public: + explicit ACMRandom(int seed) { Reset(seed); } + + void Reset(int seed) { srand(seed); } + + uint8_t Rand8(void) { return (rand() >> 8) & 0xff; } + + int PseudoUniform(int range) { return (rand() >> 8) % range; } + + int operator()(int n) { return PseudoUniform(n); } + + static int DeterministicSeed(void) { return 0xbaba; } +}; +} // namespace + +TEST(VP8, TestBitIO) { + ACMRandom rnd(ACMRandom::DeterministicSeed()); + for (int n = 0; n < num_tests; ++n) { + for (int method = 0; method <= 7; ++method) { // we generate various proba + const int bits_to_test = 1000; + uint8_t probas[bits_to_test]; + + for (int i = 0; i < bits_to_test; ++i) { + const int parity = i & 1; + probas[i] = + (method == 0) ? 0 : (method == 1) ? 255 : + (method == 2) ? 128 : + (method == 3) ? rnd.Rand8() : + (method == 4) ? (parity ? 0 : 255) : + // alternate between low and high proba: + (method == 5) ? (parity ? rnd(128) : 255 - rnd(128)) : + (method == 6) ? + (parity ? rnd(64) : 255 - rnd(64)) : + (parity ? rnd(32) : 255 - rnd(32)); + } + for (int bit_method = 0; bit_method <= 3; ++bit_method) { + const int random_seed = 6432; + const int buffer_size = 10000; + ACMRandom bit_rnd(random_seed); + BOOL_CODER bw; + uint8_t bw_buffer[buffer_size]; + vp8_start_encode(&bw, bw_buffer); + + int bit = (bit_method == 0) ? 0 : (bit_method == 1) ? 1 : 0; + for (int i = 0; i < bits_to_test; ++i) { + if (bit_method == 2) { + bit = (i & 1); + } else if (bit_method == 3) { + bit = bit_rnd(2); + } + vp8_encode_bool(&bw, bit, static_cast(probas[i])); + } + + vp8_stop_encode(&bw); + + BOOL_DECODER br; + vp8dx_start_decode(&br, bw_buffer, buffer_size); + bit_rnd.Reset(random_seed); + for (int i = 0; i < bits_to_test; ++i) { + if (bit_method == 2) { + bit = (i & 1); + } else if (bit_method == 3) { + bit = bit_rnd(2); + } + GTEST_ASSERT_EQ(vp8dx_decode_bool(&br, probas[i]), bit) + << "pos: "<< i << " / " << bits_to_test + << " bit_method: " << bit_method + << " method: " << method; + } + } + } + } +} diff --git a/test/test.mk b/test/test.mk new file mode 100644 index 000000000..bfef823bd --- /dev/null +++ b/test/test.mk @@ -0,0 +1,3 @@ +LIBVPX_TEST_SRCS-yes += test.mk +LIBVPX_TEST_SRCS-yes += boolcoder_test.cc +LIBVPX_TEST_SRCS-yes += test_libvpx.cc diff --git a/test/test_libvpx.cc b/test/test_libvpx.cc new file mode 100644 index 000000000..9b9e08c86 --- /dev/null +++ b/test/test_libvpx.cc @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include +#include "vpx_config.h" +#if ARCH_X86 || ARCH_X86_64 +extern "C" { +#include "vpx_ports/x86.h" +} +#endif +#include "third_party/googletest/src/include/gtest/gtest.h" + +static void append_gtest_filter(const char *str) +{ + std::string filter = ::testing::FLAGS_gtest_filter; + filter += str; + ::testing::FLAGS_gtest_filter = filter; +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + +#if ARCH_X86 || ARCH_X86_64 + int simd_caps = x86_simd_caps(); + if(!(simd_caps & HAS_MMX)) + append_gtest_filter(":-MMX/*"); + if(!(simd_caps & HAS_SSE)) + append_gtest_filter(":-SSE/*"); + if(!(simd_caps & HAS_SSE2)) + append_gtest_filter(":-SSE2/*"); + if(!(simd_caps & HAS_SSE3)) + append_gtest_filter(":-SSE3/*"); + if(!(simd_caps & HAS_SSSE3)) + append_gtest_filter(":-SSSE3/*"); + if(!(simd_caps & HAS_SSE4_1)) + append_gtest_filter(":-SSE4_1/*"); +#endif + + return RUN_ALL_TESTS(); +} -- 2.40.0