From 7c904d880db37713c26b19c4722b1063b220a330 Mon Sep 17 00:00:00 2001 From: dbs Date: Sun, 8 May 2011 15:35:28 +0000 Subject: [PATCH] Add a C unit testing framework and tests for OpenSRF The unit testing framework is "Check" - http://check.sourceforge.net/ These tests can be executed by running 'make check' after you configure and compile the OpenSRF code. To run them, you must have the 'check' package installed. Author: Kevin Beswick Signed-off-by: Dan Scott Signed-off-by: Kevin Beswick git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@2237 9efc2488-bf62-4759-914b-345cdb29e865 --- Makefile.am | 2 +- configure.ac | 11 + src/extras/Makefile.install | 1 + tests/Makefile.am | 32 +++ tests/check_osrf_json_object.c | 347 +++++++++++++++++++++++++++++ tests/check_osrf_list.c | 383 ++++++++++++++++++++++++++++++++ tests/check_osrf_message.c | 98 ++++++++ tests/check_osrf_stack.c | 41 ++++ tests/check_transport_client.c | 248 +++++++++++++++++++++ tests/check_transport_message.c | 279 +++++++++++++++++++++++ tests/testsuite.c | 15 ++ tests/testsuite.h | 4 + 12 files changed, 1460 insertions(+), 1 deletion(-) create mode 100644 tests/Makefile.am create mode 100644 tests/check_osrf_json_object.c create mode 100644 tests/check_osrf_list.c create mode 100644 tests/check_osrf_message.c create mode 100644 tests/check_osrf_stack.c create mode 100644 tests/check_transport_client.c create mode 100644 tests/check_transport_message.c create mode 100644 tests/testsuite.c create mode 100644 tests/testsuite.h diff --git a/Makefile.am b/Makefile.am index 6e6f5d1..048b766 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,7 +115,7 @@ opensrfinclude_HEADERS = $(OSRFINC)/log.h \ src/gateway/apachetools.h endif -SUBDIRS = src +SUBDIRS = src tests jserver: make -s -C src jserver diff --git a/configure.ac b/configure.ac index 6cc828c..2b60acb 100644 --- a/configure.ac +++ b/configure.ac @@ -294,6 +294,15 @@ if test "x$OSRF_INSTALL_CORE" = "xtrue"; then AC_SUBST(memcached_CFLAGS) AC_SUBST(memcached_LIBS) + # Check Unit test framework + PKG_CHECK_MODULES([CHECK], [check >= 0.9.0], [enable_tests=yes], + [enable_tests=no]) + AM_CONDITIONAL(CHECK_TESTS, test x$enable_tests = xyes) + + if test "x$enable_tests" = "xno"; then + AC_MSG_WARN(Check unit testing framwork not found.) + fi + #----------------------------- # Checks for header files. #----------------------------- @@ -312,6 +321,7 @@ if test "x$OSRF_INSTALL_CORE" = "xtrue"; then AC_TYPE_SIZE_T AC_HEADER_TIME AC_STRUCT_TM + AM_PROG_CC_C_O #---------------------------------- # Checks for library functions. @@ -343,6 +353,7 @@ if test "x$OSRF_INSTALL_CORE" = "xtrue"; then src/python/opensrf.py src/router/Makefile src/srfsh/Makefile + tests/Makefile bin/opensrf-perl.pl bin/osrf_config bin/osrf_ctl.sh]) diff --git a/src/extras/Makefile.install b/src/extras/Makefile.install index 5cc4252..9bcf60e 100644 --- a/src/extras/Makefile.install +++ b/src/extras/Makefile.install @@ -81,6 +81,7 @@ DEBS = \ autoconf\ automake\ build-essential\ + check\ ejabberd\ less\ libapache2-mod-perl2\ diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..107872d --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,32 @@ +COMMON = testsuite.c +OSRF_INC = $(top_srcdir)/include/opensrf +AM_LDFLAGS = $(DEF_LDFLAGS) -R $(libdir) + +TESTS = check_osrf_message check_osrf_json_object check_osrf_list check_osrf_stack check_transport_client \ + check_transport_message +check_PROGRAMS = check_osrf_message check_osrf_json_object check_osrf_list check_osrf_stack check_transport_client \ + check_transport_message + +check_osrf_message_SOURCES = $(COMMON) $(OSRF_INC)/osrf_message.h check_osrf_message.c +check_osrf_message_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS) +check_osrf_message_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la + +check_osrf_json_object_SOURCES = $(COMMON) $(OSRF_INC)/osrf_json_object.h check_osrf_json_object.c +check_osrf_json_object_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS) +check_osrf_json_object_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la + +check_osrf_list_SOURCES = $(COMMON) $(OSRF_INC)/osrf_list.h check_osrf_list.c +check_osrf_list_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS) +check_osrf_list_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la + +check_osrf_stack_SOURCES = $(COMMON) $(OSRF_INC)/osrf_stack.h check_osrf_stack.c +check_osrf_stack_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS) +check_osrf_stack_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la + +check_transport_client_SOURCES = $(COMMON) $(OSRF_INC)/transport_client.h check_transport_client.c +check_transport_client_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS) +check_transport_client_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la + +check_transport_message_SOURCES = $(COMMON) $(OSRF_INC)/transport_message.h check_transport_message.c +check_transport_message_CFLAGS = @CHECK_CFLAGS@ $(DEF_CFLAGS) +check_transport_message_LDADD = @CHECK_LIBS@ $(top_builddir)/src/libopensrf/libopensrf.la diff --git a/tests/check_osrf_json_object.c b/tests/check_osrf_json_object.c new file mode 100644 index 0000000..bd0bd37 --- /dev/null +++ b/tests/check_osrf_json_object.c @@ -0,0 +1,347 @@ +#include +#include "opensrf/osrf_json.h" + +jsonObject *jsonObj; +jsonObject *jsonHash; +jsonObject *jsonNumber; +jsonObject *jsonBool; +jsonObject *jsonArray; + +//Set up the test fixture +void setup (void) { + jsonObj = jsonNewObject("test"); + jsonHash = jsonNewObject(NULL); + jsonNumber = jsonNewNumberObject(123.456); + jsonBool = jsonNewBoolObject(0); + jsonArray = jsonNewObjectType(JSON_ARRAY); +} + +//Clean up the test fixture +void teardown (void) { + jsonObjectFree(jsonObj); + jsonObjectFree(jsonHash); + jsonObjectFree(jsonNumber); + jsonObjectFree(jsonBool); + jsonObjectFree(jsonArray); +} + +//Tests + +START_TEST(test_osrf_json_object_jsonNewObject) + fail_if(jsonObj == NULL, "jsonObject not created"); +END_TEST + +START_TEST(test_osrf_json_object_jsonNewObjectFmt) + jsonObject *fmtObj; + jsonObject *nullObj; + fmtObj = jsonNewObjectFmt("string %d %d", 10, 20); + nullObj = jsonNewObjectFmt(NULL); + + fail_if(fmtObj == NULL, "jsonObject not created"); + fail_unless(strcmp(fmtObj->value.s, "string 10 20") == 0, + "jsonObject->value.s should contain the formatted string passed to jsonNewObjectFmt()"); + fail_unless(fmtObj->type == JSON_STRING, + "jsonNewObjectFmt should set the jsonObject->type to JSON_STRING"); + fail_unless(nullObj->value.s == NULL, + "jsonNewObjectFmt should set jsonObject->value.s to NULL if passed a NULL arg"); + fail_unless(nullObj->type == JSON_NULL, + "jsonNewObjectFmt should set jsonObject->type to JSON_NULL if passed a NULL arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonNewNumberObject) + jsonObject *numObj; + numObj = jsonNewNumberObject(123); + + fail_if(numObj == NULL, "jsonObject not created"); + fail_unless(strcmp(numObj->value.s, "123") == 0, + "jsonNewNumberObject should set jsonObject->value.s to the string value of the num arg"); + fail_unless(numObj->type == JSON_NUMBER, + "jsonNewNumberObject should set jsonObject->type to JSON_NUMBER"); +END_TEST + +START_TEST(test_osrf_json_object_jsonNewNumberStringObject) + jsonObject *nullobj = jsonNewNumberStringObject(NULL); + fail_unless(strcmp(nullobj->value.s, "0") == 0, + "jsonNewNumberStringObject should return a jsonObject with a value of 0 if passed a NULL numstr arg"); + fail_unless(nullobj->type == JSON_NUMBER, + "jsonNewNumberStringObject should return a jsonObject with type JSON_NUMBER"); + jsonObject *notnumobj = jsonNewNumberStringObject("not a number"); + fail_unless(notnumobj == NULL, + "jsonNewNumberStringObject should return NULL if passed an arg that is not a number string"); + jsonObject *numstrobj = jsonNewNumberStringObject("123"); + fail_unless(strcmp(numstrobj->value.s, "123") == 0, + "jsonNewNumberStringObject should return a jsonObject with value.s = the value of the numstr arg"); + fail_unless(numstrobj->type == JSON_NUMBER, + "jsonNewNumberStringObject should return a jsonObject of type JSON_NUMBER"); +END_TEST + +START_TEST(test_osrf_json_object_jsonNewBoolObject) + fail_unless(jsonBool->type == JSON_BOOL, + "jsonNewBoolObject should return a jsonObject of type JSON_BOOL"); + fail_unless(jsonBool->value.b == 0, + "jsonNewBoolObject should return an object with a value of the val arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonSetBool) + jsonSetBool(jsonBool, -1); + fail_unless(jsonBool->value.b == -1, + "jsonSetBool should set jsonObject->value.b to the value of the val arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectSetKey) + fail_unless(jsonObjectSetKey(NULL, "key1", NULL) == -1); + fail_unless(jsonObjectSetKey(jsonHash, "key1", NULL) == 1); + fail_unless(jsonObjectSetKey(jsonHash, "key2", jsonNewObject("test2")) == 2); + fail_unless(jsonObjectGetKey(jsonHash, "key1")->value.s == NULL); + fail_unless(strcmp(jsonObjectGetKey(jsonHash, "key2")->value.s, "test2") == 0); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectRemoveKey) + jsonObjectSetKey(jsonHash, "key1", jsonNewObject("value")); + fail_unless(jsonObjectRemoveKey(jsonHash, NULL) == -1); + fail_unless(jsonObjectRemoveKey(jsonHash, "key1") == 1); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectGetKey) + jsonObjectSetKey(jsonHash, "key1", jsonNewObject("value")); + fail_unless(strcmp(jsonObjectGetKey(jsonHash, "key1")->value.s, "value") == 0); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectSetClass) + jsonObjectSetClass(jsonObj, NULL); + fail_unless(jsonObj->classname == NULL); + jsonObjectSetClass(jsonObj, "aClass"); + fail_unless(strcmp(jsonObj->classname, "aClass") == 0); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectGetClass) + fail_unless(jsonObjectGetClass(NULL) == NULL); + jsonObjectSetClass(jsonObj, "aClass"); + fail_unless(strcmp(jsonObjectGetClass(jsonObj), "aClass") == 0); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectSetIndex) + jsonObject *jsonArrayValue = jsonNewObject("value"); + fail_unless(jsonObjectSetIndex(NULL, 0, jsonArrayValue) == -1, + "jsonObjectSetIndex should return -1 if dest arg is NULL"); + fail_unless(jsonObjectSetIndex(jsonArray, 0, NULL) == 1, + "jsonObjectSetIndex should return the size of the json array after setting the new index"); + fail_unless(jsonObjectSetIndex(jsonArray, 1, jsonArrayValue) == 2, + "jsonObjectSetIndex should return the size of the json array after setting the new index"); + jsonObject *jsonArrayResult = jsonObjectGetIndex(jsonArray, 1); + fail_unless(strcmp(jsonArrayResult->value.s, "value") == 0, + "the value inserted into the jsonArray should be the value of the newObj arg"); + fail_unless(jsonArrayResult->parent == jsonArray, + "the parent of the element inserted should be equal to the newObj arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectGetIndex) + jsonObject *jsonArrayValue = jsonNewObject("value"); + jsonObjectSetIndex(jsonArray, 0, jsonArrayValue); + fail_unless(jsonObjectGetIndex(NULL, 0) == NULL, + "if no obj arg is passed to jsonObjectGetIndex, it should return NULL"); + fail_unless(jsonObjectGetIndex(jsonArray, 2) == NULL, + "if the index in the jsonArray is NULL, jsonObjectGetIndex should return NULL"); + fail_unless(jsonObjectGetIndex(jsonNumber, 0) == NULL, + "if the obj arg isn't of type JSON_ARRAY, return NULL"); + jsonObject *getIndexValue = jsonObjectGetIndex(jsonArray, 0); + fail_unless(strcmp(getIndexValue->value.s, "value") == 0, + "jsonObjectGetIndex should return the jsonObject at the index given"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectToJSONRaw) + fail_unless(jsonObjectToJSONRaw(NULL) == NULL, + "when passed NULL, jsonObjectToJSONRaw should return NULL"); + + jsonObject *val1 = jsonNewObject("value1"); + jsonObject *val2 = jsonNewObject("value2"); + jsonObjectSetClass(val1, "class1"); + jsonObjectSetClass(val2, "class2"); + jsonObjectSetKey(jsonHash, "key1", val1); + jsonObjectSetKey(jsonHash, "key2", val2); + + fail_unless(strcmp(jsonObjectToJSONRaw(jsonHash), + "{\"key1\":\"value1\",\"key2\":\"value2\"}") == 0, + "jsonObjectToJSONRaw should return a string of raw JSON, without expanding\ + class names, built from the obj arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectToJSON) + fail_unless(jsonObjectToJSON(NULL) == NULL, + "jsonObjectToJSON should return NULL if passed a NULL obj arg"); + jsonObject *val1 = jsonNewObject("value1"); + jsonObject *val2 = jsonNewObject("value2"); + jsonObjectSetClass(val1, "class1"); + jsonObjectSetClass(val2, "class2"); + + jsonObjectSetKey(jsonHash, "key1", val1); + jsonObjectSetKey(jsonHash, "key2", val2); + fail_unless(strcmp(jsonObjectToJSON(jsonHash), + "{\"key1\":{\"__c\":\"class1\",\"__p\":\"value1\"},\"key2\":{\"__c\":\"class2\",\"__p\":\"value2\"}}") == 0, + "jsonObjectToJSON should return the obj arg as raw json, expanding class names"); +END_TEST + +START_TEST(test_osrf_json_object_doubleToString) + fail_unless(strcmp(doubleToString(123.456), + "123.456000000000003069544618484") == 0, + "doubleToString should return a string version of the given double, with a precision of 30 digits"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectGetString) + fail_unless(strcmp(jsonObjectGetString(jsonObj), "test") == 0, + "jsonObjectGetString should return the value of the given object, if it is of type JSON_STRING"); + fail_unless(strcmp(jsonObjectGetString(jsonNumber), + "123.456000000000003069544618484") == 0, + "jsonObjectGetString should return the value of the given JSON_NUMBER object if it is not NULL"); + jsonObject *jsonNullNumber = jsonNewNumberObject(0); + jsonObjectSetNumberString(jsonNullNumber, "NaN"); //set jsonNullNumber->value to NULL + fail_unless(strcmp(jsonObjectGetString(jsonNullNumber), "0") == 0, + "jsonObjectGetString should return 0 if value of the given JSON_NUMBER object is NULL"); + fail_unless(jsonObjectGetString(jsonHash) == NULL, + "jsonObjectGetString should return NULL if the given arg is not of type JSON_NUMBER or JSON_STRING"); + fail_unless(jsonObjectGetString(NULL) == NULL, + "jsonObjectGetString should return NULL if the given arg is NULL"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectGetNumber) + fail_unless(jsonObjectGetNumber(NULL) == 0, + "jsonObjectGetNumber should return 0 if given arg is NULL"); + fail_unless(jsonObjectGetNumber(jsonHash) == 0, + "jsonObjectGetNumber should return 0 if given arg is not of type JSON_NUMBER"); + jsonObject *jsonNullNumber = jsonNewNumberObject(0); + jsonObjectSetNumberString(jsonNullNumber, "NaN"); + fail_unless(jsonObjectGetNumber(jsonNullNumber) == 0, + "jsonObjectGetNumber should return 0 if given args value is NULL"); + fail_unless(jsonObjectGetNumber(jsonNumber) == 123.456000000000003069544618484, + "jsonObjectGetNumber should return the value of the given obj in double form"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectSetString) + jsonObjectSetString(jsonObj, NULL); + fail_unless(strcmp(jsonObj->value.s, "test") == 0, + "jsonObjectSetString should not change the value of the dest arg if passed a NULL string arg"); + jsonObjectSetString(jsonObj, "changed"); + fail_unless(strcmp(jsonObj->value.s, "changed") == 0, + "jsonObjectSetString should change the value of the dest arg to the value of the string arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectSetNumberString) + fail_unless(jsonObjectSetNumberString(NULL, "asdf") == -1, + "jsonObjectSetNumberString should return -1 when dest arg is NULL"); + fail_unless(jsonObjectSetNumberString(jsonNumber, NULL) == -1, + "jsonObjectSetNumberString should return -1 when string arg is NULL"); + fail_unless(jsonObjectSetNumberString(jsonNumber, "111.111") == 0, + "jsonObjectSetNumberString should return 0 upon success"); + fail_unless(strcmp(jsonNumber->value.s, "111.111") == 0, + "jsonObjectSetNumberString should set the value of the dest arg to the value of the string arg"); + fail_unless(jsonObjectSetNumberString(jsonNumber, "not a number") == -1, + "jsonObjectSetNumber should return -1 if the string arg is not numeric"); + fail_unless(jsonNumber->value.s == NULL, + "when the string arg is not numeric, dest->value.s should be set to NULL"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectSetNumber) + jsonObjectSetNumber(jsonNumber, 999.999); + fail_unless(strcmp(jsonNumber->value.s, "999.999000000000023646862246096") == 0, + "jsonObjectSetNumber should set dest->value.s to the stringified version of the num arg"); +END_TEST + +START_TEST(test_osrf_json_object_jsonObjectClone) + jsonObject *nullClone = jsonObjectClone(NULL); + fail_unless(nullClone->type == JSON_NULL && nullClone->value.s == NULL, + "when passed a NULL arg, jsonObjectClone should return a jsonObject of type JSON_NULL with a value of NULL "); + + jsonObject *anotherNullClone = jsonObjectClone(nullClone); + fail_unless(anotherNullClone->type == JSON_NULL && anotherNullClone->value.s == NULL, + "jsonObjectClone should return a clone of an object with type JSON_NULL"); + + jsonObject *stringClone = jsonObjectClone(jsonObj); + fail_unless(stringClone->type == JSON_STRING && strcmp(stringClone->value.s, "test") == 0, + "jsonObjectClone should return a clone of an object with type JSON_STRING"); + + jsonObject *numberClone = jsonObjectClone(jsonNumber); + fail_unless(numberClone->type == JSON_NUMBER, + "jsonObjectClone should return a clone of a JSON_NUMBER object"); + fail_unless(strcmp(numberClone->value.s, "123.456000000000003069544618484") == 0, + "jsonObjectClone should return a clone of a JSON_NUMBER object"); + + jsonObject *boolClone = jsonObjectClone(jsonBool); + fail_unless(boolClone->type == JSON_BOOL && boolClone->value.b == 0, + "jsonObjectClone should return a clone of a JSON_BOOL object"); + + //Array + jsonObject *arrayVal1 = jsonNewObject("arrayval1"); + jsonObject *arrayVal2 = jsonNewObject("arrayval2"); + jsonObjectSetIndex(jsonArray, 0, arrayVal1); + jsonObjectSetIndex(jsonArray, 0, arrayVal2); + jsonObject *arrayClone = jsonObjectClone(jsonArray); + fail_unless(strcmp(jsonObjectToJSON(arrayClone), jsonObjectToJSON(jsonArray)) == 0, + "jsonObjectClone should return a clone of a JSON_ARRAY object"); + + //Hash + jsonObject *val1 = jsonNewObject("value1"); + jsonObject *val2 = jsonNewObject("value2"); + jsonObjectSetClass(val1, "class1"); + jsonObjectSetClass(val2, "class2"); + jsonObjectSetKey(jsonHash, "key1", val1); + jsonObjectSetKey(jsonHash, "key2", val2); + jsonObject *hashClone = jsonObjectClone(jsonHash); + fail_unless(strcmp(jsonObjectToJSON(hashClone), jsonObjectToJSON(jsonHash)) == 0, + "jsonObjectClone should return a clone of a JSON_HASH object"); +END_TEST + +START_TEST(test_osrf_json_object_jsonBoolIsTrue) + fail_unless(jsonBoolIsTrue(NULL) == 0, + "jsonBoolIsTrue should return 0 if a NULL arg is passed"); + fail_unless(jsonBoolIsTrue(jsonObj) == 0, + "jsonBoolIsTrue should return 0 if a non JSON_BOOL arg is passed"); + fail_unless(jsonBoolIsTrue(jsonBool) == 0, + "jsonBoolIsTrue should return 0 if the value of boolObj is 0"); + jsonObject *newBool = jsonNewBoolObject(123); + fail_unless(jsonBoolIsTrue(newBool) == 1, + "jsonBoolIsTrue should return 1 if the value of boolObj is not 0"); +END_TEST + +//END Tests + + +Suite *osrf_json_object_suite (void) { + //Create test suite, test case, initialize fixture + Suite *s = suite_create("osrf_json_object"); + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, setup, teardown); + + //Add tests to test case + tcase_add_test(tc_core, test_osrf_json_object_jsonNewObject); + tcase_add_test(tc_core, test_osrf_json_object_jsonNewObjectFmt); + tcase_add_test(tc_core, test_osrf_json_object_jsonNewBoolObject); + tcase_add_test(tc_core, test_osrf_json_object_jsonSetBool); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectToJSONRaw); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectToJSON); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetKey); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetKey); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetClass); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetClass); + tcase_add_test(tc_core, test_osrf_json_object_jsonNewNumberObject); + tcase_add_test(tc_core, test_osrf_json_object_jsonNewNumberStringObject); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectRemoveKey); + tcase_add_test(tc_core, test_osrf_json_object_doubleToString); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetString); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetNumber); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetString); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetNumberString); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetNumber); + tcase_add_test(tc_core, test_osrf_json_object_jsonBoolIsTrue); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectSetIndex); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectGetIndex); + tcase_add_test(tc_core, test_osrf_json_object_jsonObjectClone); + + //Add test case to test suite + suite_add_tcase(s, tc_core); + + return s; +} + +void run_tests (SRunner *sr) { + srunner_add_suite (sr, osrf_json_object_suite()); +} diff --git a/tests/check_osrf_list.c b/tests/check_osrf_list.c new file mode 100644 index 0000000..40d7a5b --- /dev/null +++ b/tests/check_osrf_list.c @@ -0,0 +1,383 @@ +#include +#include "opensrf/osrf_list.h" + +osrfList *testOsrfList; + +//Keep track of how many items have been freed using osrfCustomListFree +unsigned int freedItemsSize; + +//Define a custom freeing function for list items +void osrfCustomListFree() { + freedItemsSize++; +} + +//Set up the test fixture +void setup(void) { + freedItemsSize = 0; + //Set up a list of size 10, define the freeing function, add some items to test with + testOsrfList = osrfNewListSize(10); + testOsrfList->freeItem = (void(*)(void*)) osrfCustomListFree; + + int item1 = 7; + int item3 = 15; + + osrfListPush(testOsrfList, (int *)item1); + osrfListPush(testOsrfList, NULL); + osrfListPush(testOsrfList, (int *)item3); +} + +//Clean up the test fixture +void teardown(void) { + osrfListFree(testOsrfList); +} + +// BEGIN TESTS + +START_TEST(test_osrf_list_osrfNewList) + osrfList *newList = osrfNewList(); + fail_if(newList == NULL, "osrfList object not successfully created"); + fail_unless(newList->arrsize == 48, "the osrfList is not the default size of 48"); +END_TEST + +START_TEST(test_osrf_list_osrfNewListSize) + osrfList *smallList = osrfNewListSize(5); + fail_if(smallList == NULL, "smallList not successfully created"); + fail_unless(smallList->arrsize == 5, "smallList wasn't created with the size 5"); + fail_unless(smallList->freeItem == NULL, "freeItem should be null by default"); + int i; + for (i = 0 ; i < smallList->arrsize ; i++) { + fail_if(smallList->arrlist[i] != NULL, "Every value in smallList->arrlist should be null"); + } + + //List created with size <= 0 + osrfList *sizelessList = osrfNewListSize(0); + fail_unless(sizelessList->arrsize == 16, + "osrfNewListSize called with a size of 0 or less should have an array size of 16"); +END_TEST + +START_TEST(test_osrf_list_osrfListPush) + fail_unless(osrfListPush(NULL, NULL) == -1, + "Passing a null list to osrfListPush should return -1"); + int listItem = 111; + fail_unless(osrfListPush(testOsrfList, (int *) listItem) == 0, + "osrfListPush should return 0 if successful"); + fail_unless(testOsrfList->size == 4, + "testOsrfList->size did not update correctly, should be 4"); + fail_unless(osrfListGetIndex(testOsrfList, 3) == (int *) listItem, + "listItem did not add to the end of testOsrfList"); +END_TEST + +START_TEST(test_osrf_list_osrfListPushFirst) + fail_unless(osrfListPushFirst(NULL, NULL) == -1, + "Passing a null list to osrfListPushFirst should return -1"); + int listItem = 123; + fail_unless(osrfListPushFirst(testOsrfList, (int *) listItem) == 3, + "osrfListPushFirst should return a size of 3"); + fail_unless(osrfListGetIndex(testOsrfList, 1) == (int *) listItem, + "listItem should be in index 1 because it is the first that is null"); +END_TEST + +START_TEST(test_osrf_list_osrfListSet) + //Null argument check + fail_unless(osrfListSet(NULL, NULL, 1) == NULL, + "Given a null list arg, osrfListSet should return null"); + + //Adding an item to an existing, NULL position in the list + int listItem = 456; + fail_unless(osrfListSet(testOsrfList, (int *) listItem, 4) == NULL, + "Calling osrfListSet on an empty index should return NULL"); + fail_unless(osrfListGetIndex(testOsrfList, 4) == (int *) listItem, + "osrfListSet is not assigning item pointer to the correct position"); + fail_unless(testOsrfList->size == 5, + "osrfListSet should update a lists size after adding an item to that list"); + + //Adding an item to an exisiting, occupied position in the + //list when there is a freeing function defined on the list + int listItem2 = 789; + fail_unless(osrfListSet(testOsrfList, (int *) listItem2, 4) == NULL, + "Calling osrfListSet on an index that held a value, \ + on a list that has a custom freeing function, should return NULL"); + fail_unless(osrfListGetIndex(testOsrfList, 4) == (int *) listItem2, + "When called on a position that already has a value, \ + osrfListSet should replace that value with the new item"); + fail_unless(testOsrfList->size == 5, + "osrfListSet shouldn't update a lists size if the item is \ + not added beyond the current size"); + + //Adding an item to an exisiting, occupied position in the list + //when there is NOT a freeing function defined on the list + testOsrfList->freeItem = NULL; + int listItem3 = 111; + fail_unless(osrfListSet(testOsrfList, (int *) listItem3, 4) == (int *) listItem2, + "Calling osrfListSet on an index that held a value should \ + return the reference to that value"); + fail_unless(osrfListGetIndex(testOsrfList, 4) == (int *) listItem3, + "When called on a position that already has a value, \ + osrfListSet should replace that value with the new item"); + fail_unless(testOsrfList->size == 5, + "osrfListSet shouldn't update a lists size if the item is \ + not added beyond the current size"); + + //Adding an item to a position outside of the current array size + int listItem4 = 444; + fail_unless(osrfListSet(testOsrfList, (int *) listItem4, 18) == NULL, + "Calling osrfListSet on an empty index should return NULL, \ + even if the index does not exist yet"); + fail_unless(testOsrfList->arrsize == 266, + "New arrsize should be 266 since it was 10 before, and grows \ + in increments of 256 when expanded"); + fail_unless(testOsrfList->size == 19, + "List should have a size value of 19"); + fail_unless(osrfListGetIndex(testOsrfList, 18) == (int *) listItem4, + "Value not added to correct index of list"); +END_TEST + +START_TEST(test_osrf_list_osrfListGetIndex) + fail_unless(osrfListGetIndex(NULL, 1) == NULL, + "Calling osrfListGetIndex with a null list should return null"); + fail_unless(osrfListGetIndex(testOsrfList, 8) == NULL, + "Calling osrfListGetIndex with a value outside the range of \ + occupied indexes should return NULL"); + fail_unless(osrfListGetIndex(testOsrfList, 2) == (int *) 15, + "osrfListGetIndex should return the value of the list at the given index"); +END_TEST + +START_TEST(test_osrf_list_osrfListFree) + //Set up a new list to be freed + osrfList *myList = osrfNewList(); + myList->freeItem = (void(*)(void*)) osrfCustomListFree; + int myListItem1 = 123; + int myListItem2 = 456; + osrfListSet(myList, (int *) myListItem1, 0); + osrfListSet(myList, (int *) myListItem2, 1); + osrfListFree(myList); + fail_unless(freedItemsSize == 2, + "osrfListFree should free each item in the list if there is a custom \ + freeing function defined"); +END_TEST + +START_TEST(test_osrf_list_osrfListClear) + //Set up a new list with items to be freed + osrfList *myList = osrfNewList(); + myList->freeItem = (void(*)(void*)) osrfCustomListFree; + int myListItem1 = 123; + int myListItem2 = 456; + osrfListSet(myList, (int *) myListItem1, 0); + osrfListSet(myList, (int *) myListItem2, 1); + osrfListClear(myList); + + fail_unless(freedItemsSize == 2, + "osrfListClear should free each item in the list if there is a custom \ + freeing function defined"); + fail_unless(myList->arrlist[0] == NULL && myList->arrlist[1] == NULL, + "osrfListClear should make all previously used slots in the list NULL"); + fail_unless(myList->size == 0, + "osrfListClear should set the list's size to 0"); +END_TEST + +START_TEST(test_osrf_list_osrfListSwap) + //Prepare a second list to swap + osrfList *secondOsrfList = osrfNewListSize(7); + int item2 = 8; + int item3 = 16; + osrfListPush(secondOsrfList, NULL); + osrfListPush(secondOsrfList, (int *) item2); + osrfListPush(secondOsrfList, (int *) item3); + + osrfListSwap(testOsrfList, secondOsrfList); + fail_unless( + osrfListGetIndex(testOsrfList, 0) == NULL && + osrfListGetIndex(testOsrfList, 1) == (int *) 8 && + osrfListGetIndex(testOsrfList, 2) == (int *) 16, + "After osrfListSwap, first list should now contain \ + the contents of the second list" + ); + fail_unless( + osrfListGetIndex(secondOsrfList, 0) == (int *) 7 && + osrfListGetIndex(secondOsrfList, 1) == NULL && + osrfListGetIndex(secondOsrfList, 2) == (int *) 15, + "After osrfListSwap, second list should now contain \ + the contents of the first list" + ); +END_TEST + +START_TEST(test_osrf_list_osrfListRemove) + fail_unless(osrfListRemove(NULL, 2) == NULL, + "osrfListRemove should return NULL when not given a list"); + fail_unless(osrfListRemove(testOsrfList, 1000) == NULL, + "osrfListRemove should return NULL when given a position \ + exceeding the size of the list"); + fail_unless(osrfListRemove(testOsrfList, 2) == NULL, + "osrfListRemove should return NULL if there is a custom freeing \ + function defined on the list"); + fail_unless(osrfListGetIndex(testOsrfList, 2) == NULL, + "osrfListRemove should remove the value from the list"); + fail_unless(testOsrfList->size == 2, + "osrfListRemove should adjust the size of the list if the last \ + element is removed"); + fail_unless(freedItemsSize == 1, + "osrfListRemove should call a custom item freeing function if \ + defined"); + testOsrfList->freeItem = NULL; + fail_unless(osrfListRemove(testOsrfList, 0) == (int *) 7, + "osrfListRemove should return the value that it has removed from \ + the list if no custom freeing function is defined on the list"); + fail_unless(osrfListGetIndex(testOsrfList, 0) == NULL, + "osrfListRemove should remove the value from the list and make \ + the position NULL"); + fail_unless(testOsrfList->size == 2, "osrfListRemove should not touch \ + the size of the list if it isn't removing the last element in the \ + list"); +END_TEST + +START_TEST(test_osrf_list_osrfListExtract) + fail_unless(osrfListExtract(NULL, 2) == NULL, + "osrfListExtract should return NULL when not given a list"); + fail_unless(osrfListExtract(testOsrfList, 1000) == NULL, + "osrfListExtract should return NULL when given a position \ + exceeding the size of the list"); + fail_unless(osrfListExtract(testOsrfList, 2) == (int *) 15, + "osrfListExtract should return the value that it has removed \ + from the list"); + fail_unless(osrfListGetIndex(testOsrfList, 2) == NULL, + "osrfListExtract should remove the value from the list and \ + make the position NULL"); + fail_unless(testOsrfList->size == 2, + "osrfListExtract should adjust the size of the list if the \ + last element is removed"); + fail_unless(osrfListExtract(testOsrfList, 0) == (int *) 7, + "osrfListExtract should return the value that it has removed \ + from the list"); + fail_unless(osrfListGetIndex(testOsrfList, 0) == NULL, + "osrfListExtract should remove the value from the list and \ + make the position NULL"); + fail_unless(testOsrfList->size == 2, + "osrfListExtract should not touch the size of the list if it \ + isn't removing the last element in the list"); +END_TEST + +START_TEST(test_osrf_list_osrfListFind) + fail_unless(osrfListFind(NULL, (int *) 2) == -1, + "osrfListFind should return -1 when not given a list"); + fail_unless(osrfListFind(testOsrfList, NULL) == -1, + "osrfListFind should return -1 when not given an addr"); + fail_unless(osrfListFind(testOsrfList, (int *) 15) == 2, + "osrfListFind should return the index where the first instance \ + of addr is located"); + fail_unless(osrfListFind(testOsrfList, (int *) 199) == -1, + "osrfListFind should return -1 when the addr does not exist in \ + the list"); +END_TEST + +START_TEST(test_osrf_list_osrfListGetCount) + fail_unless(osrfListGetCount(NULL) == -1, + "osrfListGetCount should return -1 when no list is given"); + fail_unless(osrfListGetCount(testOsrfList) == 3, + "osrfListGetCount should return list->size when given a list"); +END_TEST + +START_TEST(test_osrf_list_osrfListPop) + fail_unless(osrfListPop(NULL) == NULL, + "osrfListPop should return NULL when no list is given"); + fail_unless(osrfListPop(testOsrfList) == NULL, + "osrfListPop should return NULL if there is a custom freeing \ + function defined on the list"); + fail_unless(testOsrfList->arrlist[2] == NULL, + "osrfListPop should remove the last item from the list"); + testOsrfList->freeItem = NULL; + int item = 10; + osrfListPush(testOsrfList, (int *) item); + fail_unless(osrfListPop(testOsrfList) == (int *) 10, + "osrfListPop should return the last item from the list"); + fail_unless(testOsrfList->arrlist[2] == NULL, + "osrfListPop should remove the last item from the list"); +END_TEST + +START_TEST(test_osrf_list_osrfNewListIterator) + fail_unless(osrfNewListIterator(NULL) == NULL, + "osrfNewListIterator should return NULL when no list is given"); + osrfListIterator *testListItr = osrfNewListIterator(testOsrfList); + fail_if(testListItr == NULL, + "osrfNewListIterator should create a osrfListIterator object"); + fail_unless(testListItr->list == testOsrfList, + "osrfNewListIterator should set the osrfListIterator->list \ + attribute to the given list"); + fail_unless(testListItr->current == 0, + "osrfNewListIterator should set its current position to 0 by \ + default"); +END_TEST + +START_TEST(test_osrf_list_osrfListIteratorNext) + fail_unless(osrfListIteratorNext(NULL) == NULL, + "osrfListIteratorNext should return NULL when no list given"); + osrfListIterator *testListItr = osrfNewListIterator(testOsrfList); + fail_unless(osrfListIteratorNext(testListItr) == (int *) 7, + "osrfListIteratorNext should return the value stored at the current \ + index in the list, then increment"); + fail_unless(osrfListIteratorNext(testListItr) == NULL, + "osrfListIteratorNext should return the value stored at the current \ + index in the list, then increment"); + fail_unless(osrfListIteratorNext(testListItr) == (int *) 15, + "osrfListIteratorNext should return the value stored at the current \ + index in the list, then increment"); + fail_unless(osrfListIteratorNext(testListItr) == NULL, + "osrfListIteratorNext should return NULL when it reaches the end of \ + the list"); + testListItr->list = NULL; + fail_unless(osrfListIteratorNext(testListItr) == NULL, + "osrfListIteratorNext should return NULL if osrfListIterator->list \ + is NULL"); +END_TEST + +START_TEST(test_osrf_list_osrfListIteratorFree) +END_TEST + +START_TEST(test_osrf_list_osrfListIteratorReset) + osrfListIterator *testListItr = osrfNewListIterator(testOsrfList); + osrfListIteratorNext(testListItr); + osrfListIteratorReset(testListItr); + fail_unless(testListItr->current == 0, + "osrfListIteratorReset should reset the iterator's current position to 0"); +END_TEST + +START_TEST(test_osrf_list_osrfListSetDefaultFree) +END_TEST + +//END TESTS + +Suite *osrf_list_suite(void) { + //Create test suite, test case, initialize fixture + Suite *s = suite_create("osrf_list"); + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, setup, teardown); + + //Add tests to test case + tcase_add_test(tc_core, test_osrf_list_osrfNewList); + tcase_add_test(tc_core, test_osrf_list_osrfNewListSize); + tcase_add_test(tc_core, test_osrf_list_osrfListPush); + tcase_add_test(tc_core, test_osrf_list_osrfListPushFirst); + tcase_add_test(tc_core, test_osrf_list_osrfListSet); + tcase_add_test(tc_core, test_osrf_list_osrfListGetIndex); + tcase_add_test(tc_core, test_osrf_list_osrfListFree); + tcase_add_test(tc_core, test_osrf_list_osrfListClear); + tcase_add_test(tc_core, test_osrf_list_osrfListSwap); + tcase_add_test(tc_core, test_osrf_list_osrfListRemove); + tcase_add_test(tc_core, test_osrf_list_osrfListExtract); + tcase_add_test(tc_core, test_osrf_list_osrfListFind); + tcase_add_test(tc_core, test_osrf_list_osrfListGetCount); + tcase_add_test(tc_core, test_osrf_list_osrfListPop); + tcase_add_test(tc_core, test_osrf_list_osrfNewListIterator); + tcase_add_test(tc_core, test_osrf_list_osrfListIteratorNext); + tcase_add_test(tc_core, test_osrf_list_osrfListIteratorFree); + tcase_add_test(tc_core, test_osrf_list_osrfListIteratorReset); + tcase_add_test(tc_core, test_osrf_list_osrfListSetDefaultFree); + + //Add test case to test suite + suite_add_tcase(s, tc_core); + + return s; +} + +void run_tests(SRunner *sr) { + srunner_add_suite(sr, osrf_list_suite()); +} diff --git a/tests/check_osrf_message.c b/tests/check_osrf_message.c new file mode 100644 index 0000000..1a8f9a7 --- /dev/null +++ b/tests/check_osrf_message.c @@ -0,0 +1,98 @@ +#include +#include "opensrf/osrf_json.h" +#include "opensrf/osrf_message.h" + +osrfMessage *o; + +//Set up the test fixture +void setup(void) { + o = osrf_message_init(CONNECT, 1, 1); +} + +//Clean up the test fixture +void teardown(void) { + osrfMessageFree(o); +} + +//Tests + +START_TEST(test_osrf_message_init) + fail_if (o == NULL, "osrfMessage not created"); +END_TEST + +START_TEST(test_osrf_message_get_last_locale) + fail_unless(osrf_message_get_last_locale() == NULL, + "osrf_message_get_last_locale should return the value of current_locale"); +END_TEST + +START_TEST(test_osrf_message_set_locale) + const char* new_locale = "en-CA"; + fail_unless(osrf_message_set_locale(o, NULL) == NULL, + "osrf_message_set_locale should return NULL if locale is NULL"); + fail_unless(osrf_message_set_locale(NULL, new_locale) == NULL, + "osrf_message_set_locale should return NULL if msg is NULL"); + char* l = osrf_message_set_locale(o, new_locale); + fail_unless(strcmp(l, "en-CA") == 0, + "osrf_message_set_locale should return the new locale"); + fail_unless(strcmp(o->sender_locale, "en-CA") == 0, + "osrf_message_set_locale should set osrfMessage->sender_locale to the new locale"); +END_TEST + +START_TEST(test_osrf_message_set_default_locale) + fail_unless(osrf_message_set_default_locale(NULL) == NULL, + "osrf_message_set_default_locale should return NULL if given a NULL arg"); + fail_unless(osrf_message_set_default_locale("This string is \ + longer than 16 characters for sure") == NULL, + "osrf_message_set_default_locale should return NULL if locale arg is longer than 16 chars"); + fail_unless(strcmp(osrf_message_set_default_locale("fr-CA"), + "fr-CA") == 0, + "osrf_message_set_default_locale should return the new default locale if successful"); +END_TEST + +START_TEST(test_osrf_message_set_method) + osrf_message_set_method(o, NULL); + fail_unless(o->method_name == NULL, + "osrf_message_set_method should return NULL if given a NULL method_name arg"); + osrf_message_set_method(o, "add"); + fail_unless(strcmp(o->method_name, "add") == 0, + "osrf_message_set_method should set osrfMessage->method_name if successful"); +END_TEST + +START_TEST(test_osrf_message_set_params) + osrf_message_set_params(o, NULL); + fail_unless(o->_params == NULL, + "osrf_message_set_params should set msg->_params to NULL when passed a NULL o arg"); + jsonObject *testJSONObject; + testJSONObject = jsonNewObject("test"); + osrf_message_set_params(o, testJSONObject); + fail_unless(strcmp(jsonObjectGetIndex(o->_params, 0)->value.s, "test") == 0, + "osrf_message_set_params should set msg->_params to an array containing the\ + jsonObject passed"); + jsonObjectFree(testJSONObject); +END_TEST + +//END Tests + +Suite *osrf_message_suite(void) { + //Create test suite, test case, initialize fixture + Suite *s = suite_create("osrf_message"); + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture (tc_core, setup, teardown); + + //Add tests to test case + tcase_add_test(tc_core, test_osrf_message_init); + tcase_add_test(tc_core, test_osrf_message_get_last_locale); + tcase_add_test(tc_core, test_osrf_message_set_locale); + tcase_add_test(tc_core, test_osrf_message_set_default_locale); + tcase_add_test(tc_core, test_osrf_message_set_method); + tcase_add_test(tc_core, test_osrf_message_set_params); + + //Add test case to test suite + suite_add_tcase(s, tc_core); + + return s; +} + +void run_tests(SRunner *sr) { + srunner_add_suite(sr, osrf_message_suite()); +} diff --git a/tests/check_osrf_stack.c b/tests/check_osrf_stack.c new file mode 100644 index 0000000..3657488 --- /dev/null +++ b/tests/check_osrf_stack.c @@ -0,0 +1,41 @@ +#include +#include "opensrf/osrf_stack.h" + + + +//Set up the test fixture +void setup(void){ +} + +//Clean up the test fixture +void teardown(void){ +} + +// BEGIN TESTS + +START_TEST(test_osrf_stack_process) + int *mr = 0; + fail_unless(osrf_stack_process(NULL, 10, mr) == -1, + "osrf_stack_process should return -1 if client arg is NULL"); +END_TEST + +//END TESTS + +Suite *osrf_stack_suite(void) { + //Create test suite, test case, initialize fixture + Suite *s = suite_create("osrf_stack"); + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, setup, teardown); + + //Add tests to test case + tcase_add_test(tc_core, test_osrf_stack_process); + + //Add test case to test suite + suite_add_tcase(s, tc_core); + + return s; +} + +void run_tests(SRunner *sr) { + srunner_add_suite(sr, osrf_stack_suite()); +} diff --git a/tests/check_transport_client.c b/tests/check_transport_client.c new file mode 100644 index 0000000..741263f --- /dev/null +++ b/tests/check_transport_client.c @@ -0,0 +1,248 @@ +#include +#include "opensrf/transport_client.h" + +transport_client *a_client; +transport_message *a_message; + +//Set up the test fixture +void setup(void) { + a_client = client_init("server", 1234, "unixpath", 123); + a_message = message_init("body", "subject", "thread", "recipient", "sender"); +} + +//Clean up the test fixture +void teardown(void) { + free(a_client); + free(a_message); +} + +// Stub functions to simulate behavior of transport_session functions used in +// transport_client.c (to isolate system under test) + +/* + * init_transport() returns a new transport_session object - just return an + * empty one for the purpose of testing transport_client +*/ +transport_session* init_transport(const char* server, int port, + const char* unix_path, void* user_data, int component) { + + transport_session* session = (transport_session*) safe_malloc(sizeof(transport_session)); + return session; +} + +/* + * va_list_to_string takes a format and any number of arguments, and returns + * a formatted string of those args. Its only used once here, return what is + * expected. +*/ +char* va_list_to_string(const char* format, ...) { + return "user@server/resource"; +} + +/* The rest of these functions return 1 or 0 depending on the result. + * The transport_client functions that call these are just wrappers for + * functions in transport_session.c +*/ + +int session_connect(transport_session* session, + const char* username, const char* password, + const char* resource, int connect_timeout, enum TRANSPORT_AUTH_TYPE auth_type ) { + + return 1; +} + +int session_disconnect(transport_session* session) { + return 1; +} + +int session_connected(transport_session* session) { + return 1; +} + +int session_send_msg(transport_session* session, transport_message* message) { + return 0; +} + +int session_wait(transport_session* session, int timeout) { + if (session == a_client->session && timeout == -1) { + transport_message* recvd_msg = message_init("body1", "subject1", "thread1", "recipient1", "sender1"); + a_client->msg_q_head = recvd_msg; + return 0; + } + else if (session == a_client->session && timeout > 0) { + return 0; + } + else + return 1; +} + +//End Stubs + +// BEGIN TESTS + +START_TEST(test_transport_client_init) + fail_unless(client_init(NULL, 1234, "some_path", 123) == NULL, + "When given a NULL client arg, client_init should return NULL"); + transport_client *test_client = client_init("server", 1234, "unixpath", 123); + fail_unless(test_client->msg_q_head == NULL, + "client->msg_q_head should be NULL on new client creation"); + fail_unless(test_client->msg_q_tail == NULL, + "client->msg_q_tail should be NULL on new client creation"); + fail_if(test_client->session == NULL, + "client->session should not be NULL - it is initialized by a call to init_transport"); + //fail_unless(test_client->session->message_callback == client_message_handler, + // "The default message_callback function should be client_message_handler"); + fail_unless(test_client->error == 0, "client->error should be false on new client creation"); + fail_unless(strcmp(test_client->host, "server") == 0, "client->host should be set to the host arg"); + fail_unless(test_client->xmpp_id == NULL, "xmpp_id should be NULL on new client creation"); +END_TEST + +START_TEST(test_transport_client_connect) + fail_unless(client_connect(NULL, "user", "password", "resource", 10, AUTH_PLAIN) == 0, + "Passing a NULL client to client_connect should return a failure"); + fail_unless(client_connect(a_client, "user", "password", "resource", 10, AUTH_PLAIN) == 1, + "A successful call to client_connect should return a 1, provided session_connect is successful"); + fail_unless(strcmp(a_client->xmpp_id, "user@server/resource") == 0, + "A successful call to client_connect should set the correct xmpp_id in the client"); +END_TEST + +START_TEST(test_transport_client_disconnect) + fail_unless(client_disconnect(NULL) == 0, + "client_disconnect should return 0 if no client arg is passed"); + fail_unless(client_disconnect(a_client) == 1, + "client_disconnect should return 1 if successful"); +END_TEST + +START_TEST(test_transport_client_connected) + fail_unless(client_connected(NULL) == 0, + "client_connected should return 0 if no client arg is passed"); + fail_unless(client_connected(a_client) == 1, + "client_connected should return 1 if successful"); +END_TEST + +START_TEST(test_transport_client_send_message) + fail_unless(client_send_message(NULL, a_message) == -1, + "client_send_message should return -1 if client arg is NULL"); + a_client->error = 1; + //fail_unless(client_send_message(a_client->session, a_message") == -1, + //"client_send_message should return -1 if client->error is true"); + a_client->error = 0; + //fail_unless(client_send_message(a_client->session, a_message) == 0, + //"client_send_message should return 0 on success"); + //fail_unless(strcmp(a_message->sender, "user") == 0, + //"client_send_message shoud set msg->sender to the value of client->xmpp_id"); +END_TEST + +START_TEST(test_transport_client_recv) + //NULL client case + fail_unless(client_recv(NULL, 10) == NULL, + "client_recv should return NULL if the client arg is NULL"); + + //Message at head of queue + a_client->msg_q_head = a_message; //put a message at the head of the queue + transport_message *msg = client_recv(a_client, 10); + fail_if(msg == NULL, + "client_recv should return a transport_message on success"); + fail_unless(a_client->msg_q_head == NULL, + "client_recv should remove the message from client->msg_q_head if it is successful"); + fail_unless(msg->next == NULL, + "client_recv should set msg->next to NULL"); + fail_unless(a_client->msg_q_tail == NULL, + "client_recv should set client->msg_q_tail to NULL if there was only one message in the queue"); + + //session_wait failure with no timeout + transport_client* other_client = client_init("server2", 4321, "unixpath2", 321); + transport_message *msg2 = client_recv(other_client, -1); + fail_unless(msg2 == NULL, + "client_recv should return NULL if the call to session_wait() returns an error"); + fail_unless(other_client->error == 1, + "client_recv should set client->error to true if an error has occured"); + + //message in queue with no timeout + transport_message *msg3 = client_recv(a_client, -1); + fail_unless(msg3->next == NULL, + "client_recv should set msg->next to NULL"); + fail_unless(a_client->msg_q_head == NULL, + "client_recv should set client->msg_q_head to NULL if there are no more queued messages"); + fail_unless(a_client->msg_q_tail == NULL, + "client_recv should set client->msg_q_tail to NULL if client->msg_q_head was NULL"); + fail_unless(strcmp(msg3->body, "body1") == 0, + "the message returned by client_recv should contain the contents of the message that was received"); + fail_unless(strcmp(msg3->subject, "subject1") == 0, + "the message returned by client_recv should contain the contents of the message that was received"); + fail_unless(strcmp(msg3->thread, "thread1") == 0, + "the message returned by client_recv should contain the contents of the message that was received"); + fail_unless(strcmp(msg3->recipient, "recipient1") == 0, + "the message returned by client_recv should contain the contents of the message that was received"); + fail_unless(strcmp(msg3->sender, "sender1") == 0, + "the message returned by client_recv should contain the contents of the message that was received"); + + //No message in queue with timeout + a_client->error = 0; + transport_message *msg4 = client_recv(a_client, 1); //only 1 sec timeout so we dont slow down testing + fail_unless(msg4 == NULL, + "client_recv should return NULL if there is no message in queue to receive"); + fail_unless(a_client->error == 0, + "client->error should be 0 since there was no error"); + + //session_wait failure with timeout + other_client->error = 0; + transport_message *msg5 = client_recv(other_client, 1); //only 1 sec again... + fail_unless(msg5 == NULL, + "client_recv should return NULL if there is an error"); + fail_unless(other_client->error == 1, + "client_recv should set client->error to 1 if there is an error"); +END_TEST + +START_TEST(test_transport_client_free) + fail_unless(client_free(NULL) == 0, + "client_free should retun 0 if passed a NULL arg"); + transport_client* client1 = client_init("server", 1234, "unixpath", 123); + fail_unless(client_free(client1) == 1, + "client_free should return 0 if successful"); +END_TEST + +START_TEST(test_transport_client_discard) + fail_unless(client_discard(NULL) == 0, + "client_discard should return 0 if passed a NULL arg"); + transport_client* client1 = client_init("server", 1234, "unixpath", 123); + fail_unless(client_discard(client1) == 1, + "client_discard should return 1 if successful"); +END_TEST + +START_TEST(test_transport_client_sock_fd) + fail_unless(client_sock_fd(NULL) == 0, + "client_sock_fd should return 0 if passed a NULL arg"); + a_client->session->sock_id = 1; + fail_unless(client_sock_fd(a_client) == 1, + "client_sock_fd should return client->session->sock_id"); +END_TEST + +//END TESTS + +Suite *transport_client_suite(void) { + //Create test suite, test case, initialize fixture + Suite *s = suite_create("transport_client"); + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, setup, teardown); + + //Add tests to test case + tcase_add_test(tc_core, test_transport_client_init); + tcase_add_test(tc_core, test_transport_client_connect); + tcase_add_test(tc_core, test_transport_client_disconnect); + tcase_add_test(tc_core, test_transport_client_connected); + tcase_add_test(tc_core, test_transport_client_send_message); + tcase_add_test(tc_core, test_transport_client_recv); + tcase_add_test(tc_core, test_transport_client_free); + tcase_add_test(tc_core, test_transport_client_discard); + tcase_add_test(tc_core, test_transport_client_sock_fd); + + //Add test case to test suite + suite_add_tcase(s, tc_core); + + return s; +} + +void run_tests(SRunner *sr) { + srunner_add_suite(sr, transport_client_suite()); +} diff --git a/tests/check_transport_message.c b/tests/check_transport_message.c new file mode 100644 index 0000000..293ba5d --- /dev/null +++ b/tests/check_transport_message.c @@ -0,0 +1,279 @@ +#include +#include "opensrf/transport_message.h" + +transport_message *a_message; + +//Set up the test fixture +void setup(void) { + a_message = message_init("body", "subject", "thread", "recipient", "sender"); +} + +//Clean up the test fixture +void teardown(void) { + message_free(a_message); +} + +//BEGIN TESTS + +START_TEST(test_transport_message_init_empty) + transport_message* empty_message = message_init(NULL, NULL, NULL, NULL, NULL); + fail_if(empty_message == NULL, "transport_message wasn't created"); + fail_unless(strcmp(empty_message->body, "") == 0, + "When calling message_init, an NULL body arg should yield an empty string"); + fail_unless(strcmp(empty_message->thread, "") == 0, + "When calling message_init, an NULL thread arg should yield an empty string"); + fail_unless(strcmp(empty_message->subject, "") == 0, + "When calling message_init, an NULL subject arg should yield an empty string"); + fail_unless(strcmp(empty_message->recipient, "") == 0, + "When calling message_init, an NULL recipient arg should yield an empty string"); + fail_unless(strcmp(empty_message->sender, "") == 0, + "When calling message_init, an NULL sender arg should yield an empty string"); + fail_unless(empty_message->router_from == NULL, + "message_init should set the router_from field to NULL"); + fail_unless(empty_message->router_to == NULL, + "message_init should set the router_to field to NULL"); + fail_unless(empty_message->router_class == NULL, + "message_init should set the router_class field to NULL"); + fail_unless(empty_message->router_command == NULL, + "message_init should set the router_command field to NULL"); + fail_unless(empty_message->osrf_xid == NULL, + "message_init should set the osrf_xid field to NULL"); + fail_unless(empty_message->is_error == 0, + "message_init should set the is_error field to 0"); + fail_unless(empty_message->error_type == NULL, + "message_init should set the error_type field to NULL"); + fail_unless(empty_message->error_code == 0, + "message_init should set the error_code field to 0"); + fail_unless(empty_message->broadcast == 0, + "message_init should set the broadcast field to 0"); + fail_unless(empty_message->msg_xml == NULL, + "message_init should set the msg_xml field to NULL"); + fail_unless(empty_message->next == NULL, + "message_init should set the next field to NULL"); +END_TEST + +START_TEST(test_transport_message_init_populated) + fail_if(a_message == NULL, "transport_message wasn't created"); + fail_unless(strcmp(a_message->body, "body") == 0, + "When calling message_init, an body arg should be stored in the body field"); + fail_unless(strcmp(a_message->thread, "thread") == 0, + "When calling message_init, an thread arg should be stored in the thread field"); + fail_unless(strcmp(a_message->subject, "subject") == 0, + "When calling message_init, a subject arg should be stored in the subject field"); + fail_unless(strcmp(a_message->recipient, "recipient") == 0, + "When calling message_init, a recipient arg should be stored in the recipient field"); + fail_unless(strcmp(a_message->sender, "sender") == 0, + "When calling message_init, a sender arg should be stored in the sender field"); +END_TEST + +START_TEST(test_transport_message_new_message_from_xml_empty) + fail_unless(new_message_from_xml(NULL) == NULL, + "Passing NULL to new_message_from_xml should return NULL"); + fail_unless(new_message_from_xml("\0") == NULL, + "Passing a NULL string to new_message_from_xml should return NULL"); + + const char* empty_msg = ""; + transport_message* t_msg = new_message_from_xml(empty_msg); + fail_if(t_msg == NULL, + "new_message_from_xml should create a new transport_message"); + fail_unless(strcmp(t_msg->thread, "") == 0, + "When passed no thread, msg->thread should be set to an empty string"); + fail_unless(strcmp(t_msg->subject, "") == 0, + "When passed no subject, msg->subject should be set to an empty string"); + fail_unless(strcmp(t_msg->body, "") == 0, + "When passed no body, msg->body should be set to an empty string"); + fail_unless(t_msg->recipient == NULL, + "When passed no recipient, msg->recipient should be NULL"); + fail_unless(t_msg->sender == NULL, + "When passed no sender, msg->sender should be NULL"); + fail_unless(t_msg->router_from == NULL, + "When passed no router_from, msg->router_from should be NULL"); + fail_unless(t_msg->router_to == NULL, + "When passed no router_to, msg->router_to should be NULL"); + fail_unless(t_msg->router_class == NULL, + "When passed no router_class, msg->router_class should be NULL"); + fail_unless(t_msg->router_command == NULL, + "router_command should never be passed, and therefore should be NULL"); + fail_unless(t_msg->osrf_xid == NULL, + "When passed no osrf_xid, msg->osrf_xid should be NULL"); + fail_unless(t_msg->is_error == 0, + "is_error should never be passed, and msg->is_error should be set to 0"); + fail_unless(t_msg->error_type == NULL, + "error_type should never be passed, and should be NULL"); + fail_unless(t_msg->error_code == 0, + "error_code should never be passed, and msg->error_code should be set to 0"); + fail_unless(t_msg->broadcast == 0, + "When passed no broadcast, msg->broadcast should be set to 0"); + fail_unless(strcmp(t_msg->msg_xml, "") == 0, + "msg->msg_xml should contain the contents of the original xml message"); + fail_unless(t_msg->next == NULL, "msg->next should be set to NULL"); +END_TEST + +START_TEST(test_transport_message_new_message_from_xml_populated) + const char* xml_jabber_msg = + "thread_valuesubject_valuebody_value"; + + transport_message *my_msg = new_message_from_xml(xml_jabber_msg); + fail_if(my_msg == NULL, "new_message_from_xml failed to create a transport_message"); + fail_unless(strcmp(my_msg->sender, "routerfrom") == 0, + "new_message_from_xml should populate the sender field"); + fail_unless(strcmp(my_msg->recipient, "receiver") == 0, + "new_message_from_xml should populate the receiver field"); + fail_unless(strcmp(my_msg->osrf_xid, "xid") == 0, + "new_message_from_xml should populate the osrf_xid field"); + fail_unless(strcmp(my_msg->router_from, "routerfrom") == 0, + "new_message_from_xml should populate the router_from field"); + fail_unless(strcmp(my_msg->subject, "subject_value") == 0, + "new_message_from_xml should populate the subject field"); + fail_unless(strcmp(my_msg->thread, "thread_value") == 0, + "new_message_from_xml should populate the thread field"); + fail_unless(strcmp(my_msg->router_to, "routerto") == 0, + "new_message_from_xml should populate the router_to field"); + fail_unless(strcmp(my_msg->router_class, "class") == 0, + "new_message_from_xml should populate the router_class field"); + fail_unless(my_msg->broadcast == 1, + "new_message_from_xml should populate the broadcast field"); + fail_unless(strcmp(my_msg->msg_xml, xml_jabber_msg) == 0, + "new_message_from_xml should store the original xml msg in msg_xml"); +END_TEST + +START_TEST(test_transport_message_set_osrf_xid) + message_set_osrf_xid(a_message, "abcd"); + fail_unless(strcmp(a_message->osrf_xid, "abcd") == 0, + "message_set_osrf_xid should set msg->osrf_xid to the value of the osrf_xid arg"); + message_set_osrf_xid(a_message, NULL); + fail_unless(strcmp(a_message->osrf_xid, "") == 0, + "message_set_osrf_xid should set msg->osrf_xid to an empty string if osrf_xid arg is NULL"); +END_TEST + +START_TEST(test_transport_message_set_router_info_empty) + message_set_router_info(a_message, NULL, NULL, NULL, NULL, 0); + fail_unless(strcmp(a_message->router_from, "") == 0, + "message_set_router_info should set msg->router_from to empty string if NULL router_from arg is passed"); + fail_unless(strcmp(a_message->router_to, "") == 0, + "message_set_router_info should set msg->router_to to empty string if NULL router_to arg is passed"); + fail_unless(strcmp(a_message->router_class, "") == 0, + "message_set_router_info should set msg->router_class to empty string if NULL router_class arg is passed"); + fail_unless(strcmp(a_message->router_command, "") == 0, + "message_set_router_info should set msg->router_command to empty string if NULL router_command arg is passed"); + fail_unless(a_message->broadcast == 0, + "message_set_router_info should set msg->broadcast to the content of the broadcast_enabled arg"); +END_TEST + +START_TEST(test_transport_message_set_router_info_populated) + message_set_router_info(a_message, "routerfrom", "routerto", "routerclass", "routercmd", 1); + fail_unless(strcmp(a_message->router_from, "routerfrom") == 0, + "message_set_router_info should set msg->router_from to the value of the router_from arg"); + fail_unless(strcmp(a_message->router_to, "routerto") == 0, + "message_set_router_info should set msg->router_to to the value of the router_to arg"); + fail_unless(strcmp(a_message->router_class, "routerclass") == 0, + "message_set_router_info should set msg->router_class to the value of the router_class arg"); + fail_unless(strcmp(a_message->router_command, "routercmd") == 0, + "message_set_router_info should set msg->router_command to the value of the router_command arg"); + fail_unless(a_message->broadcast == 1, + "message_set_router_info should set msg->broadcast to the value of the broadcast_enabled arg"); +END_TEST + +START_TEST(test_transport_message_free) + fail_unless(message_free(NULL) == 0, + "message_free should return 0 if passed a NULL msg arg"); + transport_message *msg = message_init("one", "two", "three", "four", "five"); + fail_unless(message_free(msg) == 1, + "message_free should return 1 if successful"); +END_TEST + +START_TEST(test_transport_message_prepare_xml) + fail_unless(message_prepare_xml(NULL) == 0, + "Passing a NULL msg arg to message_prepare_xml should return 0"); + + transport_message *msg = message_init(NULL,NULL,NULL,NULL,NULL); + msg->msg_xml = "somevalue"; + fail_unless(message_prepare_xml(msg) == 1, + "If msg->msg_xml is already populated, message_prepare_xml should return 1"); + + message_set_router_info(a_message, "routerfrom", "routerto", "routerclass", "routercommand", 1); + message_set_osrf_xid(a_message, "osrfxid"); + set_msg_error(a_message, "errortype", 123); + + fail_unless(message_prepare_xml(a_message) == 1, + "message_prepare_xml should return 1 upon success"); + fail_if(a_message->msg_xml == NULL, + "message_prepare_xml should store the returned xml in msg->msg_xml"); + fail_unless(strcmp(a_message->msg_xml, "threadsubjectbody") == 0, + "message_prepare_xml should store the correct xml in msg->msg_xml"); +END_TEST + +START_TEST(test_transport_message_jid_get_username) + int buf_size = 15; + char buffer[buf_size]; + jid_get_username("testuser@domain.com/stuff", buffer, buf_size); + fail_unless(strcmp(buffer, "testuser") == 0, + "jid_get_username should set the buffer to the username extracted from the jid arg"); +END_TEST + +START_TEST(test_transport_message_jid_get_resource) + char buf_size = 15; + char buffer[buf_size]; + jid_get_resource("testuser@domain.com/stuff", buffer, buf_size); + fail_unless(strcmp(buffer, "stuff") == 0, + "jid_get_resource should set the buffer to the resource extracted from the jid arg"); + jid_get_resource("testuser@domain.com", buffer, buf_size); + fail_unless(strcmp(buffer, "") == 0, + "jid_get_resource should set the buffer to an empty string if there is no resource"); +END_TEST + +START_TEST(test_transport_message_jid_get_domain) + char buf_size = 15; + char buffer[buf_size]; + jid_get_domain("testuser@domain.com/stuff", buffer, buf_size); + fail_unless(strcmp(buffer, "domain.com") == 0, + "jid_get_domain should set the buffer to the domain extracted from the jid arg"); + jid_get_domain("ksdljflksd", buffer, buf_size); + fail_unless(strcmp(buffer, "") == 0, + "jid_get_domain should set the buffer to an empty string if the jid is malformed"); +END_TEST + +START_TEST(test_transport_message_set_msg_error) + set_msg_error(a_message, NULL, 111); + fail_unless(a_message->is_error == 1, + "set_msg_error called with a NULL error type should only set msg->is_error to 1"); + set_msg_error(a_message, "fatal", 123); + fail_unless(a_message->is_error == 1, + "set_msg_error should set msg->is_error to 1"); + fail_unless(strcmp(a_message->error_type, "fatal") == 0, + "set_msg_error should set msg->error_type if error_type arg is passed"); + fail_unless(a_message->error_code == 123, + "set_msg_error should set msg->error_code to the value of the err_code arg"); +END_TEST +//END TESTS + +Suite *transport_message_suite(void) { + //Create test suite, test case, initialize fixture + Suite *s = suite_create("transport_message"); + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, setup, teardown); + + //Add tests to test case + tcase_add_test(tc_core, test_transport_message_init_empty); + tcase_add_test(tc_core, test_transport_message_init_populated); + tcase_add_test(tc_core, test_transport_message_new_message_from_xml_empty); + tcase_add_test(tc_core, test_transport_message_new_message_from_xml_populated); + tcase_add_test(tc_core, test_transport_message_set_osrf_xid); + tcase_add_test(tc_core, test_transport_message_set_router_info_empty); + tcase_add_test(tc_core, test_transport_message_set_router_info_populated); + tcase_add_test(tc_core, test_transport_message_free); + tcase_add_test(tc_core, test_transport_message_prepare_xml); + tcase_add_test(tc_core, test_transport_message_jid_get_username); + tcase_add_test(tc_core, test_transport_message_jid_get_resource); + tcase_add_test(tc_core, test_transport_message_jid_get_domain); + tcase_add_test(tc_core, test_transport_message_set_msg_error); + + //Add test case to test suite + suite_add_tcase(s, tc_core); + + return s; +} + +void run_tests(SRunner *sr) { + srunner_add_suite(sr, transport_message_suite()); +} diff --git a/tests/testsuite.c b/tests/testsuite.c new file mode 100644 index 0000000..e3fcae0 --- /dev/null +++ b/tests/testsuite.c @@ -0,0 +1,15 @@ +#include +#include +#include "testsuite.h" + +extern void run_tests(SRunner *sr); + +int main (int argc, char **argv) +{ + SRunner *sr = srunner_create(NULL); + run_tests(sr); + srunner_run_all(sr, CK_NORMAL); + int failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/testsuite.h b/tests/testsuite.h new file mode 100644 index 0000000..b6ef586 --- /dev/null +++ b/tests/testsuite.h @@ -0,0 +1,4 @@ +#ifndef __OPENSRF_CHECK_H__ +#define __OPENSRF_CHECK_H__ + +#endif /* __OPENSRF_CHECK_H__ */ -- 2.43.2