From 4f91b6f8739adbf96e9f9129603e2cedde99d43a Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Mon, 16 Oct 2017 14:47:07 +0200 Subject: [PATCH] add test support Most of the boilerplate and the states test has been copied from gst-plugins-good. https://bugzilla.gnome.org/show_bug.cgi?id=789094 --- .gitignore | 4 + Makefile.am | 2 +- config/meson.build | 19 ++- configure.ac | 4 +- meson.build | 6 + tests/Makefile.am | 9 ++ tests/check/.gitignore | 2 + tests/check/Makefile.am | 45 +++++++ tests/check/generic/.gitignore | 3 + tests/check/generic/states.c | 225 +++++++++++++++++++++++++++++++++ tests/check/meson.build | 56 ++++++++ tests/meson.build | 4 + 12 files changed, 373 insertions(+), 6 deletions(-) create mode 100644 tests/Makefile.am create mode 100644 tests/check/.gitignore create mode 100644 tests/check/Makefile.am create mode 100644 tests/check/generic/.gitignore create mode 100644 tests/check/generic/states.c create mode 100644 tests/check/meson.build create mode 100644 tests/meson.build diff --git a/.gitignore b/.gitignore index 74b4d309e6..b41e443390 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,7 @@ tools/listcomponents /m4/lt~obsolete.m4 Makefile.in Makefile + +test-driver +*.log +*.trs diff --git a/Makefile.am b/Makefile.am index 22c602550c..b28012ecb2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = common omx tools config m4 +SUBDIRS = common omx tools config m4 tests if BUILD_EXAMPLES SUBDIRS += examples diff --git a/config/meson.build b/config/meson.build index 9e5d1441ce..1068c6d9c6 100644 --- a/config/meson.build +++ b/config/meson.build @@ -1,9 +1,20 @@ if omx_target == 'rpi' - subdir ('rpi') + sub = 'rpi' elif omx_target == 'bellagio' - subdir ('bellagio') + sub = 'bellagio' elif omx_target == 'zynqultrascaleplus' - subdir ('zynqultrascaleplus') + sub = 'zynqultrascaleplus' elif omx_target == 'tizonia' - subdir ('tizonia') + sub = 'tizonia' +else + # No config file defined for the 'generic' target + sub = '' +endif + +if sub != '' + subdir (sub) + # Used by tests to load the proper conf file + omx_config_dir = join_paths (meson.current_source_dir(), sub) +else + omx_config_dir = '' endif diff --git a/configure.ac b/configure.ac index 1b65c1f67d..4a19440af6 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,7 @@ AC_INIT(GStreamer OpenMAX Plug-ins, 1.13.0.1, AG_GST_INIT dnl initialize automake -AM_INIT_AUTOMAKE([-Wno-portability 1.11 no-dist-gzip dist-xz tar-ustar]) +AM_INIT_AUTOMAKE([-Wno-portability 1.11 no-dist-gzip dist-xz tar-ustar subdir-objects]) dnl define PACKAGE_VERSION_* variables AS_VERSION @@ -411,6 +411,8 @@ config/zynqultrascaleplus/Makefile examples/Makefile examples/egl/Makefile m4/Makefile +tests/Makefile +tests/check/Makefile ) AC_OUTPUT diff --git a/meson.build b/meson.build index 6917826c88..12f3ec1425 100644 --- a/meson.build +++ b/meson.build @@ -153,6 +153,11 @@ gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req, gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req, fallback : ['gst-plugins-bad', 'gstgl_dep'], required : false) +if host_machine.system() != 'windows' + gstcheck_dep = dependency('gstreamer-check-1.0', version : gst_req, + fallback : ['gstreamer', 'gst_check_dep']) +endif + libm = cc.find_library('m', required : false) glib_dep = dependency('glib-2.0', version : glib_req) gio_dep = dependency('gio-2.0', version : glib_req) @@ -305,6 +310,7 @@ subdir('config') subdir('examples') subdir('omx') subdir('tools') +subdir('tests') python3 = find_program('python3') run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000000..dfe3b5a150 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,9 @@ +if HAVE_GST_CHECK +SUBDIRS_CHECK = check +else +SUBDIRS_CHECK = +endif + +SUBDIRS = $(SUBDIRS_CHECK) + +DIST_SUBDIRS = check diff --git a/tests/check/.gitignore b/tests/check/.gitignore new file mode 100644 index 0000000000..789588b65e --- /dev/null +++ b/tests/check/.gitignore @@ -0,0 +1,2 @@ +test-registry.* +orc diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am new file mode 100644 index 0000000000..6b0ffe8134 --- /dev/null +++ b/tests/check/Makefile.am @@ -0,0 +1,45 @@ +include $(top_srcdir)/common/check.mak + +CHECK_REGISTRY = $(top_builddir)/tests/check/test-registry.reg +TEST_FILES_DIRECTORY = $(top_srcdir)/tests/files + +REGISTRY_ENVIRONMENT = \ + GST_REGISTRY_1_0=$(CHECK_REGISTRY) + +if USE_OMX_TARGET_BELLAGIO + OMX_CONFIG_DIR = $(top_srcdir)/config/bellagio +endif +if USE_OMX_TARGET_RPI + OMX_CONFIG_DIR = $(top_srcdir)/config/rpi +endif +if USE_OMX_TARGET_ZYNQ_USCALE_PLUS + OMX_CONFIG_DIR = $(top_srcdir)/config/zynqultrascaleplus +endif +if USE_OMX_TARGET_TIZONIA + OMX_CONFIG_DIR = $(top_srcdir)/config/tizonia +endif + +AM_TESTS_ENVIRONMENT += \ + $(REGISTRY_ENVIRONMENT) \ + GST_PLUGIN_SYSTEM_PATH_1_0= \ + GST_PLUGIN_PATH_1_0=$(top_builddir)/omx:$(GSTPB_PLUGINS_DIR):$(GST_PLUGINS_DIR) \ + GST_PLUGIN_LOADING_WHITELIST="gstreamer@$(GST_PLUGINS_DIR):gst-plugins-base@$(GSTPB_PLUGINS_DIR):gst-omx@$(top_builddir)" \ + GST_STATE_IGNORE_ELEMENTS="" \ + GST_OMX_CONFIG_DIR=$(OMX_CONFIG_DIR) + +# the core dumps of some machines have PIDs appended +CLEANFILES = core.* test-registry.* + +clean-local: clean-local-check +distclean-local: distclean-local-orc + +check_PROGRAMS = \ + generic/states + +TESTS = $(check_PROGRAMS) + +AM_CFLAGS = $(GST_OBJ_CFLAGS) $(GST_CHECK_CFLAGS) $(CHECK_CFLAGS) \ + $(GST_OPTION_CFLAGS) $(GST_CFLAGS) -DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \ + -DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \ + -UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS $(PTHREAD_CFLAGS) +LDADD = $(GST_OBJ_LIBS) $(GST_CHECK_LIBS) $(CHECK_LIBS) diff --git a/tests/check/generic/.gitignore b/tests/check/generic/.gitignore new file mode 100644 index 0000000000..8d9bd1f6a7 --- /dev/null +++ b/tests/check/generic/.gitignore @@ -0,0 +1,3 @@ +.dirstamp +index +states diff --git a/tests/check/generic/states.c b/tests/check/generic/states.c new file mode 100644 index 0000000000..415ac543c2 --- /dev/null +++ b/tests/check/generic/states.c @@ -0,0 +1,225 @@ +/* GStreamer + * + * unit test for state changes on all elements + * + * Copyright (C) <2005> Thomas Vander Stichele + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +static GList *elements = NULL; + +static void +setup (void) +{ + GList *features, *f; + GList *plugins, *p; + gchar **ignorelist = NULL; + const gchar *STATE_IGNORE_ELEMENTS = NULL; + GstRegistry *def; + + GST_DEBUG ("getting elements for package %s", PACKAGE); + STATE_IGNORE_ELEMENTS = g_getenv ("GST_STATE_IGNORE_ELEMENTS"); + if (!g_getenv ("GST_NO_STATE_IGNORE_ELEMENTS") && STATE_IGNORE_ELEMENTS) { + GST_DEBUG ("Will ignore element factories: '%s'", STATE_IGNORE_ELEMENTS); + ignorelist = g_strsplit (STATE_IGNORE_ELEMENTS, " ", 0); + } + + def = gst_registry_get (); + + plugins = gst_registry_get_plugin_list (def); + + for (p = plugins; p; p = p->next) { + GstPlugin *plugin = p->data; + + if (strcmp (gst_plugin_get_source (plugin), PACKAGE) != 0) + continue; + + features = + gst_registry_get_feature_list_by_plugin (def, + gst_plugin_get_name (plugin)); + + for (f = features; f; f = f->next) { + GstPluginFeature *feature = f->data; + const gchar *name = gst_plugin_feature_get_name (feature); + gboolean ignore = FALSE; + + if (!GST_IS_ELEMENT_FACTORY (feature)) + continue; + + if (ignorelist) { + gchar **s; + + for (s = ignorelist; s && *s; ++s) { + if (g_str_has_prefix (name, *s)) { + GST_DEBUG ("ignoring element %s", name); + ignore = TRUE; + } + } + if (ignore) + continue; + } + + GST_DEBUG ("adding element %s", name); + elements = g_list_prepend (elements, (gpointer) g_strdup (name)); + } + gst_plugin_feature_list_free (features); + } + gst_plugin_list_free (plugins); + g_strfreev (ignorelist); +} + +static void +teardown (void) +{ + GList *e; + + for (e = elements; e; e = e->next) { + g_free (e->data); + } + g_list_free (elements); + elements = NULL; +} + + +GST_START_TEST (test_state_changes_up_and_down_seq) +{ + GstElement *element; + GList *e; + + for (e = elements; e; e = e->next) { + const gchar *name = e->data; + + GST_INFO ("testing element %s", name); + element = gst_element_factory_make (name, name); + fail_if (element == NULL, "Could not make element from factory %s", name); + + if (GST_IS_PIPELINE (element)) { + GST_DEBUG ("element %s is a pipeline", name); + } + + gst_element_set_state (element, GST_STATE_READY); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_PLAYING); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_READY); + gst_element_set_state (element, GST_STATE_NULL); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_READY); + gst_element_set_state (element, GST_STATE_PLAYING); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (element)); + } +} + +GST_END_TEST; + +GST_START_TEST (test_state_changes_up_seq) +{ + GstElement *element; + GList *e; + + for (e = elements; e; e = e->next) { + const gchar *name = e->data; + + GST_INFO ("testing element %s", name); + element = gst_element_factory_make (name, name); + fail_if (element == NULL, "Could not make element from factory %s", name); + + if (GST_IS_PIPELINE (element)) { + GST_DEBUG ("element %s is a pipeline", name); + } + + gst_element_set_state (element, GST_STATE_READY); + + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_READY); + + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_PLAYING); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_READY); + + gst_element_set_state (element, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (element)); + } +} + +GST_END_TEST; + +GST_START_TEST (test_state_changes_down_seq) +{ + GstElement *element; + GList *e; + + for (e = elements; e; e = e->next) { + const gchar *name = e->data; + + GST_INFO ("testing element %s", name); + element = gst_element_factory_make (name, name); + fail_if (element == NULL, "Could not make element from factory %s", name); + + if (GST_IS_PIPELINE (element)) { + GST_DEBUG ("element %s is a pipeline", name); + } + + gst_element_set_state (element, GST_STATE_READY); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_PLAYING); + + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_PLAYING); + + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_READY); + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_PLAYING); + + gst_element_set_state (element, GST_STATE_PAUSED); + gst_element_set_state (element, GST_STATE_READY); + gst_element_set_state (element, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (element)); + } +} + +GST_END_TEST; + + +static Suite * +states_suite (void) +{ + Suite *s = suite_create ("states_omx"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_checked_fixture (tc_chain, setup, teardown); + tcase_add_test (tc_chain, test_state_changes_up_and_down_seq); + tcase_add_test (tc_chain, test_state_changes_up_seq); + tcase_add_test (tc_chain, test_state_changes_down_seq); + + return s; +} + +GST_CHECK_MAIN (states); diff --git a/tests/check/meson.build b/tests/check/meson.build new file mode 100644 index 0000000000..b43a51709d --- /dev/null +++ b/tests/check/meson.build @@ -0,0 +1,56 @@ +# name, condition when to skip the test and extra dependencies +omx_tests = [ + [ 'generic/states' ], +] + +test_defines = [ + '-UG_DISABLE_ASSERT', + '-UG_DISABLE_CAST_CHECKS', + '-DGST_CHECK_TEST_ENVIRONMENT_BEACON="GST_PLUGIN_LOADING_WHITELIST"', +] + +pluginsdirs = [] +if gst_dep.type_name() == 'pkgconfig' + pbase = dependency('gstreamer-plugins-base-' + api_version, required : false) + pluginsdirs = [gst_dep.get_pkgconfig_variable('pluginsdir'), + pbase.get_pkgconfig_variable('pluginsdir')] +endif + +state_ignore_elements='' + +# FIXME: check, also + PTHREAD_CFLAGS +test_deps = [gst_dep, gstbase_dep, glib_dep, gstcheck_dep] + +# FIXME: add valgrind suppression common/gst.supp gst-plugins-good.supp +foreach t : omx_tests + fname = '@0@.c'.format(t.get(0)) + test_name = t.get(0).underscorify() + extra_deps = [ ] + if t.length() == 3 + extra_deps = t.get(2) + skip_test = t.get(1) + elif t.length() == 2 + skip_test = t.get(1) + else + skip_test = false + endif + if not skip_test + env = environment() + env.set('GST_PLUGIN_SYSTEM_PATH_1_0', '') + env.set('GST_STATE_IGNORE_ELEMENTS', state_ignore_elements) + env.set('CK_DEFAULT_TIMEOUT', '20') + env.set('GST_PLUGIN_LOADING_WHITELIST', 'gstreamer', 'gst-plugins-base', + 'gst-plugins-good', 'gst-omx@' + meson.build_root(), separator: ':') + env.set('GST_PLUGIN_PATH_1_0', [meson.build_root()] + pluginsdirs) + env.set('GSETTINGS_BACKEND', 'memory') + env.set('GST_OMX_CONFIG_DIR', omx_config_dir) + + env.set('GST_REGISTRY', '@0@/@1@.registry'.format(meson.current_build_dir(), test_name)) + exe = executable(test_name, fname, + include_directories : [configinc], + c_args : ['-DHAVE_CONFIG_H=1' ] + test_defines, + dependencies : [libm] + test_deps + extra_deps, + ) + test(test_name, exe, env: env, timeout: 3 * 60) + endif +endforeach diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000000..76b079162c --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,4 @@ +# FIXME: make check work on windows +if host_machine.system() != 'windows' +subdir('check') +endif