Variables that are "static" don't need to be marked like this.
+Testsuite
+---------
+
+You can run the libsigrok testsuite using:
+
+ $ make check
+
+
Release engineering
-------------------
AM_CPPFLAGS = -I$(top_srcdir)
-SUBDIRS = contrib hardware input output
+SUBDIRS = contrib hardware input output tests
lib_LTLIBRARIES = libsigrok.la
- libftdi >= 0.16 (optional, used by some drivers)
- libudev >= 151 (optional, used by some drivers)
- libasound / alsa-lib >= 1.0 (optional, only used by the alsa driver)
+ - check >= 0.9.4 (optional, only needed to run unit tests)
Building and installing
SR_PKGLIBS="$SR_PKGLIBS alsa"])
fi
+# The Check unit testing framework is optional.
+PKG_CHECK_MODULES([check], [check >= 0.9.4],
+ [have_check="yes"; CFLAGS="$CFLAGS $check_CFLAGS";
+ LIBS="$LIBS $check_LIBS"], [have_check="no"])
+AM_CONDITIONAL(HAVE_CHECK, test x"$have_check" = "xyes")
+
# EZUSB FX2 firmware helper code is only needed for some hardware drivers.
AM_CONDITIONAL(NEED_EZUSB, \
test "x$LA_FX2LAFW" != xno \
output/text/Makefile
libsigrok.pc
contrib/Makefile
+ tests/Makefile
])
AC_OUTPUT
echo
# Note: This only works for libs with pkg-config integration.
-for lib in "glib-2.0" "libusb-1.0" "libzip" "libftdi" "libudev" "alsa"; do
+for lib in "glib-2.0" "libusb-1.0" "libzip" "libftdi" "libudev" "alsa" "check"; do
if `$PKG_CONFIG --exists $lib`; then
ver=`$PKG_CONFIG --modversion $lib`
answer="yes ($ver)"
--- /dev/null
+##
+## This file is part of the libsigrok project.
+##
+## Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program 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 General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+if HAVE_CHECK
+
+TESTS = check_main
+
+check_PROGRAMS = ${TESTS}
+
+check_main_SOURCES = \
+ $(top_builddir)/libsigrok.h \
+ lib.c \
+ lib.h \
+ check_main.c \
+ check_core.c \
+ check_strutil.c \
+ check_driver_all.c
+
+check_main_CFLAGS = @check_CFLAGS@
+
+check_main_LDADD = $(top_builddir)/libsigrok.la @check_LIBS@
+
+endif
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <check.h>
+#include "../libsigrok.h"
+
+/*
+ * Check various basic init related things.
+ *
+ * - Check whether an sr_init() call with a proper sr_ctx works.
+ * If it returns != SR_OK (or segfaults) this test will fail.
+ * The sr_init() call (among other things) also runs sanity checks on
+ * all libsigrok hardware drivers and errors out upon issues.
+ *
+ * - Check whether a subsequent sr_exit() with that sr_ctx works.
+ * If it returns != SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_init_exit)
+{
+ int ret;
+ struct sr_context *sr_ctx;
+
+ ret = sr_init(&sr_ctx);
+ fail_unless(ret == SR_OK, "sr_init() failed: %d.", ret);
+ ret = sr_exit(sr_ctx);
+ fail_unless(ret == SR_OK, "sr_exit() failed: %d.", ret);
+}
+END_TEST
+
+/*
+ * Check whether two nested sr_init() and sr_exit() calls work.
+ * The two functions have two different contexts.
+ * If any function returns != SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_init_exit_2)
+{
+ int ret;
+ struct sr_context *sr_ctx1, *sr_ctx2;
+
+ ret = sr_init(&sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_init() 1 failed: %d.", ret);
+ ret = sr_init(&sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_init() 2 failed: %d.", ret);
+ ret = sr_exit(sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_exit() 2 failed: %d.", ret);
+ ret = sr_exit(sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_exit() 1 failed: %d.", ret);
+}
+END_TEST
+
+/*
+ * Same as above, but sr_exit() in the "wrong" order.
+ * This should work fine, it's not a bug to do this.
+ */
+START_TEST(test_init_exit_2_reverse)
+{
+ int ret;
+ struct sr_context *sr_ctx1, *sr_ctx2;
+
+ ret = sr_init(&sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_init() 1 failed: %d.", ret);
+ ret = sr_init(&sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_init() 2 failed: %d.", ret);
+ ret = sr_exit(sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_exit() 1 failed: %d.", ret);
+ ret = sr_exit(sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_exit() 2 failed: %d.", ret);
+}
+END_TEST
+
+/*
+ * Check whether three nested sr_init() and sr_exit() calls work.
+ * The three functions have three different contexts.
+ * If any function returns != SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_init_exit_3)
+{
+ int ret;
+ struct sr_context *sr_ctx1, *sr_ctx2, *sr_ctx3;
+
+ ret = sr_init(&sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_init() 1 failed: %d.", ret);
+ ret = sr_init(&sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_init() 2 failed: %d.", ret);
+ ret = sr_init(&sr_ctx3);
+ fail_unless(ret == SR_OK, "sr_init() 3 failed: %d.", ret);
+ ret = sr_exit(sr_ctx3);
+ fail_unless(ret == SR_OK, "sr_exit() 3 failed: %d.", ret);
+ ret = sr_exit(sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_exit() 2 failed: %d.", ret);
+ ret = sr_exit(sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_exit() 1 failed: %d.", ret);
+}
+END_TEST
+
+/*
+ * Same as above, but sr_exit() in the "wrong" order.
+ * This should work fine, it's not a bug to do this.
+ */
+START_TEST(test_init_exit_3_reverse)
+{
+ int ret;
+ struct sr_context *sr_ctx1, *sr_ctx2, *sr_ctx3;
+
+ ret = sr_init(&sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_init() 1 failed: %d.", ret);
+ ret = sr_init(&sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_init() 2 failed: %d.", ret);
+ ret = sr_init(&sr_ctx3);
+ fail_unless(ret == SR_OK, "sr_init() 3 failed: %d.", ret);
+ ret = sr_exit(sr_ctx1);
+ fail_unless(ret == SR_OK, "sr_exit() 1 failed: %d.", ret);
+ ret = sr_exit(sr_ctx2);
+ fail_unless(ret == SR_OK, "sr_exit() 2 failed: %d.", ret);
+ ret = sr_exit(sr_ctx3);
+ fail_unless(ret == SR_OK, "sr_exit() 3 failed: %d.", ret);
+}
+END_TEST
+
+/* Check whether sr_init(NULL) fails as it should. */
+START_TEST(test_init_null)
+{
+ int ret;
+
+ ret = sr_log_loglevel_set(SR_LOG_NONE);
+ fail_unless(ret == SR_OK, "sr_log_loglevel_set() failed: %d.", ret);
+
+ ret = sr_init(NULL);
+ fail_unless(ret != SR_OK, "sr_init(NULL) should have failed.");
+}
+END_TEST
+
+/* Check whether sr_exit(NULL) fails as it should. */
+START_TEST(test_exit_null)
+{
+ int ret;
+
+ ret = sr_log_loglevel_set(SR_LOG_NONE);
+ fail_unless(ret == SR_OK, "sr_log_loglevel_set() failed: %d.", ret);
+
+ ret = sr_exit(NULL);
+ fail_unless(ret != SR_OK, "sr_exit(NULL) should have failed.");
+}
+END_TEST
+
+Suite *suite_core(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("core");
+
+ tc = tcase_create("init_exit");
+ tcase_add_test(tc, test_init_exit);
+ tcase_add_test(tc, test_init_exit_2);
+ tcase_add_test(tc, test_init_exit_2_reverse);
+ tcase_add_test(tc, test_init_exit_3);
+ tcase_add_test(tc, test_init_exit_3_reverse);
+ tcase_add_test(tc, test_init_null);
+ tcase_add_test(tc, test_exit_null);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <check.h>
+#include "../libsigrok.h"
+#include "lib.h"
+
+struct sr_context *sr_ctx;
+
+static void setup(void)
+{
+ int ret;
+
+ ret = sr_init(&sr_ctx);
+ fail_unless(ret == SR_OK, "sr_init() failed: %d.", ret);
+}
+
+static void teardown(void)
+{
+ int ret;
+
+ ret = sr_exit(sr_ctx);
+ fail_unless(ret == SR_OK, "sr_exit() failed: %d.", ret);
+}
+
+/* Check whether at least one driver is available. */
+START_TEST(test_driver_available)
+{
+ struct sr_dev_driver **drivers;
+
+ drivers = sr_driver_list();
+ fail_unless(drivers != NULL, "No drivers found.");
+}
+END_TEST
+
+/* Check whether initializing all drivers works. */
+START_TEST(test_driver_init_all)
+{
+ srtest_driver_init_all(sr_ctx);
+}
+END_TEST
+
+/*
+ * Check whether setting a samplerate works.
+ *
+ * Additionally, this also checks whether SR_CONF_SAMPLERATE can be both
+ * set and read back properly.
+ */
+START_TEST(test_config_get_set_samplerate)
+{
+ /*
+ * Note: This currently only works for the demo driver.
+ * For other drivers, a scan is needed and the respective
+ * hardware must be attached to the host running the testsuite.
+ */
+ srtest_check_samplerate(sr_ctx, "demo", SR_KHZ(19));
+}
+END_TEST
+
+Suite *suite_driver_all(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("driver-all");
+
+ tc = tcase_create("config");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_driver_available);
+ tcase_add_test(tc, test_driver_init_all);
+ tcase_add_test(tc, test_config_get_set_samplerate);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <check.h>
+#include "../libsigrok.h"
+
+Suite *suite_core(void);
+Suite *suite_strutil(void);
+Suite *suite_driver_all(void);
+
+int main(void)
+{
+ int ret;
+ Suite *s;
+ SRunner *srunner;
+
+ s = suite_create("mastersuite");
+ srunner = srunner_create(s);
+
+ /* Add all testsuites to the master suite. */
+ srunner_add_suite(srunner, suite_core());
+ srunner_add_suite(srunner, suite_strutil());
+ srunner_add_suite(srunner, suite_driver_all());
+
+ srunner_run_all(srunner, CK_VERBOSE);
+ ret = srunner_ntests_failed(srunner);
+ srunner_free(srunner);
+
+ return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <check.h>
+#include "../libsigrok.h"
+
+struct sr_context *sr_ctx;
+
+static void setup(void)
+{
+ int ret;
+
+ ret = sr_init(&sr_ctx);
+ fail_unless(ret == SR_OK, "sr_init() failed: %d.", ret);
+}
+
+static void teardown(void)
+{
+ int ret;
+
+ ret = sr_exit(sr_ctx);
+ fail_unless(ret == SR_OK, "sr_exit() failed: %d.", ret);
+}
+
+static void test_samplerate(uint64_t samplerate, const char *expected)
+{
+ char *s;
+
+ s = sr_samplerate_string(samplerate);
+ fail_unless(s != NULL);
+ fail_unless(!strcmp(s, expected),
+ "Invalid result for '%s': %s.", expected, s);
+ g_free(s);
+}
+
+/*
+ * Check various inputs for sr_samplerate_string():
+ *
+ * - One, two, or three digit results (e.g. 5/55/555 MHz).
+ * - Results which contain commas (e.g. 1.234 / 12.34 / 123.4 kHz).
+ * - Results with zeroes right after the comma (e.g. 1.034 Hz).
+ * See also: http://sigrok.org/bugzilla/show_bug.cgi?id=73
+ * - Results with trailing zeroes (e.g. 1.230 kHz).
+ * (This is currently allowed, but might be changed later)
+ * - Results with zeroes in the middle (e.g. 1.204 kHz).
+ * - All of the above, but using SR_MHZ() and friends.
+ * See also: http://sigrok.org/bugzilla/show_bug.cgi?id=72
+ *
+ * All of the above tests are done for the Hz/kHz/MHz/GHz ranges.
+ */
+
+START_TEST(test_hz)
+{
+ test_samplerate(0, "0 Hz");
+ test_samplerate(1, "1 Hz");
+ test_samplerate(23, "23 Hz");
+ test_samplerate(644, "644 Hz");
+ test_samplerate(604, "604 Hz");
+ test_samplerate(550, "550 Hz");
+
+ /* Again, but now using SR_HZ(). */
+ test_samplerate(SR_HZ(0), "0 Hz");
+ test_samplerate(SR_HZ(1), "1 Hz");
+ test_samplerate(SR_HZ(23), "23 Hz");
+ test_samplerate(SR_HZ(644), "644 Hz");
+ test_samplerate(SR_HZ(604), "604 Hz");
+ test_samplerate(SR_HZ(550), "550 Hz");
+}
+END_TEST
+
+START_TEST(test_khz)
+{
+ test_samplerate(1000, "1 kHz");
+ test_samplerate(99000, "99 kHz");
+ test_samplerate(225000, "225 kHz");
+ test_samplerate(1234, "1.234 kHz");
+ test_samplerate(12345, "12.345 kHz");
+ test_samplerate(123456, "123.456 kHz");
+ test_samplerate(1034, "1.034 kHz");
+ test_samplerate(1004, "1.004 kHz");
+ test_samplerate(1230, "1.230 kHz");
+
+ /* Again, but now using SR_KHZ(). */
+ test_samplerate(SR_KHZ(1), "1 kHz");
+ test_samplerate(SR_KHZ(99), "99 kHz");
+ test_samplerate(SR_KHZ(225), "225 kHz");
+ test_samplerate(SR_KHZ(1.234), "1.234 kHz");
+ test_samplerate(SR_KHZ(12.345), "12.345 kHz");
+ test_samplerate(SR_KHZ(123.456), "123.456 kHz");
+ test_samplerate(SR_KHZ(1.204), "1.204 kHz");
+ test_samplerate(SR_KHZ(1.034), "1.034 kHz");
+ test_samplerate(SR_KHZ(1.004), "1.004 kHz");
+ test_samplerate(SR_KHZ(1.230), "1.230 kHz");
+}
+END_TEST
+
+START_TEST(test_mhz)
+{
+ test_samplerate(1000000, "1 MHz");
+ test_samplerate(28000000, "28 MHz");
+ test_samplerate(775000000, "775 MHz");
+ test_samplerate(1234567, "1.234567 MHz");
+ test_samplerate(12345678, "12.345678 MHz");
+ test_samplerate(123456789, "123.456789 MHz");
+ test_samplerate(1230007, "1.230007 MHz");
+ test_samplerate(1034567, "1.034567 MHz");
+ test_samplerate(1000007, "1.000007 MHz");
+ test_samplerate(1234000, "1.234000 MHz");
+
+ /* Again, but now using SR_MHZ(). */
+ test_samplerate(SR_MHZ(1), "1 MHz");
+ test_samplerate(SR_MHZ(28), "28 MHz");
+ test_samplerate(SR_MHZ(775), "775 MHz");
+ test_samplerate(SR_MHZ(1.234567), "1.234567 MHz");
+ test_samplerate(SR_MHZ(12.345678), "12.345678 MHz");
+ test_samplerate(SR_MHZ(123.456789), "123.456789 MHz");
+ test_samplerate(SR_MHZ(1.230007), "1.230007 MHz");
+ test_samplerate(SR_MHZ(1.034567), "1.034567 MHz");
+ test_samplerate(SR_MHZ(1.000007), "1.000007 MHz");
+ test_samplerate(SR_MHZ(1.234000), "1.234000 MHz");
+}
+END_TEST
+
+START_TEST(test_ghz)
+{
+ /* Note: Numbers > 2^32 need a ULL suffix. */
+
+ test_samplerate(1000000000, "1 GHz");
+ test_samplerate(5000000000ULL, "5 GHz");
+ test_samplerate(72000000000ULL, "72 GHz");
+ test_samplerate(388000000000ULL, "388 GHz");
+ test_samplerate(4417594444ULL, "4.417594444 GHz");
+ test_samplerate(44175944444ULL, "44.175944444 GHz");
+ test_samplerate(441759444441ULL, "441.759444441 GHz");
+ test_samplerate(441759000001ULL, "441.759000001 GHz");
+ test_samplerate(441050000000ULL, "441.05 GHz");
+ test_samplerate(441000000005ULL, "441.000000005 GHz");
+ test_samplerate(441500000000ULL, "441.500000000 GHz");
+
+ /* Again, but now using SR_GHZ(). */
+ test_samplerate(SR_GHZ(1), "1 GHz");
+ test_samplerate(SR_GHZ(5), "5 GHz");
+ test_samplerate(SR_GHZ(72), "72 GHz");
+ test_samplerate(SR_GHZ(388), "388 GHz");
+ test_samplerate(SR_GHZ(4.417594444), "4.417594444 GHz");
+ test_samplerate(SR_GHZ(44.175944444), "44.175944444 GHz");
+ test_samplerate(SR_GHZ(441.759444441), "441.759444441 GHz");
+ test_samplerate(SR_GHZ(441.759000001), "441.759000001 GHz");
+ test_samplerate(SR_GHZ(441.050000000), "441.05 GHz");
+ test_samplerate(SR_GHZ(441.000000005), "441.000000005 GHz");
+ test_samplerate(SR_GHZ(441.500000000), "441.500000000 GHz");
+
+ /* Now check the biggest-possible samplerate (2^64 Hz). */
+ test_samplerate(18446744073709551615ULL, "18446744073.709551615 GHz");
+ test_samplerate(SR_GHZ(18446744073ULL), "18446744073 GHz");
+}
+END_TEST
+
+Suite *suite_strutil(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("strutil");
+
+ tc = tcase_create("sr_samplerate_string");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_hz);
+ tcase_add_test(tc, test_khz);
+ tcase_add_test(tc, test_mhz);
+ tcase_add_test(tc, test_ghz);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <check.h>
+#include "../libsigrok.h"
+
+/* Get a libsigrok driver by name. */
+struct sr_dev_driver *srtest_driver_get(const char *drivername)
+{
+ struct sr_dev_driver **drivers, *driver = NULL;
+ int i;
+
+ drivers = sr_driver_list();
+ fail_unless(drivers != NULL, "No drivers found.");
+
+ for (i = 0; drivers[i]; i++) {
+ if (strcmp(drivers[i]->name, drivername))
+ continue;
+ driver = drivers[i];
+ }
+ fail_unless(driver != NULL, "Driver '%s' not found.", drivername);
+
+ return driver;
+}
+
+/* Initialize a libsigrok driver. */
+void srtest_driver_init(struct sr_context *sr_ctx, struct sr_dev_driver *driver)
+{
+ int ret;
+
+ ret = sr_driver_init(sr_ctx, driver);
+ fail_unless(ret == SR_OK, "Failed to init '%s' driver: %d.",
+ driver->name, ret);
+}
+
+/* Initialize all libsigrok drivers. */
+void srtest_driver_init_all(struct sr_context *sr_ctx)
+{
+ struct sr_dev_driver **drivers, *driver;
+ int i, ret;
+
+ drivers = sr_driver_list();
+ fail_unless(drivers != NULL, "No drivers found.");
+
+ for (i = 0; drivers[i]; i++) {
+ driver = drivers[i];
+ ret = sr_driver_init(sr_ctx, driver);
+ fail_unless(ret == SR_OK, "Failed to init '%s' driver: %d.",
+ driver->name, ret);
+ }
+}
+
+/* Set the samplerate for the respective driver to the specified value. */
+void srtest_set_samplerate(struct sr_dev_driver *driver, uint64_t samplerate)
+{
+ int ret;
+ struct sr_dev_inst *sdi;
+
+ sdi = g_slist_nth_data(driver->priv, 0);
+
+ ret = driver->config_set(SR_CONF_SAMPLERATE, &samplerate, sdi);
+ fail_unless(ret == SR_OK, "%s: Failed to set SR_CONF_SAMPLERATE: %d.",
+ driver->name, ret);
+}
+
+/* Get the respective driver's current samplerate. */
+uint64_t srtest_get_samplerate(struct sr_dev_driver *driver)
+{
+ int ret;
+ uint64_t *samplerate;
+ struct sr_dev_inst *sdi;
+
+ sdi = g_slist_nth_data(driver->priv, 0);
+
+ ret = driver->config_get(SR_CONF_SAMPLERATE,
+ (const void **)&samplerate, sdi);
+ fail_unless(ret == SR_OK, "%s: Failed to get SR_CONF_SAMPLERATE: %d.",
+ driver->name, ret);
+ fail_unless(samplerate != NULL);
+
+ return *samplerate;
+}
+
+/* Check whether the respective driver can set/get the correct samplerate. */
+void srtest_check_samplerate(struct sr_context *sr_ctx, const char *drivername,
+ uint64_t samplerate)
+{
+ struct sr_dev_driver *driver;
+ uint64_t s;
+
+ driver = srtest_driver_get(drivername);
+ srtest_driver_init(sr_ctx, driver);;
+ srtest_set_samplerate(driver, samplerate);
+ s = srtest_get_samplerate(driver);
+ fail_unless(s == samplerate, "%s: Incorrect samplerate: %" PRIu64 ".",
+ drivername, s);
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LIBSIGROK_TESTS_LIB_H
+#define LIBSIGROK_TESTS_LIB_H
+
+#include "../libsigrok.h"
+
+struct sr_dev_driver *srtest_driver_get(const char *drivername);
+void srtest_driver_init(struct sr_context *sr_ctx, struct sr_dev_driver *driver);
+void srtest_driver_init_all(struct sr_context *sr_ctx);
+void srtest_set_samplerate(struct sr_dev_driver *driver, uint64_t samplerate);
+uint64_t srtest_get_samplerate(struct sr_dev_driver *driver);
+void srtest_check_samplerate(struct sr_context *sr_ctx, const char *drivername,
+ uint64_t samplerate);
+
+#endif