From 17aac211029b407f9107ea3460483fbe55c03949 Mon Sep 17 00:00:00 2001 From: amalec Date: Tue, 2 Oct 2001 15:38:48 +0000 Subject: [PATCH] First generation packing code as the infrastructure to revising message passing between processes, to accomodate context messages git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@97 64e312b2-a51f-0410-8e61-82d0ca0eb02a --- check/doc/index.html | 2 +- check/doc/tutorial.lyx | 2 +- check/src/Makefile.am | 13 +- check/src/Makefile.in | 10 +- check/src/check.c | 17 ++- check/src/check.h | 35 +++-- check/src/check_magic.h | 4 +- check/src/check_msg.h | 1 - check/src/check_pack.c | 204 +++++++++++++++++++++++++++++ check/src/check_pack.h | 56 ++++++++ check/tests/Makefile.am | 1 + check/tests/Makefile.in | 10 +- check/tests/check_check.h | 1 + check/tests/check_check_fixture.c | 2 +- check/tests/check_check_fork.c | 2 +- check/tests/check_check_limit.c | 2 +- check/tests/check_check_main.c | 1 + check/tests/check_check_master.c | 3 +- check/tests/check_check_msg.c | 2 +- check/tests/check_check_pack.c | 206 ++++++++++++++++++++++++++++++ 20 files changed, 538 insertions(+), 36 deletions(-) create mode 100644 check/src/check_pack.c create mode 100644 check/src/check_pack.h create mode 100644 check/tests/check_check_pack.c diff --git a/check/doc/index.html b/check/doc/index.html index bbff3ca..2c890b0 100644 --- a/check/doc/index.html +++ b/check/doc/index.html @@ -15,7 +15,7 @@

