From c2bc1b06597b19dc0ecb8f1e733f724325d54951 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Wed, 16 Nov 2011 18:14:51 +0100 Subject: [PATCH] the new testing framework works and the tests for cclass are done...actually i try to figure out how to tell autotools to build this correctly. --- createToken.c | 31 ++++++++++----- src/cclass.c | 9 +++-- src/dyntype.c | 2 +- tests/Makefile.am | 13 +++++- tests/cclassTest.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ tests/cclass_test.c | 33 --------------- tests/crypt.c | 2 +- tests/decrypt.c | 2 +- tests/dyntype.c | 16 ++++---- tests/hash.c | 12 +++--- tests/mock/class.c | 92 ++++++++++++++++++++++++++++++++++++++++++ tests/mock/class.h | 30 ++++++++++++++ tests/packet.c | 53 +++++++++++++++---------- tests/runtest.c | 39 ++++++++++++++---- tests/runtest.h | 6 +++ 15 files changed, 343 insertions(+), 94 deletions(-) create mode 100644 tests/cclassTest.c delete mode 100644 tests/cclass_test.c create mode 100644 tests/mock/class.c create mode 100644 tests/mock/class.h diff --git a/createToken.c b/createToken.c index 80d49e8..a36691b 100644 --- a/createToken.c +++ b/createToken.c @@ -10,7 +10,7 @@ void -setHashString(struct DYNTYPE_HASH * hash, const char * key, const char * value) +setHashString(struct DYNTYPE_HASH * hash, const char * const key, const char * value) { struct DYNTYPE * dyn; @@ -19,7 +19,7 @@ setHashString(struct DYNTYPE_HASH * hash, const char * key, const char * value) } void -setHashInt(struct DYNTYPE_HASH * hash, const char * key, const int value) +setHashInt(struct DYNTYPE_HASH * hash, const char * const key, const int value) { struct DYNTYPE * dyn; @@ -27,12 +27,21 @@ setHashInt(struct DYNTYPE_HASH * hash, const char * key, const int value) dyntype_hash_set(hash, key, dyn); } +void +deleteHashValue(struct DYNTYPE_HASH * hash, const char * const key) +{ + struct DYNTYPE * dyn = dyntype_hash_get(hash, key); + + delete(&dyn); +} + int main(int argc, char * argv[]) { struct CRYPT * crypt; struct PACKET * packet; struct DYNTYPE_HASH * data; + struct DYNTYPE * _clear; struct json_object * json; const char * json_str; char * encrypted; @@ -67,7 +76,7 @@ main(int argc, char * argv[]) crypt = new(CRYPT, MCRYPT_RIJNDAEL_256, MCRYPT_CFB); encrypted = crypt_encrypt(crypt, json_str, pass, &length); - delete(crypt); + delete(&crypt); json_object_put(json); b64d = calloc(BASE64_LENGTH(length), sizeof(char)); @@ -80,13 +89,15 @@ main(int argc, char * argv[]) printf("%s\n", b64d); free(b64d); - delete(dyntype_hash_get(data, "#C#")); - delete(dyntype_hash_get(data, "usr")); - delete(dyntype_hash_get(data, "pas")); - delete(dyntype_hash_get(data, "val")); - delete(packet_getHeader(packet)); - delete(packet_getData(packet)); - delete(packet); + deleteHashValue(data, "#C#"); + deleteHashValue(data, "usr"); + deleteHashValue(data, "pas"); + deleteHashValue(data, "val"); + _clear = packet_getHeader(packet); + delete(&_clear); + _clear = packet_getData(packet); + delete(&_clear); + delete(&packet); return 0; diff --git a/src/cclass.c b/src/cclass.c index 5796699..c7201c2 100644 --- a/src/cclass.c +++ b/src/cclass.c @@ -60,13 +60,14 @@ newFromJson(const void * _class, struct json_object * json) void delete(void * _object) { - const struct CCLASS ** class = _object; + const struct CCLASS ** class = *(void**)_object; - if (_object && *class && (*class)->__destruct) { - (*class)->__destruct(_object); + if (*(void**)_object && *class && (*class)->__destruct) { + (*class)->__destruct(*(void**)_object); } - free(_object); + free(*(void**)_object); + *(void**)_object = NULL; } struct json_object * diff --git a/src/dyntype.c b/src/dyntype.c index 92619e6..aaa0581 100644 --- a/src/dyntype.c +++ b/src/dyntype.c @@ -97,7 +97,7 @@ __destruct(struct DYNTYPE * _this) break; case DYNTYPE_TYPE_HASH: - delete((_this->data)._hash); + delete(&((_this->data)._hash)); break; default: diff --git a/tests/Makefile.am b/tests/Makefile.am index 6b93d08..9ec4d36 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,8 @@ ACLOCAL_AMFLAGS = -I m4 -TESTS = crypt decrypt dyntype hash packet -check_PROGRAMS = crypt decrypt dyntype hash packet +TESTS = crypt decrypt dyntype hash packet runtest +check_PROGRAMS = crypt decrypt dyntype hash packet runtest +noinst_LTLIBRARIES = cclassTest.la crypt_SOURCES = crypt.c ../base64.c crypt_LDADD = ../src/libtoken.la $(LIBOBJS) @@ -22,3 +23,11 @@ hash_CFLAGS = -I ../include -I .. packet_SOURCES = packet.c packet_LDADD = ../src/libtoken.la $(LIBOBJS) packet_CFLAGS = -I ../include -I .. + +cclassTest_la_SOURCES = cclassTest.c +cclassTest_la_LDFLAGS = -avoid-version -module -shared -export-dynamic +cclassTest_la_CFLAGS = -nostartfiles -fPIC -I. -I../include + +runtest_SOURCES = runtest.c +runtest_LDADD = ../src/libtoken.la $(LIBOBJS) -ldl +runtest_CFLAGS = -rdynamic diff --git a/tests/cclassTest.c b/tests/cclassTest.c new file mode 100644 index 0000000..a770fc8 --- /dev/null +++ b/tests/cclassTest.c @@ -0,0 +1,97 @@ +#include +#include + +#include "runtest.h" +#include "mock/class.h" +#include "token/cclass.h" + + +char testname[] = "cclassTest"; +struct MOCK_CLASS * mock = NULL; + +void +setUp() +{ + mock = NULL; + _reset(); +} + +void +tearDown() +{ + if (NULL != mock) { + delete(&mock); + } +} + +int +testNew(void) +{ + mock = new(MOCK_CLASS, 123); + + ASSERT_NOT_NULL(mock); + ASSERT_EQUAL(1, _called); + ASSERT_EQUAL(123, mock_class_getValue(mock)); + + return TEST_OK; +} + +int +testNewFromJson(void) +{ + struct json_object * json = json_object_new_int(123); + + mock = newFromJson(MOCK_CLASS, json); + json_object_put(json); + + ASSERT_NOT_NULL(mock); + ASSERT_EQUAL(1, _called); + ASSERT_EQUAL(123, mock_class_getValue(mock)); + + return TEST_OK; +} + +int +testDelete(void) +{ + mock = new(MOCK_CLASS, 123); + + ASSERT_NOT_NULL(mock); + + _reset(); + delete(&mock); + + ASSERT_NULL(mock); + ASSERT_EQUAL(1, _called); + + return TEST_OK; +} + +int +testToJson(void) +{ + struct json_object * json = NULL; + mock = new(MOCK_CLASS, 123); + int value; + + json = toJson(mock); + + ASSERT_NOT_NULL(json); + value = json_object_get_int(json); + json_object_put(json); + + ASSERT_EQUAL(123, value); + ASSERT_EQUAL(1, _called); + + return TEST_OK; +} + +testfunc tests[] = { + testNew, + testNewFromJson, + testDelete, + testToJson +}; +size_t count = FUNCS_COUNT(tests); + +// vim: set et ts=4 sw=4: diff --git a/tests/cclass_test.c b/tests/cclass_test.c deleted file mode 100644 index 7061ec8..0000000 --- a/tests/cclass_test.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#include "runtest.h" - - -char testname[] = "cclass_test"; - -int -dummy_ok(void) -{ - return TEST_OK; -} - -int -dummy_failed(void) -{ - return TEST_FAILED; -} - -int -dummy_error(void) -{ - return TEST_ERROR; -} - -testfunc tests[] = { - dummy_ok, - dummy_failed, - dummy_error -}; -size_t count = FUNCS_COUNT(tests); - -// vim: set et ts=4 sw=4: diff --git a/tests/crypt.c b/tests/crypt.c index bfb80b1..878015b 100644 --- a/tests/crypt.c +++ b/tests/crypt.c @@ -22,7 +22,7 @@ main(int argc, char * argv[]) crypt = new(CRYPT, MCRYPT_RIJNDAEL_256, MCRYPT_CFB); encrypted = crypt_encrypt(crypt, data, pass, &length); - delete(crypt); + delete(&crypt); b64d = calloc(BASE64_LENGTH(length), sizeof(char)); base64_encode(encrypted, length, b64d, BASE64_LENGTH(length)); diff --git a/tests/decrypt.c b/tests/decrypt.c index fa26d43..5085c16 100644 --- a/tests/decrypt.c +++ b/tests/decrypt.c @@ -28,7 +28,7 @@ main(int argc, char * argv[]) crypt = new(CRYPT, MCRYPT_RIJNDAEL_256, MCRYPT_CFB); decrypted = crypt_decrypt(crypt, data, pass, &length); - delete(crypt); + delete(&crypt); free(data); printf("%s\n", decrypted); diff --git a/tests/dyntype.c b/tests/dyntype.c index 7fd16e2..7989e9d 100644 --- a/tests/dyntype.c +++ b/tests/dyntype.c @@ -20,7 +20,7 @@ main(int argc, char * argv[]) printf("%d\n", (dyn->data)._int); - delete(dyn); + delete(&dyn); json_object_put(json); dyn = new(DYNTYPE, DYNTYPE_TYPE_INT, sizeof(int), 321); @@ -28,7 +28,7 @@ main(int argc, char * argv[]) printf("%s\n", json_object_to_json_string(json)); - delete(dyn); + delete(&dyn); json_object_put(json); json = json_object_new_string(TEST_STR); @@ -36,7 +36,7 @@ main(int argc, char * argv[]) printf("%s\n", (dyn->data)._string); - delete(dyn); + delete(&dyn); json_object_put(json); dyn = new(DYNTYPE, DYNTYPE_TYPE_STRING, strlen(TEST_STR), TEST_STR); @@ -44,7 +44,7 @@ main(int argc, char * argv[]) printf("%s\n", json_object_to_json_string(json)); - delete(dyn); + delete(&dyn); json_object_put(json); json = json_tokener_parse("{\"key1\":123,\"key2\":321,\"key3\":\"" TEST_STR "\"}"); @@ -61,18 +61,18 @@ main(int argc, char * argv[]) value = dyntype_hash_get(hash, TEST_KEY1); printf("%d\n", (value->data)._int); - delete(value); + delete(&value); value = dyntype_hash_get(hash, TEST_KEY2); printf("%d\n", (value->data)._int); - delete(value); + delete(&value); value = dyntype_hash_get(hash, TEST_KEY3); printf("%s\n", (value->data)._string); - delete(value); + delete(&value); } - delete(dyn); + delete(&dyn); return 0; } diff --git a/tests/hash.c b/tests/hash.c index 1f43fba..ebc1670 100644 --- a/tests/hash.c +++ b/tests/hash.c @@ -29,13 +29,13 @@ main(int argc, char * argv[]) dyn = dyntype_hash_get(hash, TEST_KEY1); printf("%d\n", (dyn->data)._int); - delete(dyn); + delete(&dyn); dyn = dyntype_hash_get(hash, TEST_KEY2); printf("%d\n", (dyn->data)._int); - delete(dyn); + delete(&dyn); - delete(hash); + delete(&hash); json = json_tokener_parse("{\"key1\":123,\"key2\":321}"); hash = newFromJson(DYNTYPE_HASH, json); @@ -43,13 +43,13 @@ main(int argc, char * argv[]) dyn = dyntype_hash_get(hash, TEST_KEY1); printf("%d\n", (dyn->data)._int); - delete(dyn); + delete(&dyn); dyn = dyntype_hash_get(hash, TEST_KEY2); printf("%d\n", (dyn->data)._int); - delete(dyn); + delete(&dyn); - delete(hash); + delete(&hash); return 0; } diff --git a/tests/mock/class.c b/tests/mock/class.c new file mode 100644 index 0000000..8b5c4e4 --- /dev/null +++ b/tests/mock/class.c @@ -0,0 +1,92 @@ +#include +#include + +#include "token/cclass.h" +#include "class.h" + +char _called; + +void +inline +_reset() +{ + _called = 0; +} + +static +void +__construct(struct MOCK_CLASS * _this, va_list * params) +{ + _called = 1; + _this->value = va_arg(* params, int); +} + +static +void +__jsonConst(struct MOCK_CLASS * _this, json_object * json) +{ + _called = 1; + assert(json_type_int == json_object_get_type(json)); + + _this->value = json_object_get_int(json); +} + +static +void +__destruct(struct MOCK_CLASS * _this) +{ + _called = 1; +} + +static +struct json_object * +__toJson(struct MOCK_CLASS * _this) +{ + struct json_object * json = json_object_new_int(_this->value); + + _called = 1; + return json; +} + +static const +struct CCLASS _mock_class = { + sizeof(struct MOCK_CLASS), + (ctor)__construct, + (jCtor)__jsonConst, + (dtor)__destruct, + (jTo)__toJson +}; + +const struct CCLASS * const MOCK_CLASS = &_mock_class; + +/** + * ~~~ method implementations ~~~~~~~~ + */ + +int +mock_class_getValue(struct MOCK_CLASS * _this) +{ + return _this->value; +} + +void +mock_class_setValue(struct MOCK_CLASS * _this, int value) +{ + _this->value = value; +} + +/** + * ~~~ helper for mock assertions ~~~~~~~~ + */ +void * +getConstruct() +{ + return __construct; +} + +void * +getJsonConst() +{ + return __jsonConst; +} +// vim: set et ts=4 sw=4: diff --git a/tests/mock/class.h b/tests/mock/class.h new file mode 100644 index 0000000..b09e1b6 --- /dev/null +++ b/tests/mock/class.h @@ -0,0 +1,30 @@ +#ifndef __MOCK_CLASS_H__ +#define __MOCK_CLASS_H__ + +#include "token/cclass.h" + + +extern char _called; + +extern void inline +_reset() +{ + _called = 0; +} + +struct MOCK_CLASS { + const struct CCLASS * const class; + int value; +}; + +extern const struct CCLASS * const MOCK_CLASS; + +/** + * ~~~ method declarations ~~~~~~~~ + */ + +int mock_class_getValue(struct MOCK_CLASS * _this); +void mock_class_setValue(struct MOCK_CLASS * _this, int value); + +#endif//__MOCK_CLASS_H__ +// vim: set et ts=4 sw=4: diff --git a/tests/packet.c b/tests/packet.c index d6c50ba..09f0e6b 100644 --- a/tests/packet.c +++ b/tests/packet.c @@ -11,7 +11,7 @@ void -setHashString(struct DYNTYPE_HASH * hash, const char * key, const char * value) +setHashString(struct DYNTYPE_HASH * hash, const char * const key, const char * value) { struct DYNTYPE * dyn; @@ -20,7 +20,7 @@ setHashString(struct DYNTYPE_HASH * hash, const char * key, const char * value) } void -setHashInt(struct DYNTYPE_HASH * hash, const char * key, const int value) +setHashInt(struct DYNTYPE_HASH * hash, const char * const key, const int value) { struct DYNTYPE * dyn; @@ -28,13 +28,22 @@ setHashInt(struct DYNTYPE_HASH * hash, const char * key, const int value) dyntype_hash_set(hash, key, dyn); } +void +deleteHashValue(struct DYNTYPE_HASH * hash, const char * const key) +{ + struct DYNTYPE * dyn = dyntype_hash_get(hash, key); + + delete(&dyn); +} + int main(int argc, char * argv[]) { - struct PACKET * packet; - struct DYNTYPE_HASH * data; - struct json_object * json; - char * json_str; + struct PACKET * packet; + struct DYNTYPE_HASH * data; + struct DYNTYPE * _clear; + struct json_object * json; + char * json_str; packet = new(PACKET); @@ -67,13 +76,15 @@ main(int argc, char * argv[]) printf("%s\n", json_str); - delete(dyntype_hash_get(data, "#C#")); - delete(dyntype_hash_get(data, "usr")); - delete(dyntype_hash_get(data, "pas")); - delete(dyntype_hash_get(data, "val")); - delete(packet_getHeader(packet)); - delete(packet_getData(packet)); - delete(packet); + deleteHashValue(data, "#C#"); + deleteHashValue(data, "usr"); + deleteHashValue(data, "pas"); + deleteHashValue(data, "val"); + _clear = packet_getHeader(packet); + delete(&_clear); + _clear = packet_getData(packet); + delete(&_clear); + delete(&packet); json_object_put(json); @@ -83,13 +94,15 @@ main(int argc, char * argv[]) printf("%s\n", json_object_to_json_string(json)); data = (packet_getData(packet)->data)._hash; - delete(dyntype_hash_get(data, "#C#")); - delete(dyntype_hash_get(data, "usr")); - delete(dyntype_hash_get(data, "pas")); - delete(dyntype_hash_get(data, "val")); - delete(packet_getHeader(packet)); - delete(packet_getData(packet)); - delete(packet); + deleteHashValue(data, "#C#"); + deleteHashValue(data, "usr"); + deleteHashValue(data, "pas"); + deleteHashValue(data, "val"); + _clear = packet_getHeader(packet); + delete(&_clear); + _clear = packet_getData(packet); + delete(&_clear); + delete(&packet); free(json_str); json_object_put(json); diff --git a/tests/runtest.c b/tests/runtest.c index 491fa35..a67530b 100644 --- a/tests/runtest.c +++ b/tests/runtest.c @@ -27,7 +27,6 @@ load_symbol(void * dlhandle, const char * const symbol) if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); - exit(EXIT_FAILURE); } return sym; @@ -44,27 +43,51 @@ runtests( testfunc * tests; const char * const testname; //char * const * funcnames; + char testfile[NAME_MAX+3] = "./"; + + strcat(testfile, filename); + + void (*setUp)() = NULL; + void (*tearDown)() = NULL; size_t index; void * dlhandle; - dlhandle = dlopen("./cclass.test", RTLD_LAZY); + dlhandle = dlopen(testfile, RTLD_LAZY); if (!dlhandle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } - * (void **) (&count) = load_symbol(dlhandle, "count"); - * (void **) (&tests) = load_symbol(dlhandle, "tests"); - * (void **) (&testname) = load_symbol(dlhandle, "testname"); + * (void **) (&count) = load_symbol(dlhandle, "count"); + * (void **) (&tests) = load_symbol(dlhandle, "tests"); + * (void **) (&testname) = load_symbol(dlhandle, "testname"); // * (void **) (&funcnames) = load_symbol(dlhandle, "funcnames"); + + * (void **) (&setUp) = load_symbol(dlhandle, "setUp"); + * (void **) (&tearDown) = load_symbol(dlhandle, "tearDown"); + if (NULL == count || NULL == tests || NULL == testname) { + *errors = TEST_ERROR; + return; + } + *_count += *count; printf("running tests for %s\n", testname); for (index=0; index<*count; index++) { - int result = tests[index](); + int result; + + if (NULL != setUp) { + setUp(); + } + + result = tests[index](); + + if (NULL != setUp) { + tearDown(); + } switch (result) { case TEST_FAILED: (*failures)++; break; @@ -99,7 +122,7 @@ main(int argc, char * argv[]) dirent = readdir(dir); while (dirent) { - if (0 == strcmp(".test", dirent->d_name + strlen(dirent->d_name) - 5)) { + if (0 == strcmp("Test.la", dirent->d_name + strlen(dirent->d_name) - 7)) { runtests(dirent->d_name, &count, &failures, &errors); } @@ -113,7 +136,7 @@ main(int argc, char * argv[]) failures, errors); - return 0; + return failures + errors; } // vim: set et ts=4 sw=4: diff --git a/tests/runtest.h b/tests/runtest.h index b1a67d5..4b45f03 100644 --- a/tests/runtest.h +++ b/tests/runtest.h @@ -10,6 +10,12 @@ enum RESULT_TYPES { TEST_ERROR }; +#define ASSERT_NULL(value) if (NULL != (value)) return TEST_FAILED +#define ASSERT_NOT_NULL(value) if (NULL == (value)) return TEST_FAILED +#define ASSERT_EQUAL(val1,val2) if ((val1) != (val2)) return TEST_FAILED +#define ASSERT_NOT_EQUAL(val1,val2) if ((val1) == (val2)) return TEST_FAILED + + typedef int (* testfunc)(void); #define FUNCS_COUNT(array) (sizeof((array)) / sizeof(testfunc))