X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;ds=inline;f=tests%2Ftrigger.c;fp=tests%2Ftrigger.c;h=bf177602b8c0551d686ef30b40e7d70c51241dfb;hb=02a2bf688f25a50ea05276be75fba8b4f644fca6;hp=0000000000000000000000000000000000000000;hpb=d258022db0b79dffc2bbdde0882e821966dbc312;p=libsigrok.git diff --git a/tests/trigger.c b/tests/trigger.c new file mode 100644 index 00000000..bf177602 --- /dev/null +++ b/tests/trigger.c @@ -0,0 +1,280 @@ +/* + * This file is part of the libsigrok project. + * + * Copyright (C) 2014 Uwe Hermann + * + * 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 +#include +#include +#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; +}