Check was inspired by similar frameworks that currently exist for most programming languages; the most famous example being - JUnit for Java (www.junit.com). There + JUnit for Java (www.junit.org). There is a list of unit test frameworks for multiple languages at www.xprogramming.com/software.htm . Unit testing has a long history as part of formal quality diff --git a/check/doc/tutorial.lyx b/check/doc/tutorial.lyx index f49e7c7..af10701 100644 --- a/check/doc/tutorial.lyx +++ b/check/doc/tutorial.lyx @@ -53,7 +53,7 @@ Introduction Check is a unit testing framework for C. It was inspired by similar frameworks that currently exist for most programming languages; the most famous example being JUnit for Java ( -\begin_inset LatexCommand \htmlurl[www.junit.com]{www.junit.com} +\begin_inset LatexCommand \htmlurl[www.junit.org]{http://www.junit.org} \end_inset diff --git a/check/src/Makefile.am b/check/src/Makefile.am index dfaa971..e5b3cb8 100644 --- a/check/src/Makefile.am +++ b/check/src/Makefile.am @@ -3,13 +3,14 @@ lib_LIBRARIES=libcheck.a include_HEADERS=check.h libcheck_a_SOURCES=\ - check.c check_run.c check.h check_impl.h\ - check_msg.c check_msg.h\ - check_log.c check_log.h\ + check.h check_impl.h check.c check_run.c\ + check_pack.h check_pack.c\ + check_msg.h check_msg.c\ + check_log.h check_log.c\ check_str.h check_str.c\ - check_print.c check_print.h\ - error.c error.h\ - list.c list.h + check_print.h check_print.c\ + error.h error.c\ + list.h list.c CLEANFILES=*.*~ \ No newline at end of file diff --git a/check/src/Makefile.in b/check/src/Makefile.in index dd0d2a7..d0341e2 100644 --- a/check/src/Makefile.in +++ b/check/src/Makefile.in @@ -70,7 +70,7 @@ lib_LIBRARIES = libcheck.a include_HEADERS = check.h -libcheck_a_SOURCES = check.c check_run.c check.h check_impl.h check_msg.c check_msg.h check_log.c check_log.h check_str.h check_str.c check_print.c check_print.h error.c error.h list.c list.h +libcheck_a_SOURCES = check.h check_impl.h check.c check_run.c check_pack.h check_pack.c check_msg.h check_msg.c check_log.h check_log.c check_str.h check_str.c check_print.h check_print.c error.h error.c list.h list.c CLEANFILES = *.*~ @@ -85,8 +85,8 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libcheck_a_LIBADD = -libcheck_a_OBJECTS = check.o check_run.o check_msg.o check_log.o \ -check_str.o check_print.o error.o list.o +libcheck_a_OBJECTS = check.o check_run.o check_pack.o check_msg.o \ +check_log.o check_str.o check_print.o error.o list.o AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -102,8 +102,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best DEP_FILES = .deps/check.P .deps/check_log.P .deps/check_msg.P \ -.deps/check_print.P .deps/check_run.P .deps/check_str.P .deps/error.P \ -.deps/list.P +.deps/check_pack.P .deps/check_print.P .deps/check_run.P \ +.deps/check_str.P .deps/error.P .deps/list.P SOURCES = $(libcheck_a_SOURCES) OBJECTS = $(libcheck_a_OBJECTS) diff --git a/check/src/check.c b/check/src/check.c index f37e79c..b204c9a 100644 --- a/check/src/check.c +++ b/check/src/check.c @@ -27,6 +27,9 @@ static int non_pass (int val); static Fixture *fixture_create (SFun fun, int ischecked); +static void tcase_add_fixture (TCase *tc, SFun setup, SFun teardown, + int ischecked); + Suite *suite_create (char *name) { @@ -113,8 +116,18 @@ static Fixture *fixture_create (SFun fun, int ischecked) return f; } - -void tcase_add_fixture (TCase *tc, SFun setup, SFun teardown, int ischecked) +void tcase_add_unchecked_fixture (TCase *tc, SFun setup, SFun teardown) +{ + tcase_add_fixture(tc,setup,teardown,0); +} + +void tcase_add_checked_fixture (TCase *tc, SFun setup, SFun teardown) +{ + tcase_add_fixture (tc,setup,teardown,1); +} + +static void tcase_add_fixture (TCase *tc, SFun setup, SFun teardown, + int ischecked) { if (setup) { if (ischecked) diff --git a/check/src/check.h b/check/src/check.h index 77ebc78..b434214 100644 --- a/check/src/check.h +++ b/check/src/check.h @@ -106,20 +106,37 @@ void tcase_free (TCase *tc); (function version -- use this when the macro won't work */ void _tcase_add_test (TCase *tc, TFun tf, char *fname); +/* Add unchecked fixture setup/teardown functions to a test case + + If unchecked fixture functions are run at the start and end of the + test case, and not before and after unit tests. Note that unchecked + setup/teardown functions are not run in a separate address space, + like test functions, and so must not exit or signal (e.g., + segfault) + + Also, when run in CK_NOFORK mode, unchecked fixture functions may + lead to different unit test behavior IF unit tests change data + setup by the fixture functions. +*/ +void tcase_add_unchecked_fixture (TCase *tc, SFun setup, SFun teardown); + /* Add fixture setup/teardown functions to a test case - If ischecked, fixture functions are run in the same address space - as the unit tests, once per unit test. If the tests are run - CK_NOFORK, they are still run before and after each unit test. + Checked fixture functions are run before and after unit + tests. Unlike unchecked fixture functions, checked fixture + functions are run in the same separate address space as the test + program, and thus the test function will survive signals or + unexpected exits in the fixture function. Also, IF the setup + function is idempotent, unit test behavior will be the same in + CK_FORK and CK_NOFORK modes. - If not ischecked, fixture functions are run at the start and end of - the test case, and not before and after unit tests. Note that - unchecked setup/teardown functions are not run in a separate - address space, like test functions, and so must not exit or signal - (e.g., segfault) + However, since fixture functions are run before and after each unit + test, they should not be expensive code. */ -void tcase_add_fixture (TCase *tc, SFun setup, SFun teardown, int ischecked); + +void tcase_add_checked_fixture (TCase *tc, SFun setup, SFun teardown); + /* Internal function to mark the start of a test function */ void tcase_fn_start (char *fname, char *file, int line); diff --git a/check/src/check_magic.h b/check/src/check_magic.h index 1878cff..2fa1792 100644 --- a/check/src/check_magic.h +++ b/check/src/check_magic.h @@ -28,7 +28,9 @@ enum { CK_MAXLINE = 9999, /* maximum line no */ - CK_MAXMSG = 100 /* maximum length of a message, including terminating nul */ + CK_MAXMSG = 100, /* maximum length of a message, including + terminating nul */ + CK_MAXMSGBUF = 200 /* maximum length of a message buffer */ }; #endif /*CHECK_MAGIC_H*/ diff --git a/check/src/check_msg.h b/check/src/check_msg.h index 3cd3903..b899c5e 100644 --- a/check/src/check_msg.h +++ b/check/src/check_msg.h @@ -21,7 +21,6 @@ */ /* Functions implementing messaging during test runs */ -/* check.h must be included before this header */ /* Abstract type for a messaging system Hides the details (IPC msg vs. pipes vs...*/ diff --git a/check/src/check_pack.c b/check/src/check_pack.c new file mode 100644 index 0000000..7bb0904 --- /dev/null +++ b/check/src/check_pack.c @@ -0,0 +1,204 @@ +/* + Check: a unit test framework for C + Copyright (C) 2001, Arien Malec + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include +#include +#include + +#include "error.h" +#include "check_pack.h" +#include "check_magic.h" + + +static void pack_int (char **buf, int val); +static int upack_int (char **buf); +static void pack_str (char **buf, char *str); +static char *upack_str (char **buf); + +static void pack_ctx (char **buf, void *msg); +static void pack_loc (char **buf, void *msg); +static void pack_fail (char **buf, void *msg); +static void upack_ctx (char **buf, void *msg); +static void upack_loc (char **buf, void *msg); +static void upack_fail (char **buf, void *msg); + +static void check_type (int type, char *file, int line); +static enum ck_msg_type upack_type (char **buf); +static void pack_type (char **buf, enum ck_msg_type type); + +typedef void (*pfun) (char **, void *); + +static pfun pftab [] = { + pack_ctx, + pack_fail, + pack_loc +}; + +static pfun upftab [] = { + upack_ctx, + upack_fail, + upack_loc +}; + +int pack (enum ck_msg_type type, char *buf, void *data) +{ + char *obuf; + + if (buf == NULL) + return -1; + if (data == NULL) + return 0; + obuf = buf; + + check_type(type, __FILE__, __LINE__); + + pack_type(&buf, type); + + pftab[type] (&buf, data); + + return buf - obuf; +} + +enum ck_msg_type upack (char *buf, void *data) +{ + enum ck_msg_type type; + + type = upack_type (&buf); + + check_type(type, __FILE__, __LINE__); + + upftab[type] (&buf, data); + + return type; +} + +static void pack_int (char **buf, int val) +{ + int n; + + n = sprintf (*buf, "%d", val); + + *buf += n + 1; +} + +static int upack_int (char **buf) +{ + int val; + char *endptr; + + val = (int) strtol (*buf, &endptr, 10); + + *buf = endptr + 1; + + return val; +} + +static void pack_str (char **buf, char *val) +{ + int strsz; + int n; + + if (val == NULL) + strsz = 0; + else + strsz = strlen (val) + 1; + + pack_int(buf,strsz); + n = sprintf (*buf, "%s", val); + + *buf += n + 1; +} + +static char *upack_str (char **buf) +{ + char *val; + int strsz; + + val = emalloc (CK_MAXMSG); + + strsz = upack_int (buf); + + strncpy (val, *buf, strsz); + *buf += strsz; + + return val; +} + +static void pack_type (char **buf, enum ck_msg_type type) +{ + pack_int(buf, (int) type); +} + +static enum ck_msg_type upack_type (char **buf) +{ + return (enum ck_msg_type) upack_int(buf); +} + + +static void pack_ctx (char **buf, void *msg) +{ + CtxMsg *cmsg = msg; + pack_int(buf,(int) cmsg->ctx); +} + +static void upack_ctx (char **buf, void *msg) +{ + CtxMsg *cmsg = msg; + + cmsg->ctx = upack_int (buf); + + return; +} + +static void pack_loc (char **buf, void *msg) +{ + LocMsg *lmsg = msg; + + pack_str (buf, lmsg->file); + pack_int (buf, lmsg->line); + +} + +static void upack_loc (char **buf, void *msg) +{ + + LocMsg *lmsg = msg; + + lmsg->file = upack_str(buf); + lmsg->line = upack_int(buf); + return; +} + +static void pack_fail (char **buf, void *msg) +{ + FailMsg *fmsg = msg; + pack_str (buf, fmsg->msg); +} + +static void upack_fail (char **buf, void *msg) +{ + FailMsg *fmsg = msg; + fmsg->msg = upack_str(buf); +} + +static void check_type (int type, char *file, int line) +{ + if (type >= CK_MSG_LAST) + eprintf ("%s:%d:Bad message type arg", file, line); +} + diff --git a/check/src/check_pack.h b/check/src/check_pack.h new file mode 100644 index 0000000..02fffb7 --- /dev/null +++ b/check/src/check_pack.h @@ -0,0 +1,56 @@ +#ifndef CHECK_PACK_H +#define CHECK_PACK_H + +/* + Check: a unit test framework for C + Copyright (C) 2001, Arien Malec + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +enum ck_msg_type { + CK_MSG_CTX, + CK_MSG_FAIL, + CK_MSG_LOC, + CK_MSG_LAST +}; + +enum ck_msg_context { + CK_CTX_SETUP, + CK_CTX_TEST, + CK_CTX_TEARDOWN +}; + +typedef struct CtxMsg +{ + enum ck_msg_context ctx; +} CtxMsg; + +typedef struct LocMsg +{ + int line; + char *file; +} LocMsg; + +typedef struct FailMsg +{ + char *msg; +} FailMsg; + + +int pack (enum ck_msg_type type, char *buf, void *data); +enum ck_msg_type upack (char *buf, void *data); + +#endif /*CHECK_PACK_H */ diff --git a/check/tests/Makefile.am b/check/tests/Makefile.am index b589356..4731a6c 100644 --- a/check/tests/Makefile.am +++ b/check/tests/Makefile.am @@ -23,6 +23,7 @@ check_check_SOURCES= \ check_check_limit.c\ check_check_fork.c\ check_check_fixture.c\ + check_check_pack.c\ check_check_main.c check_stress_SOURCES=\ diff --git a/check/tests/Makefile.in b/check/tests/Makefile.in index 893257d..8106935 100644 --- a/check/tests/Makefile.in +++ b/check/tests/Makefile.in @@ -75,7 +75,7 @@ noinst_PROGRAMS = check_check check_stress ex_output ex_log_output ex_setu EXTRA_DIST = test_output.sh test_log_output.sh -check_check_SOURCES = check_check.h check_list.c check_check_sub.c check_check_master.c check_check_msg.c check_check_log.c check_check_limit.c check_check_fork.c check_check_fixture.c check_check_main.c +check_check_SOURCES = check_check.h check_list.c check_check_sub.c check_check_master.c check_check_msg.c check_check_log.c check_check_limit.c check_check_fork.c check_check_fixture.c check_check_pack.c check_check_main.c check_stress_SOURCES = check_stress.c @@ -107,7 +107,7 @@ LIBS = @LIBS@ check_check_OBJECTS = check_list.o check_check_sub.o \ check_check_master.o check_check_msg.o check_check_log.o \ check_check_limit.o check_check_fork.o check_check_fixture.o \ -check_check_main.o +check_check_pack.o check_check_main.o check_check_LDADD = $(LDADD) check_check_DEPENDENCIES = ../src/libcheck.a check_check_LDFLAGS = @@ -141,9 +141,9 @@ GZIP_ENV = --best DEP_FILES = .deps/check_check_fixture.P .deps/check_check_fork.P \ .deps/check_check_limit.P .deps/check_check_log.P \ .deps/check_check_main.P .deps/check_check_master.P \ -.deps/check_check_msg.P .deps/check_check_sub.P .deps/check_list.P \ -.deps/check_stress.P .deps/ex_log_output.P .deps/ex_output.P \ -.deps/ex_setup_output.P +.deps/check_check_msg.P .deps/check_check_pack.P \ +.deps/check_check_sub.P .deps/check_list.P .deps/check_stress.P \ +.deps/ex_log_output.P .deps/ex_output.P .deps/ex_setup_output.P SOURCES = $(check_check_SOURCES) $(check_stress_SOURCES) $(ex_output_SOURCES) $(ex_log_output_SOURCES) $(ex_setup_output_SOURCES) OBJECTS = $(check_check_OBJECTS) $(check_stress_OBJECTS) $(ex_output_OBJECTS) $(ex_log_output_OBJECTS) $(ex_setup_output_OBJECTS) diff --git a/check/tests/check_check.h b/check/tests/check_check.h index 492645c..c4cf67d 100644 --- a/check/tests/check_check.h +++ b/check/tests/check_check.h @@ -19,5 +19,6 @@ Suite *make_log_suite(void); Suite *make_limit_suite(void); Suite *make_fork_suite(void); Suite *make_fixture_suite(void); +Suite *make_pack_suite(void); #endif /* CHECK_CHECK_H */ diff --git a/check/tests/check_check_fixture.c b/check/tests/check_check_fixture.c index 46fcbe6..ce76773 100644 --- a/check/tests/check_check_fixture.c +++ b/check/tests/check_check_fixture.c @@ -20,7 +20,7 @@ void setup_fixture (void) fixture_s = suite_create("Fix Sub"); tc = tcase_create("Core"); - tcase_add_fixture(tc, fixture_sub_setup, NULL, 0); + tcase_add_unchecked_fixture(tc, fixture_sub_setup, NULL); suite_add_tcase (fixture_s, tc); fixture_sr = srunner_create(fixture_s); srunner_run_all(fixture_sr,CRSILENT); diff --git a/check/tests/check_check_fork.c b/check/tests/check_check_fork.c index 0be615a..106693e 100644 --- a/check/tests/check_check_fork.c +++ b/check/tests/check_check_fork.c @@ -44,7 +44,7 @@ static Suite *make_fork_sub_suite (void) tc = tcase_create("Core"); suite_add_tcase (s, tc); - tcase_add_fixture(tc, fork_sub_setup,NULL, 0); + tcase_add_unchecked_fixture(tc, fork_sub_setup,NULL); tcase_add_test(tc,test_inc); tcase_add_test(tc,test_nofork_sideeffects); tcase_add_test(tc,test_nofork_pid); diff --git a/check/tests/check_check_limit.c b/check/tests/check_check_limit.c index bb0075a..762b640 100644 --- a/check/tests/check_check_limit.c +++ b/check/tests/check_check_limit.c @@ -33,7 +33,7 @@ Suite *make_limit_suite (void) TCase *tc = tcase_create("Empty"); tcase_add_test(tc,test_summary); - tcase_add_fixture(tc,limit_setup,limit_teardown, 0); + tcase_add_unchecked_fixture(tc,limit_setup,limit_teardown); suite_add_tcase(s, tc); diff --git a/check/tests/check_check_main.c b/check/tests/check_check_main.c index 675d9cb..a4971ad 100644 --- a/check/tests/check_check_main.c +++ b/check/tests/check_check_main.c @@ -17,6 +17,7 @@ int main (void) srunner_add_suite(sr, make_limit_suite()); srunner_add_suite(sr, make_fork_suite()); srunner_add_suite(sr, make_fixture_suite()); + srunner_add_suite(sr, make_pack_suite()); setup(); printf ("Ran %d tests in subordinate suite\n", sub_nfailed); diff --git a/check/tests/check_check_master.c b/check/tests/check_check_master.c index f955c72..e72af53 100644 --- a/check/tests/check_check_master.c +++ b/check/tests/check_check_master.c @@ -237,7 +237,8 @@ Suite *make_master_suite (void) tcase_add_test (tc_core, test_check_failure_tcnames); tcase_add_test (tc_core, test_check_all_msgs); tcase_add_test (tc_core, test_check_all_ftypes); - tcase_add_fixture(tc_fixture, test_fixture_setup, test_fixture_teardown, 0); + tcase_add_unchecked_fixture(tc_fixture, test_fixture_setup, + test_fixture_teardown); /* add the test 3 times to make sure we adequately test preservation of fixture values across tests, regardless of the order in which tests are added to the test case */ diff --git a/check/tests/check_check_msg.c b/check/tests/check_check_msg.c index da7022b..6c05d32 100644 --- a/check/tests/check_check_msg.c +++ b/check/tests/check_check_msg.c @@ -58,7 +58,7 @@ Suite *make_msg_suite (void) TCase *tc; s = suite_create("Msg"); tc = tcase_create("Core Tests"); - tcase_add_fixture(tc, msg_setup, msg_teardown, 0); + tcase_add_unchecked_fixture(tc, msg_setup, msg_teardown); tcase_add_test(tc, test_send_failure); tcase_add_test(tc, test_send_lastloc); suite_add_tcase(s, tc); diff --git a/check/tests/check_check_pack.c b/check/tests/check_check_pack.c new file mode 100644 index 0000000..7fe3352 --- /dev/null +++ b/check/tests/check_check_pack.c @@ -0,0 +1,206 @@ +#include +#include + +#include +#include "check_magic.h" +#include "check_pack.h" +#include "error.h" +#include "check_check.h" + +START_TEST(test_pack_fmsg) +{ + FailMsg *fmsg; + char *buf; + enum ck_msg_type type; + + fmsg = emalloc (sizeof(FailMsg)); + buf = emalloc (CK_MAXMSGBUF); + fmsg->msg = "Hello, world!"; + + pack (CK_MSG_FAIL, buf, fmsg); + fmsg->msg = ""; + type = upack (buf, fmsg); + + fail_unless (type == CK_MSG_FAIL, + "Bad type unpacked for FailMsg"); + + if (strcmp (fmsg->msg, "Hello, world!") != 0) { + char *msg = emalloc(CK_MAXMSG); + snprintf (msg,CK_MAXMSG, + "Unpacked string is %s, should be Hello, World!", + fmsg->msg); + + fail(msg); + } + + free(fmsg->msg); + free(fmsg); + free(buf); +} +END_TEST + +START_TEST(test_pack_loc) +{ + LocMsg *lmsg; + char *buf; + enum ck_msg_type type; + + lmsg = emalloc (sizeof(LocMsg)); + buf = emalloc (CK_MAXMSGBUF); + lmsg->file = "abc123.c"; + lmsg->line = 125; + + pack (CK_MSG_LOC, buf, lmsg); + lmsg->file = ""; + lmsg->line = 0; + type = upack (buf, lmsg); + + fail_unless (type == CK_MSG_LOC, + "Bad type unpacked for LocMsg"); + + if (lmsg->line != 125) { + char *errm = emalloc (CK_MAXMSG); + snprintf(errm, CK_MAXMSG, + "LocMsg line was %d, should be %d", + lmsg->line, 125); + fail (errm); + } + + if (strcmp (lmsg->file, "abc123.c") != 0) { + char *errm = emalloc (CK_MAXMSG); + snprintf(errm, CK_MAXMSG, + "LocMsg file was %s, should be abc123.c", + lmsg->file); + fail (errm); + } + + free (lmsg->file); + free (lmsg); + free (buf); +} +END_TEST + +START_TEST(test_pack_ctx) +{ + CtxMsg *cmsg; + char *buf; + enum ck_msg_type type; + + cmsg = emalloc (sizeof(CtxMsg)); + buf = emalloc (CK_MAXMSGBUF); + cmsg->ctx = CK_CTX_SETUP; + + pack (CK_MSG_CTX, buf, cmsg); + cmsg->ctx = CK_CTX_TEARDOWN; + type = upack (buf, cmsg); + + fail_unless (type == CK_MSG_CTX, + "Bad type unpacked for CtxMsg"); + + if (cmsg->ctx != CK_CTX_SETUP) { + char *errm = emalloc (CK_MAXMSG); + snprintf(errm, CK_MAXMSG, + "CtxMsg ctx got %d, expected %d", + cmsg->ctx, CK_CTX_SETUP); + fail (errm); + } + + free (cmsg); + free (buf); + +} +END_TEST + +START_TEST(test_pack_len) +{ + CtxMsg cmsg; + char *buf; + int n = 0; + + buf = emalloc (CK_MAXMSGBUF); + cmsg.ctx = CK_CTX_TEST; + n = pack(CK_MSG_CTX,buf,&cmsg); + fail_unless (n > 0, "Return val from pack not set correctly"); + + /* Value below may change with different implementations of pack */ + fail_unless (n == 4, "Return val from pack not correct"); + + free(buf); +} +END_TEST + +START_TEST(test_pack_ctx_limit) +{ + CtxMsg cmsg; + CtxMsg *cmsgp = NULL; + char *buf; + + cmsg.ctx = -1; + buf = emalloc (CK_MAXMSGBUF); + pack(CK_MSG_CTX,buf,&cmsg); + pack(CK_MSG_CTX,buf,cmsgp); + +} +END_TEST + +START_TEST(test_pack_fail_limit) +{ + FailMsg fmsg; + FailMsg *fmsgp = NULL; + char *buf; + + buf = emalloc (CK_MAXMSGBUF); + fmsg.msg = ""; + pack(CK_MSG_FAIL,buf,&fmsg); + (void) upack(buf,&fmsg); + fail_unless (strcmp(fmsg.msg, "") == 0, "Empty string not handled properly"); + free(fmsg.msg); + fmsg.msg = NULL; + pack(CK_MSG_FAIL,buf,&fmsg); + pack(CK_MSG_FAIL,buf,fmsgp); +} +END_TEST + +START_TEST(test_pack_loc_limit) +{ + LocMsg lmsg; + LocMsg *lmsgp = NULL; + char *buf; + + buf = emalloc (CK_MAXMSGBUF); + lmsg.file = ""; + lmsg.line = 0; + pack(CK_MSG_LOC,buf,&lmsg); + (void) upack(buf,&lmsg); + fail_unless (strcmp(lmsg.file, "") == 0, + "Empty string not handled properly"); + free(lmsg.file); + lmsg.file = NULL; + pack(CK_MSG_LOC,buf,&lmsg); + pack(CK_MSG_LOC,buf,lmsgp); +} +END_TEST + +Suite *make_pack_suite(void) +{ + + Suite *s; + TCase *tc_core; + TCase *tc_limit; + + s = suite_create("Pack"); + tc_core = tcase_create("Core"); + tc_limit = tcase_create("Limit"); + + suite_add_tcase(s, tc_core); + tcase_add_test(tc_core, test_pack_fmsg); + tcase_add_test(tc_core, test_pack_loc); + tcase_add_test(tc_core, test_pack_ctx); + tcase_add_test(tc_core, test_pack_len); + suite_add_tcase(s, tc_limit); + tcase_add_test(tc_limit, test_pack_ctx_limit); + tcase_add_test(tc_limit, test_pack_fail_limit); + tcase_add_test(tc_limit, test_pack_loc_limit); + + return s; +} -- 2.40.0