if HAVE_CHECK
-TESTS = tests/check_main
+TESTS = tests/main
check_PROGRAMS = ${TESTS}
-tests_check_main_SOURCES = \
+tests_main_SOURCES = \
include/libsigrok/libsigrok.h \
tests/lib.c \
tests/lib.h \
- tests/check_main.c \
- tests/check_core.c \
- tests/check_input_all.c \
- tests/check_input_binary.c \
- tests/check_output_all.c \
- tests/check_transform_all.c \
- tests/check_session.c \
- tests/check_strutil.c \
- tests/check_version.c \
- tests/check_driver_all.c \
- tests/check_device.c \
- tests/check_trigger.c
-
-tests_check_main_CFLAGS = @check_CFLAGS@
-
-tests_check_main_LDADD = $(top_builddir)/libsigrok.la @check_LIBS@
+ tests/main.c \
+ tests/core.c \
+ tests/input_all.c \
+ tests/input_binary.c \
+ tests/output_all.c \
+ tests/transform_all.c \
+ tests/session.c \
+ tests/strutil.c \
+ tests/version.c \
+ tests/driver_all.c \
+ tests/device.c \
+ tests/trigger.c
+
+tests_main_CFLAGS = @check_CFLAGS@
+
+tests_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 "../include/libsigrok/libsigrok.h"
-#include "lib.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) 2014 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 <string.h>
-#include <check.h>
-#include "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-START_TEST(test_user_new)
-{
- struct sr_dev_inst *sdi;
-
- sdi = sr_dev_inst_user_new("Vendor", "Model", "Version");
-
- fail_unless(sdi != NULL, "sr_dev_inst_user_new() failed.");
-
- fail_unless(!strcmp("Vendor", sr_dev_inst_vendor_get(sdi)));
- fail_unless(!strcmp("Model", sr_dev_inst_model_get(sdi)));
- fail_unless(!strcmp("Version", sr_dev_inst_version_get(sdi)));
-}
-END_TEST
-
-START_TEST(test_channel_add)
-{
- int ret;
- struct sr_dev_inst *sdi;
- GSList *channels;
-
- sdi = sr_dev_inst_user_new("Vendor", "Model", "Version");
- fail_unless(sdi != NULL, "sr_dev_inst_user_new() failed.");
-
- channels = sr_dev_inst_channels_get(sdi);
- fail_unless(g_slist_length(channels) == 0, "More than 0 channels.");
-
- ret = sr_dev_inst_channel_add(sdi, 0, SR_CHANNEL_LOGIC, "D1");
- channels = sr_dev_inst_channels_get(sdi);
- fail_unless(ret == SR_OK);
- fail_unless(g_slist_length(channels) == 1);
-
- ret = sr_dev_inst_channel_add(sdi, 1, SR_CHANNEL_ANALOG, "A1");
- channels = sr_dev_inst_channels_get(sdi);
- fail_unless(ret == SR_OK);
- fail_unless(g_slist_length(channels) == 2);
-}
-END_TEST
-
-Suite *suite_device(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("device");
-
- tc = tcase_create("sr_dev_inst_user_new");
- tcase_add_test(tc, test_user_new);
- suite_add_tcase(s, tc);
-
- tc = tcase_create("sr_dev_inst_channel_add");
- tcase_add_test(tc, test_channel_add);
- 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 "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/* 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(srtest_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.
- */
-#if 0
-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
-#endif
-
-Suite *suite_driver_all(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("driver-all");
-
- tc = tcase_create("config");
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_driver_available);
- tcase_add_test(tc, test_driver_init_all);
- // TODO: Currently broken.
- // 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-2014 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 "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/* Check whether at least one input module is available. */
-START_TEST(test_input_available)
-{
- const struct sr_input_module **inputs;
-
- inputs = sr_input_list();
- fail_unless(inputs != NULL, "No input modules found.");
-}
-END_TEST
-
-Suite *suite_input_all(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("input-all");
-
- tc = tcase_create("basic");
- tcase_add_test(tc, test_input_available);
- suite_add_tcase(s, tc);
-
- return s;
-}
+++ /dev/null
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2013-2014 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 <glib/gstdio.h>
-#include "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-#define BUFSIZE 1000000
-
-enum {
- CHECK_ALL_LOW,
- CHECK_ALL_HIGH,
- CHECK_HELLO_WORLD,
-};
-
-static uint64_t df_packet_counter = 0, sample_counter = 0;
-static gboolean have_seen_df_end = FALSE;
-static GArray *logic_channellist = NULL;
-static int check_to_perform;
-static uint64_t expected_samples;
-static uint64_t *expected_samplerate;
-
-static void check_all_low(const struct sr_datafeed_logic *logic)
-{
- uint64_t i;
- uint8_t *data;
-
- for (i = 0; i < logic->length; i++) {
- data = logic->data;
- if (data[i * logic->unitsize] != 0)
- fail("Logic data was not all-0x00.");
- }
-}
-
-static void check_all_high(const struct sr_datafeed_logic *logic)
-{
- uint64_t i;
- uint8_t *data;
-
- for (i = 0; i < logic->length; i++) {
- data = logic->data;
- if (data[i * logic->unitsize] != 0xff)
- fail("Logic data was not all-0xff.");
- }
-}
-
-static void check_hello_world(const struct sr_datafeed_logic *logic)
-{
- uint64_t i;
- uint8_t *data, b;
- const char *h = "Hello world";
-
- for (i = 0; i < logic->length; i++) {
- data = logic->data;
- b = data[sample_counter + i];
- if (b != h[sample_counter + i])
- fail("Logic data was not 'Hello world'.");
- }
-}
-
-static void datafeed_in(const struct sr_dev_inst *sdi,
- const struct sr_datafeed_packet *packet, void *cb_data)
-{
- const struct sr_datafeed_meta *meta;
- const struct sr_datafeed_logic *logic;
- struct sr_config *src;
- uint64_t samplerate, sample_interval;
- GSList *l;
- const void *p;
-
- (void)cb_data;
-
- fail_unless(sdi != NULL);
- fail_unless(packet != NULL);
-
- if (df_packet_counter++ == 0)
- fail_unless(packet->type == SR_DF_HEADER,
- "The first packet must be an SR_DF_HEADER.");
-
- if (have_seen_df_end)
- fail("There must be no packets after an SR_DF_END, but we "
- "received a packet of type %d.", packet->type);
-
- p = packet->payload;
-
- switch (packet->type) {
- case SR_DF_HEADER:
- // g_debug("Received SR_DF_HEADER.");
- // fail_unless(p != NULL, "SR_DF_HEADER payload was NULL.");
-
- logic_channellist = srtest_get_enabled_logic_channels(sdi);
- fail_unless(logic_channellist != NULL);
- fail_unless(logic_channellist->len != 0);
- // g_debug("Enabled channels: %d.", logic_channellist->len);
- break;
- case SR_DF_META:
- // g_debug("Received SR_DF_META.");
-
- meta = packet->payload;
- fail_unless(p != NULL, "SR_DF_META payload was NULL.");
-
- for (l = meta->config; l; l = l->next) {
- src = l->data;
- // g_debug("Got meta key: %d.", src->key);
- switch (src->key) {
- case SR_CONF_SAMPLERATE:
- samplerate = g_variant_get_uint64(src->data);
- if (!expected_samplerate)
- break;
- fail_unless(samplerate == *expected_samplerate,
- "Expected samplerate=%" PRIu64 ", "
- "got %" PRIu64 "", samplerate,
- *expected_samplerate);
- // g_debug("samplerate = %" PRIu64 " Hz.",
- // samplerate);
- break;
- case SR_CONF_SAMPLE_INTERVAL:
- sample_interval = g_variant_get_uint64(src->data);
- (void)sample_interval;
- // g_debug("sample interval = %" PRIu64 " ms.",
- // sample_interval);
- break;
- default:
- /* Unknown metadata is not an error. */
- g_debug("Got unknown meta key: %d.", src->key);
- break;
- }
- }
- break;
- case SR_DF_LOGIC:
- logic = packet->payload;
- fail_unless(p != NULL, "SR_DF_LOGIC payload was NULL.");
-
- // g_debug("Received SR_DF_LOGIC (%" PRIu64 " bytes, "
- // "unitsize %d).", logic->length, logic->unitsize);
-
- if (check_to_perform == CHECK_ALL_LOW)
- check_all_low(logic);
- else if (check_to_perform == CHECK_ALL_HIGH)
- check_all_high(logic);
- else if (check_to_perform == CHECK_HELLO_WORLD)
- check_hello_world(logic);
-
- sample_counter += logic->length / logic->unitsize;
-
- break;
- case SR_DF_END:
- // g_debug("Received SR_DF_END.");
- // fail_unless(p != NULL, "SR_DF_END payload was NULL.");
- have_seen_df_end = TRUE;
- if (sample_counter != expected_samples)
- fail("Expected %" PRIu64 " samples, got %" PRIu64 "",
- expected_samples, sample_counter);
- break;
- default:
- /*
- * Note: The binary input format doesn't support SR_DF_TRIGGER
- * and some other types, those should yield an error.
- */
- fail("Invalid packet type: %d.", packet->type);
- break;
- }
-}
-
-static void check_buf(GHashTable *options, const uint8_t *buf, int check,
- uint64_t samples, uint64_t *samplerate)
-{
- int ret;
- struct sr_input *in;
- const struct sr_input_module *imod;
- struct sr_session *session;
- struct sr_dev_inst *sdi;
- GString *gbuf;
-
- /* Initialize global variables for this run. */
- df_packet_counter = sample_counter = 0;
- have_seen_df_end = FALSE;
- logic_channellist = NULL;
- check_to_perform = check;
- expected_samples = samples;
- expected_samplerate = samplerate;
-
- gbuf = g_string_new_len((gchar *)buf, (gssize)samples);
-
- imod = sr_input_find("binary");
- fail_unless(imod != NULL, "Failed to find input module.");
-
- in = sr_input_new(imod, options);
- fail_unless(in != NULL, "Failed to create input instance.");
-
- sdi = sr_input_dev_inst_get(in);
-
- sr_session_new(&session);
- sr_session_datafeed_callback_add(session, datafeed_in, NULL);
- sr_session_dev_add(session, sdi);
-
- ret = sr_input_send(in, gbuf);
- fail_unless(ret == SR_OK, "sr_input_send() error: %d", ret);
- sr_input_free(in);
-
- sr_session_destroy(session);
-
- g_string_free(gbuf, TRUE);
-}
-
-START_TEST(test_input_binary_all_low)
-{
- uint64_t i, samplerate;
- GHashTable *options;
- uint8_t *buf;
- GVariant *gvar;
-
- buf = g_malloc0(BUFSIZE);
-
- gvar = g_variant_new_uint64(1250);
- options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- (GDestroyNotify)g_variant_unref);
- g_hash_table_insert(options, g_strdup("samplerate"),
- g_variant_ref_sink(gvar));
- samplerate = SR_HZ(1250);
-
- /* Check various filesizes, with/without specifying a samplerate. */
- check_buf(NULL, buf, CHECK_ALL_LOW, 0, NULL);
- check_buf(options, buf, CHECK_ALL_LOW, 0, &samplerate);
- for (i = 1; i < BUFSIZE; i *= 3) {
- check_buf(NULL, buf, CHECK_ALL_LOW, i, NULL);
- check_buf(options, buf, CHECK_ALL_LOW, i, &samplerate);
- }
-
- g_hash_table_destroy(options);
- g_free(buf);
-}
-END_TEST
-
-START_TEST(test_input_binary_all_high)
-{
- uint64_t i;
- uint8_t *buf;
-
- buf = g_malloc(BUFSIZE);
- memset(buf, 0xff, BUFSIZE);
-
- check_buf(NULL, buf, CHECK_ALL_HIGH, 0, NULL);
- for (i = 1; i < BUFSIZE; i *= 3)
- check_buf(NULL, buf, CHECK_ALL_HIGH, i, NULL);
-
- g_free(buf);
-}
-END_TEST
-
-START_TEST(test_input_binary_all_high_loop)
-{
- uint8_t *buf;
- uint64_t bufsize;
-
- /* Note: _i is the loop variable from tcase_add_loop_test(). */
-
- bufsize = (_i * 10);
- buf = g_malloc(BUFSIZE);
- memset(buf, 0xff, BUFSIZE);
-
- check_buf(NULL, buf, CHECK_ALL_HIGH, bufsize, NULL);
-
- g_free(buf);
-}
-END_TEST
-
-START_TEST(test_input_binary_hello_world)
-{
- uint64_t samplerate;
- uint8_t *buf;
- GHashTable *options;
- GVariant *gvar;
-
- buf = (uint8_t *)g_strdup("Hello world");
-
- gvar = g_variant_new_uint64(1250);
- options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
- (GDestroyNotify)g_variant_unref);
- g_hash_table_insert(options, g_strdup("samplerate"),
- g_variant_ref_sink(gvar));
- samplerate = SR_HZ(1250);
-
- /* Check with and without specifying a samplerate. */
- check_buf(NULL, buf, CHECK_HELLO_WORLD, 11, NULL);
- check_buf(options, buf, CHECK_HELLO_WORLD, 11, &samplerate);
-
- g_hash_table_destroy(options);
- g_free(buf);
-}
-END_TEST
-
-Suite *suite_input_binary(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("input-binary");
-
- tc = tcase_create("basic");
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_input_binary_all_low);
- tcase_add_test(tc, test_input_binary_all_high);
- tcase_add_loop_test(tc, test_input_binary_all_high_loop, 1, 10);
- tcase_add_test(tc, test_input_binary_hello_world);
- 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 "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-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_driver_all());
- srunner_add_suite(srunner, suite_input_all());
- srunner_add_suite(srunner, suite_input_binary());
- srunner_add_suite(srunner, suite_output_all());
- srunner_add_suite(srunner, suite_transform_all());
- srunner_add_suite(srunner, suite_session());
- srunner_add_suite(srunner, suite_strutil());
- srunner_add_suite(srunner, suite_version());
- srunner_add_suite(srunner, suite_device());
- srunner_add_suite(srunner, suite_trigger());
-
- 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 <stdlib.h>
-#include <check.h>
-#include "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/* Check whether at least one output module is available. */
-START_TEST(test_output_available)
-{
- const struct sr_output_module **outputs;
-
- outputs = sr_output_list();
- fail_unless(outputs != NULL, "No output modules found.");
-}
-END_TEST
-
-/* Check whether sr_output_id_get() works. */
-START_TEST(test_output_id)
-{
- const struct sr_output_module **outputs;
- const char *id;
-
- outputs = sr_output_list();
-
- id = sr_output_id_get(outputs[0]);
- fail_unless(id != NULL, "No id found in output module.");
-}
-END_TEST
-
-/* Check whether sr_output_name_get() works. */
-START_TEST(test_output_name)
-{
- const struct sr_output_module **outputs;
- const char *name;
-
- outputs = sr_output_list();
-
- name = sr_output_name_get(outputs[0]);
- fail_unless(name != NULL, "No name found in output module.");
-}
-END_TEST
-
-/* Check whether sr_output_description_get() works. */
-START_TEST(test_output_desc)
-{
- const struct sr_output_module **outputs;
- const char *desc;
-
- outputs = sr_output_list();
-
- desc = sr_output_description_get(outputs[0]);
- fail_unless(desc != NULL, "No description found in output module.");
-}
-END_TEST
-
-/* Check whether sr_output_find() works. */
-START_TEST(test_output_find)
-{
- const struct sr_output_module *omod;
- const char *id;
-
- omod = sr_output_find("bits");
- fail_unless(omod != NULL, "Couldn't find the 'bits' output module.");
- id = sr_output_id_get(omod);
- fail_unless(!strcmp(id, "bits"), "That is not the 'bits' module!");
-}
-END_TEST
-
-/* Check whether sr_output_options_get() works. */
-START_TEST(test_output_options)
-{
- const struct sr_option **opt;
-
- opt = sr_output_options_get(sr_output_find("bits"));
- fail_unless(opt != NULL, "Couldn't find 'bits' options.");
- fail_unless(!strcmp((*opt)->id, "width"), "Wrong 'bits' option found!");
-}
-END_TEST
-
-Suite *suite_output_all(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("output-all");
-
- tc = tcase_create("basic");
- tcase_add_test(tc, test_output_available);
- tcase_add_test(tc, test_output_id);
- tcase_add_test(tc, test_output_name);
- tcase_add_test(tc, test_output_desc);
- tcase_add_test(tc, test_output_find);
- tcase_add_test(tc, test_output_options);
- suite_add_tcase(s, tc);
-
- return s;
-}
+++ /dev/null
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2014 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 "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/*
- * Check whether sr_session_new() works.
- * If it returns != SR_OK (or segfaults) this test will fail.
- */
-START_TEST(test_session_new)
-{
- int ret;
- struct sr_session *sess;
-
- ret = sr_session_new(&sess);
- fail_unless(ret == SR_OK, "sr_session_new() failed: %d.", ret);
- sr_session_destroy(sess);
-}
-END_TEST
-
-/*
- * Check whether sr_session_new() fails for bogus parameters.
- * If it returns SR_OK (or segfaults) this test will fail.
- */
-START_TEST(test_session_new_bogus)
-{
- int ret;
-
- ret = sr_session_new(NULL);
- fail_unless(ret != SR_OK, "sr_session_new(NULL) worked.");
-}
-END_TEST
-
-/*
- * Check whether multiple sr_session_new() calls work.
- * If any call returns != SR_OK (or segfaults) this test will fail.
- */
-START_TEST(test_session_new_multiple)
-{
- int ret;
- struct sr_session *sess1, *sess2, *sess3;
-
- sess1 = sess2 = sess3 = NULL;
-
- /* Multiple sr_session_new() calls must work. */
- ret = sr_session_new(&sess1);
- fail_unless(ret == SR_OK, "sr_session_new() 1 failed: %d.", ret);
- ret = sr_session_new(&sess2);
- fail_unless(ret == SR_OK, "sr_session_new() 2 failed: %d.", ret);
- ret = sr_session_new(&sess3);
- fail_unless(ret == SR_OK, "sr_session_new() 3 failed: %d.", ret);
-
- /* The returned session pointers must all be non-NULL. */
- fail_unless(sess1 != NULL);
- fail_unless(sess2 != NULL);
- fail_unless(sess3 != NULL);
-
- /* The returned session pointers must not be the same. */
- fail_unless(sess1 != sess2);
- fail_unless(sess1 != sess3);
- fail_unless(sess2 != sess3);
-
- /* Destroying any of the sessions must work. */
- ret = sr_session_destroy(sess1);
- fail_unless(ret == SR_OK, "sr_session_destroy() 1 failed: %d.", ret);
- ret = sr_session_destroy(sess2);
- fail_unless(ret == SR_OK, "sr_session_destroy() 2 failed: %d.", ret);
- ret = sr_session_destroy(sess3);
- fail_unless(ret == SR_OK, "sr_session_destroy() 3 failed: %d.", ret);
-}
-END_TEST
-
-/*
- * Check whether sr_session_destroy() works.
- * If it returns != SR_OK (or segfaults) this test will fail.
- */
-START_TEST(test_session_destroy)
-{
- int ret;
- struct sr_session *sess;
-
- sr_session_new(&sess);
- ret = sr_session_destroy(sess);
- fail_unless(ret == SR_OK, "sr_session_destroy() failed: %d.", ret);
-}
-END_TEST
-
-/*
- * Check whether sr_session_destroy() fails for bogus sessions.
- * If it returns SR_OK (or segfaults) this test will fail.
- */
-START_TEST(test_session_destroy_bogus)
-{
- int ret;
-
- ret = sr_session_destroy(NULL);
- fail_unless(ret != SR_OK, "sr_session_destroy() worked.");
-}
-END_TEST
-
-START_TEST(test_session_trigger_set_get)
-{
- int ret;
- struct sr_session *sess;
- struct sr_trigger *t1, *t2;
-
- sr_session_new(&sess);
- t1 = sr_trigger_new("T1");
-
- /* Set a trigger and see if getting it works OK. */
- ret = sr_session_trigger_set(sess, t1);
- fail_unless(ret == SR_OK);
- t2 = sr_session_trigger_get(sess);
- fail_unless(t2 != NULL);
- fail_unless(t1 == t2);
- fail_unless(g_slist_length(t1->stages) == g_slist_length(t2->stages));
- fail_unless(!strcmp(t1->name, t2->name));
-
- sr_session_destroy(sess);
-}
-END_TEST
-
-START_TEST(test_session_trigger_set_get_null)
-{
- int ret;
- struct sr_session *sess;
- struct sr_trigger *t;
-
- sr_session_new(&sess);
-
- /* Adding a NULL trigger is allowed. */
- ret = sr_session_trigger_set(sess, NULL);
- fail_unless(ret == SR_OK);
- t = sr_session_trigger_get(sess);
- fail_unless(t == NULL);
-
- sr_session_destroy(sess);
-}
-END_TEST
-
-START_TEST(test_session_trigger_set_null)
-{
- int ret;
- struct sr_trigger *t;
-
- t = sr_trigger_new("T1");
-
- /* NULL session, must not segfault. */
- ret = sr_session_trigger_set(NULL, t);
- fail_unless(ret == SR_ERR_ARG);
-
- /* NULL session and NULL trigger, must not segfault. */
- ret = sr_session_trigger_set(NULL, NULL);
- fail_unless(ret == SR_ERR_ARG);
-}
-END_TEST
-
-START_TEST(test_session_trigger_get_null)
-{
- struct sr_trigger *t;
-
- /* NULL session, must not segfault. */
- t = sr_session_trigger_get(NULL);
- fail_unless(t == NULL);
-}
-END_TEST
-
-Suite *suite_session(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("session");
-
- tc = tcase_create("new_destroy");
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_session_new);
- tcase_add_test(tc, test_session_new_bogus);
- tcase_add_test(tc, test_session_new_multiple);
- tcase_add_test(tc, test_session_destroy);
- tcase_add_test(tc, test_session_destroy_bogus);
- suite_add_tcase(s, tc);
-
- tc = tcase_create("trigger");
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_session_trigger_set_get);
- tcase_add_test(tc, test_session_trigger_set_get_null);
- tcase_add_test(tc, test_session_trigger_set_null);
- tcase_add_test(tc, test_session_trigger_get_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 <check.h>
-#include "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-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 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.23 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.23 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.234 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.234 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.5 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.5 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, srtest_setup, srtest_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) 2015 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 "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/* Check whether at least one transform module is available. */
-START_TEST(test_transform_available)
-{
- const struct sr_transform_module **transforms;
-
- transforms = sr_transform_list();
- fail_unless(transforms != NULL, "No transform modules found.");
-}
-END_TEST
-
-/* Check whether sr_transform_id_get() works. */
-START_TEST(test_transform_id)
-{
- const struct sr_transform_module **transforms;
- const char *id;
-
- transforms = sr_transform_list();
-
- id = sr_transform_id_get(transforms[0]);
- fail_unless(id != NULL, "No ID found in transform module.");
-}
-END_TEST
-
-/* Check whether sr_transform_name_get() works. */
-START_TEST(test_transform_name)
-{
- const struct sr_transform_module **transforms;
- const char *name;
-
- transforms = sr_transform_list();
-
- name = sr_transform_name_get(transforms[0]);
- fail_unless(name != NULL, "No name found in transform module.");
-}
-END_TEST
-
-/* Check whether sr_transform_description_get() works. */
-START_TEST(test_transform_desc)
-{
- const struct sr_transform_module **transforms;
- const char *desc;
-
- transforms = sr_transform_list();
-
- desc = sr_transform_description_get(transforms[0]);
- fail_unless(desc != NULL, "No description found in transform module.");
-}
-END_TEST
-
-/* Check whether sr_transform_find() works. */
-START_TEST(test_transform_find)
-{
- const struct sr_transform_module *tmod;
- const char *id;
-
- tmod = sr_transform_find("nop");
- fail_unless(tmod != NULL, "Couldn't find the 'nop' transform module.");
- id = sr_transform_id_get(tmod);
- fail_unless(id != NULL, "No ID found in transform module.");
- fail_unless(!strcmp(id, "nop"), "That is not the 'nop' module!");
-}
-END_TEST
-
-/* Check whether sr_transform_options_get() works. */
-START_TEST(test_transform_options)
-{
- const struct sr_option **opt;
-
- opt = sr_transform_options_get(sr_transform_find("nop"));
- fail_unless(opt == NULL, "Transform module 'nop' doesn't have options.");
-}
-END_TEST
-
-Suite *suite_transform_all(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("transform-all");
-
- tc = tcase_create("basic");
- tcase_add_test(tc, test_transform_available);
- tcase_add_test(tc, test_transform_id);
- tcase_add_test(tc, test_transform_name);
- tcase_add_test(tc, test_transform_desc);
- tcase_add_test(tc, test_transform_find);
- tcase_add_test(tc, test_transform_options);
- suite_add_tcase(s, tc);
-
- return s;
-}
+++ /dev/null
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2014 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 <stdlib.h>
-#include <check.h>
-#include "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/* Test lots of triggers/stages/matches/channels */
-#define NUM_TRIGGERS 70
-#define NUM_STAGES 30
-#define NUM_MATCHES 70
-#define NUM_CHANNELS NUM_MATCHES
-
-/* Check whether creating/freeing triggers with valid names works. */
-START_TEST(test_trigger_new_free)
-{
- int i;
- struct sr_trigger *t[NUM_TRIGGERS];
- char name[10];
-
- /* Create a few triggers with a valid name. */
- for (i = 0; i < NUM_TRIGGERS; i++) {
- sprintf((char *)&name, "T%d", i);
- t[i] = sr_trigger_new((const char *)&name);
- fail_unless(t[i] != NULL);
- fail_unless(!strcmp(t[i]->name, (const char *)&name));
- fail_unless(t[i]->stages == NULL);
- }
-
- /* Free the triggers again (must not segfault). */
- for (i = 0; i < NUM_TRIGGERS; i++)
- sr_trigger_free(t[i]);
-}
-END_TEST
-
-/* Check whether creating/freeing triggers with NULL names works. */
-START_TEST(test_trigger_new_free_null)
-{
- int i;
- struct sr_trigger *t[NUM_TRIGGERS];
-
- /* Create a few triggers with a NULL name (which is allowed). */
- for (i = 0; i < NUM_TRIGGERS; i++) {
- t[i] = sr_trigger_new(NULL);
- fail_unless(t[i] != NULL);
- fail_unless(t[i]->name == NULL);
- fail_unless(t[i]->stages == NULL);
- }
-
- /* Free the triggers again (must not segfault). */
- for (i = 0; i < NUM_TRIGGERS; i++)
- sr_trigger_free(t[i]);
-}
-END_TEST
-
-/* Check whether sr_trigger_free(NULL) works without segfaulting. */
-START_TEST(test_trigger_free_null)
-{
- sr_trigger_free(NULL);
-}
-END_TEST
-
-/* Check whether creating/freeing triggers with stages works. */
-START_TEST(test_trigger_stage_add)
-{
- int i, j;
- struct sr_trigger *t[NUM_TRIGGERS];
- struct sr_trigger_stage *s[NUM_STAGES];
-
- /* Create a few triggers with a valid name. */
- for (i = 0; i < NUM_TRIGGERS; i++) {
- t[i] = sr_trigger_new("T");
-
- /* Add a bunch of trigger stages to this trigger. */
- for (j = 0; j < NUM_STAGES; j++) {
- s[j] = sr_trigger_stage_add(t[i]);
- fail_unless(s[j] != NULL);
- fail_unless(t[i]->stages != NULL);
- fail_unless((int)g_slist_length(t[i]->stages) == (j + 1));
- fail_unless(s[j]->stage == j);
- fail_unless(s[j]->matches == NULL);
- }
- }
-
- /* Free the triggers again (must not segfault). */
- for (i = 0; i < NUM_TRIGGERS; i++)
- sr_trigger_free(t[i]);
-}
-END_TEST
-
-/* Check whether creating NULL trigger stages fails (as it should). */
-START_TEST(test_trigger_stage_add_null)
-{
- /* Should not segfault, but rather return NULL. */
- fail_unless(sr_trigger_stage_add(NULL) == NULL);
-}
-END_TEST
-
-/* Check whether creating/freeing triggers with matches works. */
-START_TEST(test_trigger_match_add)
-{
- int i, j, k, tm, ret;
- struct sr_trigger *t[NUM_TRIGGERS];
- struct sr_trigger_stage *s[NUM_STAGES];
- struct sr_channel *chl[NUM_CHANNELS];
- struct sr_channel *cha[NUM_CHANNELS];
- char name[10];
-
- /* Create a bunch of logic and analog channels. */
- for (i = 0; i < NUM_CHANNELS; i++) {
- sprintf((char *)&name, "L%d", i);
- chl[i] = g_malloc0(sizeof(struct sr_channel));
- chl[i]->index = i;
- chl[i]->type = SR_CHANNEL_LOGIC;
- chl[i]->enabled = TRUE;
- chl[i]->name = g_strdup((const char *)&name);
-
- sprintf((char *)&name, "A%d", i);
- cha[i] = g_malloc0(sizeof(struct sr_channel));
- cha[i]->index = i;
- cha[i]->type = SR_CHANNEL_ANALOG;
- cha[i]->enabled = TRUE;
- cha[i]->name = g_strdup((const char *)&name);
- }
-
- /* Create a few triggers with a valid name. */
- for (i = 0; i < NUM_TRIGGERS; i++) {
- t[i] = sr_trigger_new("T");
-
- /* Add a bunch of trigger stages to this trigger. */
- for (j = 0; j < NUM_STAGES; j++) {
- s[j] = sr_trigger_stage_add(t[i]);
-
- /* Add a bunch of matches to this stage. */
- for (k = 0; k < NUM_MATCHES; k++) {
- /* Logic channel matches. */
- tm = 1 + (k % 5); /* *_ZERO .. *_EDGE */
- ret = sr_trigger_match_add(s[j], chl[k], tm, 0);
- fail_unless(ret == SR_OK);
-
- /* Analog channel matches. */
- tm = 3 + (k % 4); /* *_RISING .. *_UNDER */
- ret = sr_trigger_match_add(s[j], cha[k],
- tm, ((rand() % 500) - 500) * 1.739);
- fail_unless(ret == SR_OK);
- }
- }
- }
-
- /* Free the triggers again (must not segfault). */
- for (i = 0; i < NUM_TRIGGERS; i++)
- sr_trigger_free(t[i]);
-
- /* Free the channels. */
- for (i = 0; i < NUM_CHANNELS; i++) {
- g_free(chl[i]->name);
- g_free(chl[i]);
- g_free(cha[i]->name);
- g_free(cha[i]);
- }
-}
-END_TEST
-
-/* Check whether trigger_match_add() copes well with incorrect input. */
-START_TEST(test_trigger_match_add_bogus)
-{
- int ret;
- struct sr_trigger *t;
- struct sr_trigger_stage *s, *sl;
- struct sr_channel *chl, *cha;
-
- t = sr_trigger_new("T");
- s = sr_trigger_stage_add(t);
- chl = g_malloc0(sizeof(struct sr_channel));
- chl->index = 0;
- chl->type = SR_CHANNEL_LOGIC;
- chl->enabled = TRUE;
- chl->name = g_strdup("L0");
- cha = g_malloc0(sizeof(struct sr_channel));
- cha->index = 1;
- cha->type = SR_CHANNEL_ANALOG;
- cha->enabled = TRUE;
- cha->name = g_strdup("A0");
-
- /* Initially we have no matches at all. */
- sl = t->stages->data;
- fail_unless(g_slist_length(sl->matches) == 0);
-
- /* NULL stage */
- ret = sr_trigger_match_add(NULL, chl, SR_TRIGGER_ZERO, 0);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
-
- /* NULL channel */
- ret = sr_trigger_match_add(s, NULL, SR_TRIGGER_ZERO, 0);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
-
- /* Invalid trigger matches for logic channels. */
- ret = sr_trigger_match_add(s, chl, SR_TRIGGER_OVER, 0);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
- ret = sr_trigger_match_add(s, chl, SR_TRIGGER_UNDER, 0);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
-
- /* Invalid trigger matches for analog channels. */
- ret = sr_trigger_match_add(s, cha, SR_TRIGGER_ZERO, 9.4);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
- ret = sr_trigger_match_add(s, cha, SR_TRIGGER_ONE, -9.4);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
-
- /* Invalid channel type. */
- chl->type = -1;
- ret = sr_trigger_match_add(s, chl, SR_TRIGGER_ZERO, 0);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
- chl->type = 270;
- ret = sr_trigger_match_add(s, chl, SR_TRIGGER_ZERO, 0);
- fail_unless(ret == SR_ERR_ARG);
- fail_unless(g_slist_length(sl->matches) == 0);
-
- sr_trigger_free(t);
- g_free(chl->name);
- g_free(chl);
- g_free(cha->name);
- g_free(cha);
-}
-END_TEST
-
-Suite *suite_trigger(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("trigger");
-
- tc = tcase_create("new_free");
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_trigger_new_free);
- tcase_add_test(tc, test_trigger_new_free_null);
- tcase_add_test(tc, test_trigger_free_null);
- suite_add_tcase(s, tc);
-
- tc = tcase_create("stage");
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_trigger_stage_add);
- tcase_add_test(tc, test_trigger_stage_add_null);
- suite_add_tcase(s, tc);
-
- tc = tcase_create("match");
- tcase_set_timeout(tc, 0);
- tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
- tcase_add_test(tc, test_trigger_match_add);
- tcase_add_test(tc, test_trigger_match_add_bogus);
- 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 "../include/libsigrok/libsigrok.h"
-#include "lib.h"
-
-/*
- * Check the version number API calls and macros.
- *
- * The numbers returned by the sr_*_version*get() calls must match the
- * respective SR_*_VERSION* macro values, must be >= 0, and must not be
- * unreasonably high (> 20), otherwise something is probably wrong.
- */
-START_TEST(test_version_numbers)
-{
- int ver;
-
- ver = sr_package_version_major_get();
- fail_unless(ver == SR_PACKAGE_VERSION_MAJOR);
- fail_unless(ver >= 0 && ver <= 20);
- ver = sr_package_version_minor_get();
- fail_unless(ver == SR_PACKAGE_VERSION_MINOR);
- fail_unless(ver >= 0 && ver <= 20);
- ver = sr_package_version_micro_get();
- fail_unless(ver == SR_PACKAGE_VERSION_MICRO);
- fail_unless(ver >= 0 && ver <= 20);
-
- ver = sr_lib_version_current_get();
- fail_unless(ver == SR_LIB_VERSION_CURRENT);
- fail_unless(ver >= 0 && ver <= 20);
- ver = sr_lib_version_revision_get();
- fail_unless(ver == SR_LIB_VERSION_REVISION);
- fail_unless(ver >= 0 && ver <= 20);
- ver = sr_lib_version_age_get();
- fail_unless(ver == SR_LIB_VERSION_AGE);
- fail_unless(ver >= 0 && ver <= 20);
-}
-END_TEST
-
-/*
- * Check the version number API calls and macros.
- *
- * The string representations of the package/lib version must match the
- * version numbers, the string lengths must be >= 5 (e.g. "0.1.0"), and
- * the strings length must be <= 20 characters, otherwise something is
- * probably wrong.
- */
-START_TEST(test_version_strings)
-{
- const char *str;
-
- str = sr_package_version_string_get();
- fail_unless(str != NULL);
- fail_unless(strlen(str) >= 5 && strlen(str) <= 20);
- str = sr_lib_version_string_get();
- fail_unless(str != NULL);
- fail_unless(strlen(str) >= 5 && strlen(str) <= 20);
-}
-END_TEST
-
-Suite *suite_version(void)
-{
- Suite *s;
- TCase *tc;
-
- s = suite_create("version");
-
- tc = tcase_create("version");
- tcase_add_test(tc, test_version_numbers);
- tcase_add_test(tc, test_version_strings);
- 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 "../include/libsigrok/libsigrok.h"
+#include "lib.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) 2014 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 <string.h>
+#include <check.h>
+#include "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+START_TEST(test_user_new)
+{
+ struct sr_dev_inst *sdi;
+
+ sdi = sr_dev_inst_user_new("Vendor", "Model", "Version");
+
+ fail_unless(sdi != NULL, "sr_dev_inst_user_new() failed.");
+
+ fail_unless(!strcmp("Vendor", sr_dev_inst_vendor_get(sdi)));
+ fail_unless(!strcmp("Model", sr_dev_inst_model_get(sdi)));
+ fail_unless(!strcmp("Version", sr_dev_inst_version_get(sdi)));
+}
+END_TEST
+
+START_TEST(test_channel_add)
+{
+ int ret;
+ struct sr_dev_inst *sdi;
+ GSList *channels;
+
+ sdi = sr_dev_inst_user_new("Vendor", "Model", "Version");
+ fail_unless(sdi != NULL, "sr_dev_inst_user_new() failed.");
+
+ channels = sr_dev_inst_channels_get(sdi);
+ fail_unless(g_slist_length(channels) == 0, "More than 0 channels.");
+
+ ret = sr_dev_inst_channel_add(sdi, 0, SR_CHANNEL_LOGIC, "D1");
+ channels = sr_dev_inst_channels_get(sdi);
+ fail_unless(ret == SR_OK);
+ fail_unless(g_slist_length(channels) == 1);
+
+ ret = sr_dev_inst_channel_add(sdi, 1, SR_CHANNEL_ANALOG, "A1");
+ channels = sr_dev_inst_channels_get(sdi);
+ fail_unless(ret == SR_OK);
+ fail_unless(g_slist_length(channels) == 2);
+}
+END_TEST
+
+Suite *suite_device(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("device");
+
+ tc = tcase_create("sr_dev_inst_user_new");
+ tcase_add_test(tc, test_user_new);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sr_dev_inst_channel_add");
+ tcase_add_test(tc, test_channel_add);
+ 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 "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/* 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(srtest_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.
+ */
+#if 0
+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
+#endif
+
+Suite *suite_driver_all(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("driver-all");
+
+ tc = tcase_create("config");
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_driver_available);
+ tcase_add_test(tc, test_driver_init_all);
+ // TODO: Currently broken.
+ // 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-2014 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 "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/* Check whether at least one input module is available. */
+START_TEST(test_input_available)
+{
+ const struct sr_input_module **inputs;
+
+ inputs = sr_input_list();
+ fail_unless(inputs != NULL, "No input modules found.");
+}
+END_TEST
+
+Suite *suite_input_all(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("input-all");
+
+ tc = tcase_create("basic");
+ tcase_add_test(tc, test_input_available);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013-2014 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 <glib/gstdio.h>
+#include "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+#define BUFSIZE 1000000
+
+enum {
+ CHECK_ALL_LOW,
+ CHECK_ALL_HIGH,
+ CHECK_HELLO_WORLD,
+};
+
+static uint64_t df_packet_counter = 0, sample_counter = 0;
+static gboolean have_seen_df_end = FALSE;
+static GArray *logic_channellist = NULL;
+static int check_to_perform;
+static uint64_t expected_samples;
+static uint64_t *expected_samplerate;
+
+static void check_all_low(const struct sr_datafeed_logic *logic)
+{
+ uint64_t i;
+ uint8_t *data;
+
+ for (i = 0; i < logic->length; i++) {
+ data = logic->data;
+ if (data[i * logic->unitsize] != 0)
+ fail("Logic data was not all-0x00.");
+ }
+}
+
+static void check_all_high(const struct sr_datafeed_logic *logic)
+{
+ uint64_t i;
+ uint8_t *data;
+
+ for (i = 0; i < logic->length; i++) {
+ data = logic->data;
+ if (data[i * logic->unitsize] != 0xff)
+ fail("Logic data was not all-0xff.");
+ }
+}
+
+static void check_hello_world(const struct sr_datafeed_logic *logic)
+{
+ uint64_t i;
+ uint8_t *data, b;
+ const char *h = "Hello world";
+
+ for (i = 0; i < logic->length; i++) {
+ data = logic->data;
+ b = data[sample_counter + i];
+ if (b != h[sample_counter + i])
+ fail("Logic data was not 'Hello world'.");
+ }
+}
+
+static void datafeed_in(const struct sr_dev_inst *sdi,
+ const struct sr_datafeed_packet *packet, void *cb_data)
+{
+ const struct sr_datafeed_meta *meta;
+ const struct sr_datafeed_logic *logic;
+ struct sr_config *src;
+ uint64_t samplerate, sample_interval;
+ GSList *l;
+ const void *p;
+
+ (void)cb_data;
+
+ fail_unless(sdi != NULL);
+ fail_unless(packet != NULL);
+
+ if (df_packet_counter++ == 0)
+ fail_unless(packet->type == SR_DF_HEADER,
+ "The first packet must be an SR_DF_HEADER.");
+
+ if (have_seen_df_end)
+ fail("There must be no packets after an SR_DF_END, but we "
+ "received a packet of type %d.", packet->type);
+
+ p = packet->payload;
+
+ switch (packet->type) {
+ case SR_DF_HEADER:
+ // g_debug("Received SR_DF_HEADER.");
+ // fail_unless(p != NULL, "SR_DF_HEADER payload was NULL.");
+
+ logic_channellist = srtest_get_enabled_logic_channels(sdi);
+ fail_unless(logic_channellist != NULL);
+ fail_unless(logic_channellist->len != 0);
+ // g_debug("Enabled channels: %d.", logic_channellist->len);
+ break;
+ case SR_DF_META:
+ // g_debug("Received SR_DF_META.");
+
+ meta = packet->payload;
+ fail_unless(p != NULL, "SR_DF_META payload was NULL.");
+
+ for (l = meta->config; l; l = l->next) {
+ src = l->data;
+ // g_debug("Got meta key: %d.", src->key);
+ switch (src->key) {
+ case SR_CONF_SAMPLERATE:
+ samplerate = g_variant_get_uint64(src->data);
+ if (!expected_samplerate)
+ break;
+ fail_unless(samplerate == *expected_samplerate,
+ "Expected samplerate=%" PRIu64 ", "
+ "got %" PRIu64 "", samplerate,
+ *expected_samplerate);
+ // g_debug("samplerate = %" PRIu64 " Hz.",
+ // samplerate);
+ break;
+ case SR_CONF_SAMPLE_INTERVAL:
+ sample_interval = g_variant_get_uint64(src->data);
+ (void)sample_interval;
+ // g_debug("sample interval = %" PRIu64 " ms.",
+ // sample_interval);
+ break;
+ default:
+ /* Unknown metadata is not an error. */
+ g_debug("Got unknown meta key: %d.", src->key);
+ break;
+ }
+ }
+ break;
+ case SR_DF_LOGIC:
+ logic = packet->payload;
+ fail_unless(p != NULL, "SR_DF_LOGIC payload was NULL.");
+
+ // g_debug("Received SR_DF_LOGIC (%" PRIu64 " bytes, "
+ // "unitsize %d).", logic->length, logic->unitsize);
+
+ if (check_to_perform == CHECK_ALL_LOW)
+ check_all_low(logic);
+ else if (check_to_perform == CHECK_ALL_HIGH)
+ check_all_high(logic);
+ else if (check_to_perform == CHECK_HELLO_WORLD)
+ check_hello_world(logic);
+
+ sample_counter += logic->length / logic->unitsize;
+
+ break;
+ case SR_DF_END:
+ // g_debug("Received SR_DF_END.");
+ // fail_unless(p != NULL, "SR_DF_END payload was NULL.");
+ have_seen_df_end = TRUE;
+ if (sample_counter != expected_samples)
+ fail("Expected %" PRIu64 " samples, got %" PRIu64 "",
+ expected_samples, sample_counter);
+ break;
+ default:
+ /*
+ * Note: The binary input format doesn't support SR_DF_TRIGGER
+ * and some other types, those should yield an error.
+ */
+ fail("Invalid packet type: %d.", packet->type);
+ break;
+ }
+}
+
+static void check_buf(GHashTable *options, const uint8_t *buf, int check,
+ uint64_t samples, uint64_t *samplerate)
+{
+ int ret;
+ struct sr_input *in;
+ const struct sr_input_module *imod;
+ struct sr_session *session;
+ struct sr_dev_inst *sdi;
+ GString *gbuf;
+
+ /* Initialize global variables for this run. */
+ df_packet_counter = sample_counter = 0;
+ have_seen_df_end = FALSE;
+ logic_channellist = NULL;
+ check_to_perform = check;
+ expected_samples = samples;
+ expected_samplerate = samplerate;
+
+ gbuf = g_string_new_len((gchar *)buf, (gssize)samples);
+
+ imod = sr_input_find("binary");
+ fail_unless(imod != NULL, "Failed to find input module.");
+
+ in = sr_input_new(imod, options);
+ fail_unless(in != NULL, "Failed to create input instance.");
+
+ sdi = sr_input_dev_inst_get(in);
+
+ sr_session_new(&session);
+ sr_session_datafeed_callback_add(session, datafeed_in, NULL);
+ sr_session_dev_add(session, sdi);
+
+ ret = sr_input_send(in, gbuf);
+ fail_unless(ret == SR_OK, "sr_input_send() error: %d", ret);
+ sr_input_free(in);
+
+ sr_session_destroy(session);
+
+ g_string_free(gbuf, TRUE);
+}
+
+START_TEST(test_input_binary_all_low)
+{
+ uint64_t i, samplerate;
+ GHashTable *options;
+ uint8_t *buf;
+ GVariant *gvar;
+
+ buf = g_malloc0(BUFSIZE);
+
+ gvar = g_variant_new_uint64(1250);
+ options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)g_variant_unref);
+ g_hash_table_insert(options, g_strdup("samplerate"),
+ g_variant_ref_sink(gvar));
+ samplerate = SR_HZ(1250);
+
+ /* Check various filesizes, with/without specifying a samplerate. */
+ check_buf(NULL, buf, CHECK_ALL_LOW, 0, NULL);
+ check_buf(options, buf, CHECK_ALL_LOW, 0, &samplerate);
+ for (i = 1; i < BUFSIZE; i *= 3) {
+ check_buf(NULL, buf, CHECK_ALL_LOW, i, NULL);
+ check_buf(options, buf, CHECK_ALL_LOW, i, &samplerate);
+ }
+
+ g_hash_table_destroy(options);
+ g_free(buf);
+}
+END_TEST
+
+START_TEST(test_input_binary_all_high)
+{
+ uint64_t i;
+ uint8_t *buf;
+
+ buf = g_malloc(BUFSIZE);
+ memset(buf, 0xff, BUFSIZE);
+
+ check_buf(NULL, buf, CHECK_ALL_HIGH, 0, NULL);
+ for (i = 1; i < BUFSIZE; i *= 3)
+ check_buf(NULL, buf, CHECK_ALL_HIGH, i, NULL);
+
+ g_free(buf);
+}
+END_TEST
+
+START_TEST(test_input_binary_all_high_loop)
+{
+ uint8_t *buf;
+ uint64_t bufsize;
+
+ /* Note: _i is the loop variable from tcase_add_loop_test(). */
+
+ bufsize = (_i * 10);
+ buf = g_malloc(BUFSIZE);
+ memset(buf, 0xff, BUFSIZE);
+
+ check_buf(NULL, buf, CHECK_ALL_HIGH, bufsize, NULL);
+
+ g_free(buf);
+}
+END_TEST
+
+START_TEST(test_input_binary_hello_world)
+{
+ uint64_t samplerate;
+ uint8_t *buf;
+ GHashTable *options;
+ GVariant *gvar;
+
+ buf = (uint8_t *)g_strdup("Hello world");
+
+ gvar = g_variant_new_uint64(1250);
+ options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify)g_variant_unref);
+ g_hash_table_insert(options, g_strdup("samplerate"),
+ g_variant_ref_sink(gvar));
+ samplerate = SR_HZ(1250);
+
+ /* Check with and without specifying a samplerate. */
+ check_buf(NULL, buf, CHECK_HELLO_WORLD, 11, NULL);
+ check_buf(options, buf, CHECK_HELLO_WORLD, 11, &samplerate);
+
+ g_hash_table_destroy(options);
+ g_free(buf);
+}
+END_TEST
+
+Suite *suite_input_binary(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("input-binary");
+
+ tc = tcase_create("basic");
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_input_binary_all_low);
+ tcase_add_test(tc, test_input_binary_all_high);
+ tcase_add_loop_test(tc, test_input_binary_all_high_loop, 1, 10);
+ tcase_add_test(tc, test_input_binary_hello_world);
+ 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 "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+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_driver_all());
+ srunner_add_suite(srunner, suite_input_all());
+ srunner_add_suite(srunner, suite_input_binary());
+ srunner_add_suite(srunner, suite_output_all());
+ srunner_add_suite(srunner, suite_transform_all());
+ srunner_add_suite(srunner, suite_session());
+ srunner_add_suite(srunner, suite_strutil());
+ srunner_add_suite(srunner, suite_version());
+ srunner_add_suite(srunner, suite_device());
+ srunner_add_suite(srunner, suite_trigger());
+
+ 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 <stdlib.h>
+#include <check.h>
+#include "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/* Check whether at least one output module is available. */
+START_TEST(test_output_available)
+{
+ const struct sr_output_module **outputs;
+
+ outputs = sr_output_list();
+ fail_unless(outputs != NULL, "No output modules found.");
+}
+END_TEST
+
+/* Check whether sr_output_id_get() works. */
+START_TEST(test_output_id)
+{
+ const struct sr_output_module **outputs;
+ const char *id;
+
+ outputs = sr_output_list();
+
+ id = sr_output_id_get(outputs[0]);
+ fail_unless(id != NULL, "No id found in output module.");
+}
+END_TEST
+
+/* Check whether sr_output_name_get() works. */
+START_TEST(test_output_name)
+{
+ const struct sr_output_module **outputs;
+ const char *name;
+
+ outputs = sr_output_list();
+
+ name = sr_output_name_get(outputs[0]);
+ fail_unless(name != NULL, "No name found in output module.");
+}
+END_TEST
+
+/* Check whether sr_output_description_get() works. */
+START_TEST(test_output_desc)
+{
+ const struct sr_output_module **outputs;
+ const char *desc;
+
+ outputs = sr_output_list();
+
+ desc = sr_output_description_get(outputs[0]);
+ fail_unless(desc != NULL, "No description found in output module.");
+}
+END_TEST
+
+/* Check whether sr_output_find() works. */
+START_TEST(test_output_find)
+{
+ const struct sr_output_module *omod;
+ const char *id;
+
+ omod = sr_output_find("bits");
+ fail_unless(omod != NULL, "Couldn't find the 'bits' output module.");
+ id = sr_output_id_get(omod);
+ fail_unless(!strcmp(id, "bits"), "That is not the 'bits' module!");
+}
+END_TEST
+
+/* Check whether sr_output_options_get() works. */
+START_TEST(test_output_options)
+{
+ const struct sr_option **opt;
+
+ opt = sr_output_options_get(sr_output_find("bits"));
+ fail_unless(opt != NULL, "Couldn't find 'bits' options.");
+ fail_unless(!strcmp((*opt)->id, "width"), "Wrong 'bits' option found!");
+}
+END_TEST
+
+Suite *suite_output_all(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("output-all");
+
+ tc = tcase_create("basic");
+ tcase_add_test(tc, test_output_available);
+ tcase_add_test(tc, test_output_id);
+ tcase_add_test(tc, test_output_name);
+ tcase_add_test(tc, test_output_desc);
+ tcase_add_test(tc, test_output_find);
+ tcase_add_test(tc, test_output_options);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2014 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 "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/*
+ * Check whether sr_session_new() works.
+ * If it returns != SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_session_new)
+{
+ int ret;
+ struct sr_session *sess;
+
+ ret = sr_session_new(&sess);
+ fail_unless(ret == SR_OK, "sr_session_new() failed: %d.", ret);
+ sr_session_destroy(sess);
+}
+END_TEST
+
+/*
+ * Check whether sr_session_new() fails for bogus parameters.
+ * If it returns SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_session_new_bogus)
+{
+ int ret;
+
+ ret = sr_session_new(NULL);
+ fail_unless(ret != SR_OK, "sr_session_new(NULL) worked.");
+}
+END_TEST
+
+/*
+ * Check whether multiple sr_session_new() calls work.
+ * If any call returns != SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_session_new_multiple)
+{
+ int ret;
+ struct sr_session *sess1, *sess2, *sess3;
+
+ sess1 = sess2 = sess3 = NULL;
+
+ /* Multiple sr_session_new() calls must work. */
+ ret = sr_session_new(&sess1);
+ fail_unless(ret == SR_OK, "sr_session_new() 1 failed: %d.", ret);
+ ret = sr_session_new(&sess2);
+ fail_unless(ret == SR_OK, "sr_session_new() 2 failed: %d.", ret);
+ ret = sr_session_new(&sess3);
+ fail_unless(ret == SR_OK, "sr_session_new() 3 failed: %d.", ret);
+
+ /* The returned session pointers must all be non-NULL. */
+ fail_unless(sess1 != NULL);
+ fail_unless(sess2 != NULL);
+ fail_unless(sess3 != NULL);
+
+ /* The returned session pointers must not be the same. */
+ fail_unless(sess1 != sess2);
+ fail_unless(sess1 != sess3);
+ fail_unless(sess2 != sess3);
+
+ /* Destroying any of the sessions must work. */
+ ret = sr_session_destroy(sess1);
+ fail_unless(ret == SR_OK, "sr_session_destroy() 1 failed: %d.", ret);
+ ret = sr_session_destroy(sess2);
+ fail_unless(ret == SR_OK, "sr_session_destroy() 2 failed: %d.", ret);
+ ret = sr_session_destroy(sess3);
+ fail_unless(ret == SR_OK, "sr_session_destroy() 3 failed: %d.", ret);
+}
+END_TEST
+
+/*
+ * Check whether sr_session_destroy() works.
+ * If it returns != SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_session_destroy)
+{
+ int ret;
+ struct sr_session *sess;
+
+ sr_session_new(&sess);
+ ret = sr_session_destroy(sess);
+ fail_unless(ret == SR_OK, "sr_session_destroy() failed: %d.", ret);
+}
+END_TEST
+
+/*
+ * Check whether sr_session_destroy() fails for bogus sessions.
+ * If it returns SR_OK (or segfaults) this test will fail.
+ */
+START_TEST(test_session_destroy_bogus)
+{
+ int ret;
+
+ ret = sr_session_destroy(NULL);
+ fail_unless(ret != SR_OK, "sr_session_destroy() worked.");
+}
+END_TEST
+
+START_TEST(test_session_trigger_set_get)
+{
+ int ret;
+ struct sr_session *sess;
+ struct sr_trigger *t1, *t2;
+
+ sr_session_new(&sess);
+ t1 = sr_trigger_new("T1");
+
+ /* Set a trigger and see if getting it works OK. */
+ ret = sr_session_trigger_set(sess, t1);
+ fail_unless(ret == SR_OK);
+ t2 = sr_session_trigger_get(sess);
+ fail_unless(t2 != NULL);
+ fail_unless(t1 == t2);
+ fail_unless(g_slist_length(t1->stages) == g_slist_length(t2->stages));
+ fail_unless(!strcmp(t1->name, t2->name));
+
+ sr_session_destroy(sess);
+}
+END_TEST
+
+START_TEST(test_session_trigger_set_get_null)
+{
+ int ret;
+ struct sr_session *sess;
+ struct sr_trigger *t;
+
+ sr_session_new(&sess);
+
+ /* Adding a NULL trigger is allowed. */
+ ret = sr_session_trigger_set(sess, NULL);
+ fail_unless(ret == SR_OK);
+ t = sr_session_trigger_get(sess);
+ fail_unless(t == NULL);
+
+ sr_session_destroy(sess);
+}
+END_TEST
+
+START_TEST(test_session_trigger_set_null)
+{
+ int ret;
+ struct sr_trigger *t;
+
+ t = sr_trigger_new("T1");
+
+ /* NULL session, must not segfault. */
+ ret = sr_session_trigger_set(NULL, t);
+ fail_unless(ret == SR_ERR_ARG);
+
+ /* NULL session and NULL trigger, must not segfault. */
+ ret = sr_session_trigger_set(NULL, NULL);
+ fail_unless(ret == SR_ERR_ARG);
+}
+END_TEST
+
+START_TEST(test_session_trigger_get_null)
+{
+ struct sr_trigger *t;
+
+ /* NULL session, must not segfault. */
+ t = sr_session_trigger_get(NULL);
+ fail_unless(t == NULL);
+}
+END_TEST
+
+Suite *suite_session(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("session");
+
+ tc = tcase_create("new_destroy");
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_session_new);
+ tcase_add_test(tc, test_session_new_bogus);
+ tcase_add_test(tc, test_session_new_multiple);
+ tcase_add_test(tc, test_session_destroy);
+ tcase_add_test(tc, test_session_destroy_bogus);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("trigger");
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_session_trigger_set_get);
+ tcase_add_test(tc, test_session_trigger_set_get_null);
+ tcase_add_test(tc, test_session_trigger_set_null);
+ tcase_add_test(tc, test_session_trigger_get_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 <check.h>
+#include "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+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 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.23 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.23 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.234 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.234 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.5 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.5 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, srtest_setup, srtest_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) 2015 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 "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/* Check whether at least one transform module is available. */
+START_TEST(test_transform_available)
+{
+ const struct sr_transform_module **transforms;
+
+ transforms = sr_transform_list();
+ fail_unless(transforms != NULL, "No transform modules found.");
+}
+END_TEST
+
+/* Check whether sr_transform_id_get() works. */
+START_TEST(test_transform_id)
+{
+ const struct sr_transform_module **transforms;
+ const char *id;
+
+ transforms = sr_transform_list();
+
+ id = sr_transform_id_get(transforms[0]);
+ fail_unless(id != NULL, "No ID found in transform module.");
+}
+END_TEST
+
+/* Check whether sr_transform_name_get() works. */
+START_TEST(test_transform_name)
+{
+ const struct sr_transform_module **transforms;
+ const char *name;
+
+ transforms = sr_transform_list();
+
+ name = sr_transform_name_get(transforms[0]);
+ fail_unless(name != NULL, "No name found in transform module.");
+}
+END_TEST
+
+/* Check whether sr_transform_description_get() works. */
+START_TEST(test_transform_desc)
+{
+ const struct sr_transform_module **transforms;
+ const char *desc;
+
+ transforms = sr_transform_list();
+
+ desc = sr_transform_description_get(transforms[0]);
+ fail_unless(desc != NULL, "No description found in transform module.");
+}
+END_TEST
+
+/* Check whether sr_transform_find() works. */
+START_TEST(test_transform_find)
+{
+ const struct sr_transform_module *tmod;
+ const char *id;
+
+ tmod = sr_transform_find("nop");
+ fail_unless(tmod != NULL, "Couldn't find the 'nop' transform module.");
+ id = sr_transform_id_get(tmod);
+ fail_unless(id != NULL, "No ID found in transform module.");
+ fail_unless(!strcmp(id, "nop"), "That is not the 'nop' module!");
+}
+END_TEST
+
+/* Check whether sr_transform_options_get() works. */
+START_TEST(test_transform_options)
+{
+ const struct sr_option **opt;
+
+ opt = sr_transform_options_get(sr_transform_find("nop"));
+ fail_unless(opt == NULL, "Transform module 'nop' doesn't have options.");
+}
+END_TEST
+
+Suite *suite_transform_all(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("transform-all");
+
+ tc = tcase_create("basic");
+ tcase_add_test(tc, test_transform_available);
+ tcase_add_test(tc, test_transform_id);
+ tcase_add_test(tc, test_transform_name);
+ tcase_add_test(tc, test_transform_desc);
+ tcase_add_test(tc, test_transform_find);
+ tcase_add_test(tc, test_transform_options);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
--- /dev/null
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2014 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 <stdlib.h>
+#include <check.h>
+#include "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/* Test lots of triggers/stages/matches/channels */
+#define NUM_TRIGGERS 70
+#define NUM_STAGES 30
+#define NUM_MATCHES 70
+#define NUM_CHANNELS NUM_MATCHES
+
+/* Check whether creating/freeing triggers with valid names works. */
+START_TEST(test_trigger_new_free)
+{
+ int i;
+ struct sr_trigger *t[NUM_TRIGGERS];
+ char name[10];
+
+ /* Create a few triggers with a valid name. */
+ for (i = 0; i < NUM_TRIGGERS; i++) {
+ sprintf((char *)&name, "T%d", i);
+ t[i] = sr_trigger_new((const char *)&name);
+ fail_unless(t[i] != NULL);
+ fail_unless(!strcmp(t[i]->name, (const char *)&name));
+ fail_unless(t[i]->stages == NULL);
+ }
+
+ /* Free the triggers again (must not segfault). */
+ for (i = 0; i < NUM_TRIGGERS; i++)
+ sr_trigger_free(t[i]);
+}
+END_TEST
+
+/* Check whether creating/freeing triggers with NULL names works. */
+START_TEST(test_trigger_new_free_null)
+{
+ int i;
+ struct sr_trigger *t[NUM_TRIGGERS];
+
+ /* Create a few triggers with a NULL name (which is allowed). */
+ for (i = 0; i < NUM_TRIGGERS; i++) {
+ t[i] = sr_trigger_new(NULL);
+ fail_unless(t[i] != NULL);
+ fail_unless(t[i]->name == NULL);
+ fail_unless(t[i]->stages == NULL);
+ }
+
+ /* Free the triggers again (must not segfault). */
+ for (i = 0; i < NUM_TRIGGERS; i++)
+ sr_trigger_free(t[i]);
+}
+END_TEST
+
+/* Check whether sr_trigger_free(NULL) works without segfaulting. */
+START_TEST(test_trigger_free_null)
+{
+ sr_trigger_free(NULL);
+}
+END_TEST
+
+/* Check whether creating/freeing triggers with stages works. */
+START_TEST(test_trigger_stage_add)
+{
+ int i, j;
+ struct sr_trigger *t[NUM_TRIGGERS];
+ struct sr_trigger_stage *s[NUM_STAGES];
+
+ /* Create a few triggers with a valid name. */
+ for (i = 0; i < NUM_TRIGGERS; i++) {
+ t[i] = sr_trigger_new("T");
+
+ /* Add a bunch of trigger stages to this trigger. */
+ for (j = 0; j < NUM_STAGES; j++) {
+ s[j] = sr_trigger_stage_add(t[i]);
+ fail_unless(s[j] != NULL);
+ fail_unless(t[i]->stages != NULL);
+ fail_unless((int)g_slist_length(t[i]->stages) == (j + 1));
+ fail_unless(s[j]->stage == j);
+ fail_unless(s[j]->matches == NULL);
+ }
+ }
+
+ /* Free the triggers again (must not segfault). */
+ for (i = 0; i < NUM_TRIGGERS; i++)
+ sr_trigger_free(t[i]);
+}
+END_TEST
+
+/* Check whether creating NULL trigger stages fails (as it should). */
+START_TEST(test_trigger_stage_add_null)
+{
+ /* Should not segfault, but rather return NULL. */
+ fail_unless(sr_trigger_stage_add(NULL) == NULL);
+}
+END_TEST
+
+/* Check whether creating/freeing triggers with matches works. */
+START_TEST(test_trigger_match_add)
+{
+ int i, j, k, tm, ret;
+ struct sr_trigger *t[NUM_TRIGGERS];
+ struct sr_trigger_stage *s[NUM_STAGES];
+ struct sr_channel *chl[NUM_CHANNELS];
+ struct sr_channel *cha[NUM_CHANNELS];
+ char name[10];
+
+ /* Create a bunch of logic and analog channels. */
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ sprintf((char *)&name, "L%d", i);
+ chl[i] = g_malloc0(sizeof(struct sr_channel));
+ chl[i]->index = i;
+ chl[i]->type = SR_CHANNEL_LOGIC;
+ chl[i]->enabled = TRUE;
+ chl[i]->name = g_strdup((const char *)&name);
+
+ sprintf((char *)&name, "A%d", i);
+ cha[i] = g_malloc0(sizeof(struct sr_channel));
+ cha[i]->index = i;
+ cha[i]->type = SR_CHANNEL_ANALOG;
+ cha[i]->enabled = TRUE;
+ cha[i]->name = g_strdup((const char *)&name);
+ }
+
+ /* Create a few triggers with a valid name. */
+ for (i = 0; i < NUM_TRIGGERS; i++) {
+ t[i] = sr_trigger_new("T");
+
+ /* Add a bunch of trigger stages to this trigger. */
+ for (j = 0; j < NUM_STAGES; j++) {
+ s[j] = sr_trigger_stage_add(t[i]);
+
+ /* Add a bunch of matches to this stage. */
+ for (k = 0; k < NUM_MATCHES; k++) {
+ /* Logic channel matches. */
+ tm = 1 + (k % 5); /* *_ZERO .. *_EDGE */
+ ret = sr_trigger_match_add(s[j], chl[k], tm, 0);
+ fail_unless(ret == SR_OK);
+
+ /* Analog channel matches. */
+ tm = 3 + (k % 4); /* *_RISING .. *_UNDER */
+ ret = sr_trigger_match_add(s[j], cha[k],
+ tm, ((rand() % 500) - 500) * 1.739);
+ fail_unless(ret == SR_OK);
+ }
+ }
+ }
+
+ /* Free the triggers again (must not segfault). */
+ for (i = 0; i < NUM_TRIGGERS; i++)
+ sr_trigger_free(t[i]);
+
+ /* Free the channels. */
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ g_free(chl[i]->name);
+ g_free(chl[i]);
+ g_free(cha[i]->name);
+ g_free(cha[i]);
+ }
+}
+END_TEST
+
+/* Check whether trigger_match_add() copes well with incorrect input. */
+START_TEST(test_trigger_match_add_bogus)
+{
+ int ret;
+ struct sr_trigger *t;
+ struct sr_trigger_stage *s, *sl;
+ struct sr_channel *chl, *cha;
+
+ t = sr_trigger_new("T");
+ s = sr_trigger_stage_add(t);
+ chl = g_malloc0(sizeof(struct sr_channel));
+ chl->index = 0;
+ chl->type = SR_CHANNEL_LOGIC;
+ chl->enabled = TRUE;
+ chl->name = g_strdup("L0");
+ cha = g_malloc0(sizeof(struct sr_channel));
+ cha->index = 1;
+ cha->type = SR_CHANNEL_ANALOG;
+ cha->enabled = TRUE;
+ cha->name = g_strdup("A0");
+
+ /* Initially we have no matches at all. */
+ sl = t->stages->data;
+ fail_unless(g_slist_length(sl->matches) == 0);
+
+ /* NULL stage */
+ ret = sr_trigger_match_add(NULL, chl, SR_TRIGGER_ZERO, 0);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+
+ /* NULL channel */
+ ret = sr_trigger_match_add(s, NULL, SR_TRIGGER_ZERO, 0);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+
+ /* Invalid trigger matches for logic channels. */
+ ret = sr_trigger_match_add(s, chl, SR_TRIGGER_OVER, 0);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+ ret = sr_trigger_match_add(s, chl, SR_TRIGGER_UNDER, 0);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+
+ /* Invalid trigger matches for analog channels. */
+ ret = sr_trigger_match_add(s, cha, SR_TRIGGER_ZERO, 9.4);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+ ret = sr_trigger_match_add(s, cha, SR_TRIGGER_ONE, -9.4);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+
+ /* Invalid channel type. */
+ chl->type = -1;
+ ret = sr_trigger_match_add(s, chl, SR_TRIGGER_ZERO, 0);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+ chl->type = 270;
+ ret = sr_trigger_match_add(s, chl, SR_TRIGGER_ZERO, 0);
+ fail_unless(ret == SR_ERR_ARG);
+ fail_unless(g_slist_length(sl->matches) == 0);
+
+ sr_trigger_free(t);
+ g_free(chl->name);
+ g_free(chl);
+ g_free(cha->name);
+ g_free(cha);
+}
+END_TEST
+
+Suite *suite_trigger(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("trigger");
+
+ tc = tcase_create("new_free");
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_trigger_new_free);
+ tcase_add_test(tc, test_trigger_new_free_null);
+ tcase_add_test(tc, test_trigger_free_null);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("stage");
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_trigger_stage_add);
+ tcase_add_test(tc, test_trigger_stage_add_null);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("match");
+ tcase_set_timeout(tc, 0);
+ tcase_add_checked_fixture(tc, srtest_setup, srtest_teardown);
+ tcase_add_test(tc, test_trigger_match_add);
+ tcase_add_test(tc, test_trigger_match_add_bogus);
+ 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 "../include/libsigrok/libsigrok.h"
+#include "lib.h"
+
+/*
+ * Check the version number API calls and macros.
+ *
+ * The numbers returned by the sr_*_version*get() calls must match the
+ * respective SR_*_VERSION* macro values, must be >= 0, and must not be
+ * unreasonably high (> 20), otherwise something is probably wrong.
+ */
+START_TEST(test_version_numbers)
+{
+ int ver;
+
+ ver = sr_package_version_major_get();
+ fail_unless(ver == SR_PACKAGE_VERSION_MAJOR);
+ fail_unless(ver >= 0 && ver <= 20);
+ ver = sr_package_version_minor_get();
+ fail_unless(ver == SR_PACKAGE_VERSION_MINOR);
+ fail_unless(ver >= 0 && ver <= 20);
+ ver = sr_package_version_micro_get();
+ fail_unless(ver == SR_PACKAGE_VERSION_MICRO);
+ fail_unless(ver >= 0 && ver <= 20);
+
+ ver = sr_lib_version_current_get();
+ fail_unless(ver == SR_LIB_VERSION_CURRENT);
+ fail_unless(ver >= 0 && ver <= 20);
+ ver = sr_lib_version_revision_get();
+ fail_unless(ver == SR_LIB_VERSION_REVISION);
+ fail_unless(ver >= 0 && ver <= 20);
+ ver = sr_lib_version_age_get();
+ fail_unless(ver == SR_LIB_VERSION_AGE);
+ fail_unless(ver >= 0 && ver <= 20);
+}
+END_TEST
+
+/*
+ * Check the version number API calls and macros.
+ *
+ * The string representations of the package/lib version must match the
+ * version numbers, the string lengths must be >= 5 (e.g. "0.1.0"), and
+ * the strings length must be <= 20 characters, otherwise something is
+ * probably wrong.
+ */
+START_TEST(test_version_strings)
+{
+ const char *str;
+
+ str = sr_package_version_string_get();
+ fail_unless(str != NULL);
+ fail_unless(strlen(str) >= 5 && strlen(str) <= 20);
+ str = sr_lib_version_string_get();
+ fail_unless(str != NULL);
+ fail_unless(strlen(str) >= 5 && strlen(str) <= 20);
+}
+END_TEST
+
+Suite *suite_version(void)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("version");
+
+ tc = tcase_create("version");
+ tcase_add_test(tc, test_version_numbers);
+ tcase_add_test(tc, test_version_strings);
+ suite_add_tcase(s, tc);
+
+ return s;
+}