| /* $Id$ | |
| * | |
| * Licensed to the Apache Software Foundation (ASF) under one or more | |
| * contributor license agreements. See the NOTICE file distributed with | |
| * this work for additional information regarding copyright ownership. | |
| * The ASF licenses this file to you under the Apache License, Version | |
| * 2.0 (the "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| /* | |
| * test_packetizer.c | |
| */ | |
| #include "apr_time.h" /* some apr must be included first */ | |
| #include "etch_packetizer.h" /* must be included second */ | |
| #include <tchar.h> | |
| #include <stdio.h> | |
| #include <conio.h> | |
| #include "cunit.h" | |
| #include "basic.h" | |
| #include "automated.h" | |
| #include "etch_connection.h" | |
| #include "etch_global.h" | |
| #include "etch_encoding.h" | |
| #include "etchthread.h" | |
| #include "etchlog.h" | |
| int apr_setup(void); | |
| int apr_teardown(void); | |
| int this_setup(); | |
| int this_teardown(); | |
| apr_pool_t* g_apr_mempool; | |
| const char* pooltag = "etchpool"; | |
| /* - - - - - - - - - - - - - - | |
| * unit test infrastructure | |
| * - - - - - - - - - - - - - - | |
| */ | |
| int init_suite(void) | |
| { | |
| apr_setup(); | |
| etch_runtime_init(TRUE); | |
| return this_setup(); | |
| } | |
| int clean_suite(void) | |
| { | |
| this_teardown(); | |
| etch_runtime_cleanup(0,0); /* free memtable and cache etc */ | |
| apr_teardown(); | |
| return 0; | |
| } | |
| int g_is_automated_test, g_bytes_allocated; | |
| #define IS_DEBUG_CONSOLE FALSE | |
| /* | |
| * apr_setup() | |
| * establish apache portable runtime environment | |
| */ | |
| int apr_setup(void) | |
| { | |
| int result = apr_initialize(); | |
| if (result == 0) | |
| { result = etch_apr_init(); | |
| g_apr_mempool = etch_apr_mempool; | |
| } | |
| if (g_apr_mempool) | |
| apr_pool_tag(g_apr_mempool, pooltag); | |
| else result = -1; | |
| return result; | |
| } | |
| /* | |
| * apr_teardown() | |
| * free apache portable runtime environment | |
| */ | |
| int apr_teardown(void) | |
| { | |
| if (g_apr_mempool) | |
| apr_pool_destroy(g_apr_mempool); | |
| g_apr_mempool = NULL; | |
| apr_terminate(); | |
| return 0; | |
| } | |
| int this_setup() | |
| { | |
| etch_apr_mempool = g_apr_mempool; | |
| return 0; | |
| } | |
| int this_teardown() | |
| { | |
| return 0; | |
| } | |
| /* - - - - - - - - - - - - - - | |
| * unit test support | |
| * - - - - - - - - - - - - - - | |
| */ | |
| etch_packetizer* g_my_packetizer; | |
| i_sessionpacket* g_my_sessionpacket; | |
| i_transportdata* g_my_transportdata; | |
| etch_flexbuffer* g_mybuf; | |
| etch_who* g_who; | |
| #define THISTEST_WHO_VALUE 0x5151 | |
| unsigned short CLASSID_MY_IMPL_SP; | |
| unsigned short CLASSID_MY_IMPL_TD; | |
| #define is_my_impl_transportdata(x) \ | |
| (x && ((objmask*)x)->obj_type == ETCHTYPEB_TRANSPORTDATA && ((objmask*)x)->class_id == CLASSID_MY_IMPL_TD) | |
| #define is_my_impl_sessionpkt(x) \ | |
| (x && ((objmask*)x)->obj_type == ETCHTYPEB_SESSIONPKT&& ((objmask*)x)->class_id == CLASSID_MY_IMPL_SP) | |
| int check_packetizer_results(i_transportdata*, etch_nativearray*); | |
| int check_packetizer_resultx(i_sessionpacket*, etch_nativearray*); | |
| int check_packetized_results (etch_arraylist*, etch_nativearray*); | |
| int check_packetized_result (byte* v1, size_t c1, byte* v2, size_t c2); | |
| etch_arraylist* new_packetizertest_list(); | |
| typedef enum etch_what | |
| { WHAT_NONE, WHAT_DATA, WHAT_PACKET, | |
| TRANSPORT_QUERY, TRANSPORT_CONTROL, TRANSPORT_NOTIFY, | |
| SESSION_QUERY, SESSION_CONTROL, SESSION_NOTIFY | |
| } etch_what; | |
| int is_equal_who(etch_who* who1, etch_who* who2) | |
| { | |
| int n1 = 0, n2 = 0; | |
| if (!who1 || !who2) return FALSE; | |
| if (who1->class_id != CLASSID_WHO || who2->class_id != CLASSID_WHO) return FALSE; | |
| if (!who1->value || !who2->value) return FALSE; | |
| if (!is_etch_int32(who1->value) || !is_etch_int32(who2->value)) return FALSE; | |
| n1 = ((etch_int32*)who1->value)->value; | |
| n2 = ((etch_int32*)who2->value)->value; | |
| return n1 == n2; | |
| } | |
| /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
| * my_impl_transportdata (i_transportdata implementation) | |
| * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
| */ | |
| /** | |
| * my_impl_transportdata | |
| * test object implementing i_transportdata | |
| */ | |
| typedef struct my_impl_transportdata | |
| { | |
| unsigned int hashkey; | |
| unsigned short obj_type; | |
| unsigned short class_id; | |
| struct objmask* vtab; | |
| int (*destroy)(void*); | |
| void*(*clone) (void*); | |
| obj_gethashkey get_hashkey; | |
| struct objmask* parent; | |
| etchresult* result; | |
| unsigned int refcount; | |
| unsigned int length; | |
| unsigned char is_null; | |
| unsigned char is_copy; | |
| unsigned char is_static; | |
| unsigned char reserved; | |
| /* i_transportdata interface and methods, plus original destructor | |
| * which becomes replaced with a custom destructor to destroy this | |
| * object. this is the model for destroying an interface wrapper object | |
| * when we do not save and pass around a pointer to the wrapper, but rather | |
| * a pointer to the interface. the interface in question, i_transportdata | |
| * in this case, contains a pointer to the wrapper object, in this case a | |
| * my_impl_transportdata*. when the interface is instantiated, its original | |
| * destructor is saved, and is replaced with a destructor which invokes | |
| * the wrapper's destructor. the wrapper destructor must then know to | |
| * invoke the interface's original destructor when destroying the interface. | |
| */ | |
| i_transportdata* itd; /* owned */ | |
| objdtor destroy_transportdata; /* i_transportdata original destructor */ | |
| etch_transport_data transport_data; /* i_transportdata::transport_data() */ | |
| i_sessiondata* session; /* not owned */ | |
| etch_what what; | |
| etch_who* recipient; /* not owned */ | |
| etch_arraylist* list; /* owned */ | |
| etch_object* query; /* owned */ | |
| etch_object* query_result; /* owned */ | |
| etch_object* control; /* owned */ | |
| etch_object* value; /* owned */ | |
| etch_object* eventx; /* owned */ | |
| } my_impl_transportdata; | |
| /** | |
| * destroy_my_impl_transportdata() | |
| * my_impl_transportdata destructor | |
| */ | |
| int destroy_my_impl_transportdata (my_impl_transportdata* thisx) | |
| { | |
| if (thisx->refcount > 0 && --thisx->refcount > 0) return -1; | |
| if (!is_etchobj_static_content(thisx)) | |
| { /* invoke original i_transportdata destructor */ | |
| if (thisx->itd && thisx->destroy_transportdata) | |
| thisx->destroy_transportdata(thisx->itd); | |
| if (thisx->list) | |
| thisx->list->destroy(thisx->list); | |
| if (thisx->query) | |
| thisx->query->destroy(thisx->query); | |
| if (thisx->query_result) | |
| thisx->query_result->destroy(thisx->query_result); | |
| if (thisx->control) | |
| thisx->control->destroy(thisx->control); | |
| if (thisx->value) | |
| thisx->value->destroy(thisx->value); | |
| if (thisx->eventx) | |
| thisx->eventx->destroy(thisx->eventx); | |
| } | |
| return destroy_objectex((objmask*) thisx); | |
| } | |
| /** | |
| * impl_transport_data() | |
| * my_impl_transportdata::transport_data | |
| * @param whoto caller retains, can be null | |
| * @param fbuf caller retains | |
| */ | |
| int impl_transport_data (my_impl_transportdata* mytd, etch_who* whoto, etch_flexbuffer* fbuf) | |
| { | |
| etch_nativearray* wrapped_array = NULL; | |
| byte* newbuf = NULL; | |
| size_t bytecount = 0; | |
| assert(is_my_impl_transportdata(mytd)); | |
| assert(is_etch_transportdata(mytd->itd)); | |
| mytd->what = WHAT_DATA; | |
| mytd->recipient = whoto; | |
| /* get a new byte vector of the entire packet from the buffer */ | |
| newbuf = etch_flexbuf_get_all (fbuf, &bytecount); | |
| /* wrap the packet bytes in an etch_nativearray object */ | |
| wrapped_array = new_nativearray_from (newbuf, | |
| CLASSID_ARRAY_BYTE, sizeof(byte), 1, (int) bytecount, 0, 0); | |
| /* we want wrapped array to own new packet bytes memory */ | |
| wrapped_array->is_content_owned = TRUE; | |
| return arraylist_add (mytd->list, wrapped_array); | |
| } | |
| /** | |
| * my_transport_control() | |
| * my_impl_transportdata::itransport::transport_control | |
| */ | |
| int my_transport_control (my_impl_transportdata* mytd, etch_object* control, etch_object* value) | |
| { | |
| /* changed parameter from i_transportdata* to my_impl_transportdata to correspond to change | |
| * in etch_pktizer_transport_control to pass pzr->transport->thisx rather than pzr->transport. | |
| * likewise for my_transport_notify() and my_transport_query. */ | |
| CU_ASSERT_FATAL(is_my_impl_transportdata(mytd)); | |
| mytd->what = TRANSPORT_CONTROL; | |
| mytd->control = control; | |
| mytd->value = value; | |
| return 0; | |
| } | |
| /** | |
| * my_transport_notify() | |
| * my_impl_transportdata::itransport::transport_notify | |
| */ | |
| int my_transport_notify (my_impl_transportdata* mytd, etch_object* evt) | |
| { | |
| CU_ASSERT_FATAL(is_my_impl_transportdata(mytd)); | |
| mytd->what = TRANSPORT_NOTIFY; | |
| mytd->eventx = evt; | |
| return 0; | |
| } | |
| /** | |
| * my_transport_query() | |
| * my_impl_transportdata::itransport::transport_query | |
| */ | |
| objmask* my_transport_query (my_impl_transportdata* mytd, etch_object* query) | |
| { | |
| etch_object* resultobj = NULL; | |
| CU_ASSERT_FATAL(is_my_impl_transportdata(mytd)); | |
| resultobj = mytd->query_result; /* set artificially in test */ | |
| mytd->what = TRANSPORT_QUERY; | |
| mytd->query = query; | |
| mytd->query_result = NULL; | |
| return (objmask*) resultobj; /* caller owns */ | |
| } | |
| /** | |
| * my_transport_get_session() | |
| * my_impl_transportdata::itransport::get_session | |
| */ | |
| i_sessiondata* my_transport_get_session (my_impl_transportdata* mytd) | |
| { | |
| ETCH_ASSERT(is_etch_transportdata(mytd)); | |
| return mytd->session; | |
| } | |
| /** | |
| * my_transport_set_session() | |
| * my_impl_transportdata::itransport::set_session | |
| */ | |
| void my_transport_set_session (my_impl_transportdata* mytd, i_sessiondata* newsession) | |
| { | |
| ETCH_ASSERT(is_etch_transportdata(mytd)); | |
| ETCH_ASSERT(is_etch_sessiondata(newsession)); | |
| mytd->session = newsession; | |
| } | |
| /* | |
| * destroy_my_transportdata() | |
| * i_transportdata destructor | |
| * this destructor will destroy its parent (my_impl_transportdata), | |
| * which will in turn destroy this object. | |
| */ | |
| int destroy_my_transportdata(i_transportdata* itd) | |
| { | |
| my_impl_transportdata* mytd = NULL; | |
| if (NULL == itd) return -1; | |
| mytd = itd->thisx; | |
| mytd->destroy(mytd); | |
| return 0; | |
| } | |
| /** | |
| * new_my_impl_transportdata() | |
| * my_impl_transportdata constructor | |
| */ | |
| my_impl_transportdata* new_my_impl_transportdata() | |
| { | |
| i_transportdata* itd = NULL; | |
| i_transport* itransport = NULL; | |
| /* this is a model for dynamic class ID assigment */ | |
| unsigned short class_id = CLASSID_MY_IMPL_TD? CLASSID_MY_IMPL_TD: | |
| (CLASSID_MY_IMPL_TD = get_dynamic_classid()); | |
| my_impl_transportdata* mytd = (my_impl_transportdata*) new_object | |
| (sizeof(my_impl_transportdata), ETCHTYPEB_TRANSPORTDATA, class_id); | |
| mytd->destroy = destroy_my_impl_transportdata; | |
| itransport = new_transport_interface_ex (mytd, | |
| (etch_transport_control) my_transport_control, | |
| (etch_transport_notify) my_transport_notify, | |
| (etch_transport_query) my_transport_query, | |
| (etch_transport_get_session) my_transport_get_session, | |
| (etch_transport_set_session) my_transport_set_session); | |
| itd = new_transportdata_interface(mytd, impl_transport_data, itransport); | |
| /* save off i_transportdata destructor */ | |
| mytd->destroy_transportdata = itd->destroy; | |
| /* replace i_transportdata destructor with one which will destroy this object */ | |
| itd->destroy = destroy_my_transportdata; | |
| mytd->list = new_packetizertest_list(); | |
| /* g_my_transportdata will get set to this interface */ | |
| mytd->itd = itd; | |
| return mytd; | |
| } | |
| /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
| * my_impl_sessionpacket (i_sessionpacket implementation) | |
| * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
| */ | |
| /** | |
| * my_impl_sessionpacket | |
| * test object implementing i_sessionpacket | |
| */ | |
| typedef struct my_impl_sessionpacket | |
| { | |
| unsigned int hashkey; | |
| unsigned short obj_type; | |
| unsigned short class_id; | |
| struct objmask* vtab; | |
| int (*destroy)(void*); | |
| void*(*clone) (void*); | |
| obj_gethashkey get_hashkey; | |
| struct objmask* parent; | |
| etchresult* result; | |
| unsigned int refcount; | |
| unsigned int length; | |
| unsigned char is_null; | |
| unsigned char is_copy; | |
| unsigned char is_static; | |
| unsigned char reserved; | |
| /* i_sessionpacket interface and methods, plus original destructor | |
| * which becomes replaced with a custom destructor to destroy this | |
| * object. this is the model for destroying an interface wrapper object | |
| * when we do not save and pass around a pointer to the wrapper, but rather | |
| * a pointer to the interface. the interface in question, i_sessionpacket | |
| * in this case, contains a pointer to the wrapper object, in this case a | |
| * my_impl_sessionpacket*. when the interface is instantiated, its original | |
| * destructor is saved, and is replaced with a destructor which invokes | |
| * the wrapper's destructor. the wrapper destructor must then know to | |
| * invoke the interface's original destructor when destroying the interface. | |
| */ | |
| i_sessionpacket* isp; /* owned */ | |
| objdtor destroy_sessionpacket; /* i_sessionpacket original destructor */ | |
| etch_session_packet session_packet; /* session_packet() */ | |
| etch_what what; | |
| etch_who* sender; /* not owned */ | |
| etch_arraylist* list; /* owned */ | |
| etch_object* query; /* owned */ | |
| etch_object* query_result; /* owned */ | |
| etch_object* control; /* owned */ | |
| etch_object* value; /* owned */ | |
| etch_object* eventx; /* owned */ | |
| } my_impl_sessionpacket; | |
| /** | |
| * destroy_my_impl_sessionpacket() | |
| * my_impl_sessionpacket destructor | |
| */ | |
| int destroy_my_impl_sessionpacket(my_impl_sessionpacket* thisx) | |
| { | |
| if (thisx->refcount > 0 && --thisx->refcount > 0) return -1; | |
| if (!is_etchobj_static_content(thisx)) | |
| { /* invoke original i_sessionpacket destructor */ | |
| if (thisx->isp && thisx->destroy_sessionpacket) | |
| thisx->destroy_sessionpacket(thisx->isp); | |
| if (thisx->list) | |
| thisx->list->destroy(thisx->list); | |
| if (thisx->query) | |
| thisx->query->destroy(thisx->query); | |
| if (thisx->query_result) | |
| thisx->query_result->destroy(thisx->query_result); | |
| if (thisx->control) | |
| thisx->control->destroy(thisx->control); | |
| if (thisx->value) | |
| thisx->value->destroy(thisx->value); | |
| if (thisx->eventx) | |
| thisx->eventx->destroy(thisx->eventx); | |
| } | |
| return destroy_objectex((objmask*) thisx); | |
| } | |
| /** | |
| * impl_session_packet() | |
| * my_impl_sessionpacket::session_packet | |
| * @param whofrom caller retains, can be null | |
| * @param fbuf caller retains | |
| */ | |
| int impl_session_packet (my_impl_sessionpacket* mysp, etch_who* whofrom, etch_flexbuffer* fbuf) | |
| { | |
| etch_nativearray* wrapped_array = NULL; | |
| byte* newbuf = NULL; | |
| size_t bytecount = 0; | |
| CU_ASSERT_FATAL(is_my_impl_sessionpkt(mysp)); | |
| mysp->what = WHAT_PACKET; | |
| mysp->sender = whofrom; | |
| /* get a new byte vector of the entire packet from the buffer */ | |
| newbuf = etch_flexbuf_get_all(fbuf, &bytecount); | |
| /* wrap the packet bytes in an etch_nativearray object */ | |
| wrapped_array = new_nativearray_from(newbuf, | |
| CLASSID_ARRAY_BYTE, sizeof(byte), 1, (int) bytecount, 0, 0); | |
| /* we want wrapped array to own new packet bytes memory */ | |
| wrapped_array->is_content_owned = TRUE; | |
| return arraylist_add(mysp->list, wrapped_array); | |
| } | |
| /** | |
| * my_session_control() | |
| * my_impl_sessionpacket::isession::session_control | |
| */ | |
| int my_session_control (my_impl_sessionpacket* mysp, etch_object* control, etch_object* value) | |
| { | |
| CU_ASSERT_FATAL(is_my_impl_sessionpkt(mysp)); | |
| mysp->what = SESSION_CONTROL; | |
| mysp->control = control; | |
| mysp->value = value; | |
| return 0; | |
| } | |
| /** | |
| * my_session_notify() | |
| * my_impl_sessionpacket::isession::session_notify | |
| */ | |
| int my_session_notify (my_impl_sessionpacket* mysp, etch_object* evt) | |
| { | |
| CU_ASSERT_FATAL(is_my_impl_sessionpkt(mysp)); | |
| mysp->what = SESSION_NOTIFY; | |
| mysp->eventx = evt; | |
| return 0; | |
| } | |
| /** | |
| * my_session_query() | |
| * my_impl_sessionpacket::isession::session_query | |
| */ | |
| objmask* my_session_query (my_impl_sessionpacket* mysp, etch_object* query) | |
| { | |
| etch_object* resultobj = NULL; | |
| CU_ASSERT_FATAL(is_my_impl_sessionpkt(mysp)); | |
| resultobj = mysp->query_result; /* set artificially in test */ | |
| mysp->what = SESSION_QUERY; | |
| mysp->query = query; | |
| mysp->query_result = NULL; | |
| return (objmask*) resultobj; /* caller owns */ | |
| } | |
| /** | |
| * new_packetizertest_list() | |
| * constructor for a list which owns content memory and where content is etch_object derived. | |
| * content will be etch_nativearray objects | |
| */ | |
| etch_arraylist* new_packetizertest_list() | |
| { | |
| etch_arraylist* list = new_arraylist(32,0); | |
| list->content_type = ETCHARRAYLIST_CONTENT_OBJECT; /* list can call destroy() on list item */ | |
| list->is_readonly = FALSE; | |
| return list; | |
| } | |
| /* | |
| * destroy_my_sessionpacket() | |
| * i_sessionpacket destructor | |
| * this destructor will destroy its parent (my_impl_sessionpacket), | |
| * which will in turn destroy this object. | |
| */ | |
| int destroy_my_sessionpacket(i_sessionpacket* itp) | |
| { | |
| my_impl_sessionpacket* mytp = NULL; | |
| if (NULL == itp) return -1; | |
| mytp = itp->thisx; | |
| mytp->destroy(mytp); | |
| return 0; | |
| } | |
| /** | |
| * new_my_impl_sessionpacket() | |
| * my_impl_sessionpacket constructor | |
| */ | |
| my_impl_sessionpacket* new_my_impl_sessionpacket() | |
| { | |
| i_sessionpacket* isessionpkt = NULL; | |
| i_session* isession = NULL; | |
| /* this is a model for dynamic class ID assigment */ | |
| unsigned short class_id = CLASSID_MY_IMPL_SP? CLASSID_MY_IMPL_SP: | |
| (CLASSID_MY_IMPL_SP = get_dynamic_classid()); | |
| my_impl_sessionpacket* mysessionpkt = (my_impl_sessionpacket*) new_object | |
| (sizeof(my_impl_sessionpacket), ETCHTYPEB_SESSIONPKT, class_id); | |
| mysessionpkt->destroy = destroy_my_impl_sessionpacket; | |
| mysessionpkt->list = new_packetizertest_list(); | |
| isession = new_session_interface(mysessionpkt, | |
| (etch_session_control) my_session_control, | |
| (etch_session_notify) my_session_notify, | |
| (etch_session_query) my_session_query); | |
| isessionpkt = new_sessionpkt_interface(mysessionpkt, impl_session_packet, isession); | |
| /* save off i_sessionpacket destructor */ | |
| mysessionpkt->destroy_sessionpacket = isessionpkt->destroy; | |
| /* replace i_sessionpacket destructor with one which will destroy this object */ | |
| isessionpkt->destroy = destroy_my_sessionpacket; | |
| /* g_my_sessionpacket will get set to this interface */ | |
| mysessionpkt->isp = isessionpkt; | |
| return mysessionpkt; | |
| } | |
| /* - - - - - - - - - - - - - - - - - - - - - - | |
| * support functions | |
| * - - - - - - - - - - - - - - - - - - - - - - | |
| */ | |
| /** | |
| * check_packetizer_results() | |
| * check array of packetizer result byte arrays against a control byte array. | |
| * arrays may be packet payloads, or packets with headers, depending on test. | |
| * result arrays are found in the packet handler arraylist, each such list item | |
| * being an etch_nativearray object of one dimension, wrapping that result array. | |
| * control arrays are passed as an etch_nativearray of two dimensions, created | |
| * from a static 2-dimensional array. | |
| */ | |
| int check_packetizer_results(i_transportdata* itd, etch_nativearray* expected_array) | |
| { | |
| my_impl_transportdata* mytd = (my_impl_transportdata*) itd->thisx; | |
| const int packetcount = mytd->list->count; /* # of result arrays in list */ | |
| int errors = 0; | |
| if (NULL == expected_array) /* todo: also check for zero populated count */ | |
| return packetcount == 0? 0: -1; | |
| if (packetcount != expected_array->dimension[1]) | |
| return -1; /* check against count of expected results */ | |
| errors = check_packetized_results(mytd->list, expected_array); | |
| return errors? -1: 0; | |
| } | |
| /** | |
| * check_packetizer_resultx() | |
| * check array of packetizer result byte arrays against a control byte array. | |
| * arrays may be packet payloads, or packets with headers, depending on test. | |
| * result arrays are found in the packet handler arraylist, each such list item | |
| * being an etch_nativearray object of one dimension, wrapping that result array. | |
| * control arrays are passed as an etch_nativearray of two dimensions, created | |
| * from a static 2-dimensional array. | |
| */ | |
| int check_packetizer_resultx(i_sessionpacket* isp, etch_nativearray* expected_array) | |
| { | |
| my_impl_sessionpacket* mysp = (my_impl_sessionpacket*) isp->thisx; | |
| const int packetcount = mysp->list->count; /* # of result arrays in list */ | |
| int errors = 0; | |
| if (NULL == expected_array) /* todo: also check for zero populated count */ | |
| return packetcount == 0? 0: -1; | |
| if (packetcount != expected_array->dimension[1]) | |
| return -1; /* check against count of expected results */ | |
| errors = check_packetized_results(mysp->list, expected_array); | |
| return errors? -1: 0; | |
| } | |
| /** | |
| * check_packetized_results() | |
| */ | |
| int check_packetized_results(etch_arraylist* list, etch_nativearray* expected_array) | |
| { | |
| etch_iterator iterator; | |
| int result = 0, errors = 0, i = 0; | |
| set_iterator(&iterator, list, &list->iterable); | |
| while(iterator.has_next(&iterator)) | |
| { | |
| /* get result (one-dimension byte array) out of list */ | |
| etch_nativearray* resultobj = arraylist_get(list, i); | |
| byte* packetizedbytes = resultobj->values; | |
| size_t packetizedbytecount = resultobj->dimension[0]; | |
| /* get (offset to) this result out of expected results */ | |
| size_t dim2offset = etch_nativearray_off2(expected_array, i, 0); | |
| byte* expected_bytes = (byte*) expected_array->values + dim2offset; | |
| size_t expected_bytecount = expected_array->dimension[0]; | |
| result = check_packetized_result(packetizedbytes, packetizedbytecount, | |
| expected_bytes, expected_bytecount); | |
| if (result == -1) | |
| errors++; | |
| i++; | |
| iterator.next(&iterator); | |
| } | |
| return errors; | |
| } | |
| /** | |
| * check_packetized_result() | |
| * check a single packetizer result array against a control array, | |
| * each represented as a byte vector. the array can be a packet, or a packet payload, | |
| * depending on tested direction of the packetizer call. | |
| */ | |
| int check_packetized_result (byte* v1, size_t c1, byte* v2, size_t c2) | |
| { | |
| byte *p = 0, *q = 0; | |
| size_t i = 0, errors = 0; | |
| if (c1 != c2) return FALSE; | |
| if (!v1 && !v2) return TRUE; | |
| if (!v1 || !v2) return FALSE; | |
| for(p = v1, q = v2; i < c1; i++, p++, q++) | |
| if (*p != *q) | |
| errors++; | |
| return errors? -1: 0; | |
| } | |
| /* - - - - - - - - - - - - - - - - - - - - - - | |
| * individual setup and teardown | |
| * - - - - - - - - - - - - - - - - - - - - - - | |
| */ | |
| /** | |
| * setup_this_test() | |
| */ | |
| int setup_this_test() | |
| { | |
| my_impl_transportdata* mytd_impl = NULL; | |
| my_impl_sessionpacket* mysp_impl = NULL; | |
| /* we instantiate a wrapper x which implements and instantiates i_transportpacket. | |
| * the instantiation of i_transportpacket will contain a pointer to x. | |
| * our global reference g_my_transportpacket is a pointer to the interface. | |
| * the purpose of this excercise is that, in the real binding we can pass | |
| * around the interface, whose methods can be then invoked without knowing | |
| * anything about the wrapper. when we want to reference the wrapper x, | |
| * it is (my_impl_transportpacket) g_my_transportpacket->thisx. | |
| */ | |
| mytd_impl = new_my_impl_transportdata(); | |
| g_my_transportdata = mytd_impl->itd; | |
| CU_ASSERT_FATAL(is_my_impl_transportdata(g_my_transportdata->thisx)); | |
| /* we instantiate a wrapper y which implements and instantiates i_sessionpacket. | |
| * the instantiation of i_sessionpacket will contain a pointer to y. | |
| * our global reference g_my_sessionpacket is a pointer to the interface. | |
| * the purpose of this excercise is that, in the real binding we can pass | |
| * around the interface, whose methods can be then invoked without knowing | |
| * anything about the wrapper. when we want to reference the wrapper x, | |
| * it is (my_impl_sessionpacket*) g_my_sessionpacket->thisx. | |
| */ | |
| mysp_impl = new_my_impl_sessionpacket(); | |
| g_my_sessionpacket = mysp_impl->isp; | |
| g_who = new_who(new_int32(THISTEST_WHO_VALUE), TRUE); | |
| /* finally instantiate the test packetizer */ | |
| g_my_packetizer = new_packetizer(g_my_transportdata, L"tcp", NULL); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_my_packetizer); | |
| g_my_packetizer->set_session(g_my_packetizer, g_my_sessionpacket); | |
| return 0; | |
| } | |
| /** | |
| * teardown_this_test() | |
| */ | |
| int teardown_this_test() | |
| { | |
| g_my_packetizer->destroy(g_my_packetizer); | |
| g_my_sessionpacket->destroy(g_my_sessionpacket); // destroy() is now 0xfeeefeee | |
| g_my_transportdata->destroy(g_my_transportdata); | |
| g_who->destroy(g_who); | |
| if (g_mybuf) | |
| g_mybuf->destroy(g_mybuf); | |
| g_my_packetizer = NULL; | |
| g_my_sessionpacket = NULL; | |
| g_my_transportdata = NULL; | |
| g_mybuf = NULL; | |
| g_who = NULL; | |
| return 0; | |
| } | |
| /* - - - - - - - - - - - - - - - - - - - - - - | |
| * tests | |
| * - - - - - - - - - - - - - - - - - - - - - - | |
| */ | |
| /** | |
| * test_sessionpacket_constructor() | |
| */ | |
| void test_sessionpacket_constructor(void) | |
| { | |
| my_impl_sessionpacket* mysp_impl = new_my_impl_sessionpacket(); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mysp_impl); | |
| /* the custom interface object destructors are coded to destroy their | |
| * implementing objects, so we do that here to verify this functionality. | |
| */ | |
| do | |
| { i_sessionpacket* isp = mysp_impl->isp; | |
| isp->destroy(isp); | |
| } while(0); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_transportdata_constructor() | |
| */ | |
| void test_transportdata_constructor(void) | |
| { | |
| my_impl_transportdata* mytd_impl = new_my_impl_transportdata(); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mytd_impl); | |
| /* the custom interface object destructors are coded to destroy their | |
| * implementing objects, so we do that here to verify this functionality. | |
| */ | |
| do | |
| { i_transportdata* itd = mytd_impl->itd; | |
| itd->destroy(itd); | |
| } while(0); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_packetizer_constructor() | |
| */ | |
| void test_packetizer_constructor(void) | |
| { | |
| etch_packetizer* pzr = NULL; | |
| i_transportdata* itd = NULL; | |
| my_impl_transportdata* mytd_impl = NULL; | |
| mytd_impl = new_my_impl_transportdata(); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mytd_impl); | |
| itd = mytd_impl->itd; | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(itd); | |
| /* packetizer does not own i_transportdata* itd */ | |
| pzr = new_packetizer(itd, L"tcp", NULL); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(pzr); | |
| pzr->destroy(pzr); | |
| /* i_transportdata.destroy() will destroy my_impl_transportdata */ | |
| itd->destroy(itd); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_test_setup() | |
| * test that the test setup works with all memory accounted for. | |
| * if this test fails, all subsequent tests would also fail. | |
| * all subsequent tests should include this skeleton code. | |
| */ | |
| void test_test_setup(void) | |
| { | |
| int result = setup_this_test(); | |
| CU_ASSERT_EQUAL_FATAL(result, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_who); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_my_packetizer); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_my_sessionpacket); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_my_transportdata); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_to_source_packet1() | |
| * test 1 for packets delivered to packet source | |
| */ | |
| void test_to_source_packet1(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| byte* disposable_packet = NULL; | |
| #define EXPECTED_HEADERSIZE 8 | |
| etch_nativearray* expected_result_array = NULL; | |
| my_impl_transportdata* mytransport = g_my_transportdata->thisx; | |
| byte empty_packet[EXPECTED_HEADERSIZE] = { 0,0,0,0, 0,0,0,0, }; | |
| byte expected_result[][EXPECTED_HEADERSIZE] = | |
| { | |
| { | |
| -34,-83,-66,-17, 0,0,0,0, | |
| }, | |
| }; | |
| CU_ASSERT_EQUAL_FATAL(g_my_packetizer->headersize, EXPECTED_HEADERSIZE); | |
| expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, sizeof(byte), 2, EXPECTED_HEADERSIZE, 1, 0); | |
| disposable_packet = etch_malloc(sizeof(empty_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, empty_packet, sizeof(empty_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(empty_packet), 1024, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->transport_packet(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, 0); | |
| result = check_packetizer_results(g_my_packetizer->transport, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mytransport->what, WHAT_DATA); | |
| result = is_equal_who(mytransport->recipient, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_to_source_packet2() | |
| * test 2 for packets delivered to packet source | |
| */ | |
| void test_to_source_packet2(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TTSP2BYTECOUNT 9 | |
| byte* disposable_packet = NULL; | |
| etch_nativearray* expected_result_array = NULL; | |
| my_impl_transportdata* mytransport = g_my_transportdata->thisx; | |
| byte test_packet[TTSP2BYTECOUNT] = { 0,0,0,0, 0,0,0,0, 1 }; | |
| byte expected_result[][TTSP2BYTECOUNT] = | |
| { /* --signature--- data-length data */ | |
| { /* de ad be ef 00 00 00 01 01 */ | |
| -34,-83,-66,-17, 0, 0, 0, 1, 1 | |
| }, | |
| }; | |
| CU_ASSERT_EQUAL_FATAL(g_my_packetizer->headersize, EXPECTED_HEADERSIZE); | |
| expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, sizeof(byte), 2, TTSP2BYTECOUNT, 1, 0); | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->transport_packet(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, 0); | |
| result = check_packetizer_results(g_my_packetizer->transport, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mytransport->what, WHAT_DATA); | |
| result = is_equal_who(mytransport->recipient, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_to_source_packet3() | |
| * test 3 for packets delivered to packet source | |
| */ | |
| void test_to_source_packet3(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TTSP3BYTECOUNT 10 | |
| byte* disposable_packet = NULL; | |
| etch_nativearray* expected_result_array = NULL; | |
| my_impl_transportdata* mytransport = g_my_transportdata->thisx; | |
| byte test_packet[TTSP3BYTECOUNT] = { 0,0,0,0, 0,0,0,0, 2, 3 }; | |
| byte expected_result[][TTSP3BYTECOUNT] = | |
| { /* --signature--- data-length data */ | |
| { /* de ad be ef 00 00 00 02 02 03 */ | |
| -34,-83,-66,-17, 0, 0, 0, 2, 2, 3 | |
| }, | |
| }; | |
| CU_ASSERT_EQUAL_FATAL(g_my_packetizer->headersize, EXPECTED_HEADERSIZE); | |
| expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, sizeof(byte), 2, TTSP3BYTECOUNT, 1, 0); | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->transport_packet(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, 0); | |
| result = check_packetizer_results(g_my_packetizer->transport, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mytransport->what, WHAT_DATA); | |
| result = is_equal_who(mytransport->recipient, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_to_source_badpacket1() | |
| * test 4 for packets delivered to packet source | |
| */ | |
| void test_to_source_badpacket1(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TTSP4BYTECOUNT 7 | |
| byte* disposable_packet = NULL; | |
| etch_nativearray* expected_result_array = NULL; | |
| my_impl_transportdata* mytransport = g_my_transportdata->thisx; | |
| byte test_packet[TTSP4BYTECOUNT] = { 0,0,0,0, 0,0,0 }; /* too short */ | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 256, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->transport_packet(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, -1); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_badpacket1() | |
| * test 1 for bad packet data | |
| */ | |
| void test_badpacket1(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TBP1COUNT 8 | |
| byte* disposable_packet = NULL; | |
| byte test_packet_1[TBP1COUNT] = { 0,0,0,0, 0,0,0,0 }; /* bad sig */ | |
| byte test_packet_2[TBP1COUNT] = { 1,2,3,4, 0,0,0,0 }; /* bad sig */ | |
| byte test_packet_3[TBP1COUNT] = { -34,-83,-66,-17, 0,1,0,0 }; /* bad len */ | |
| /* bad signature 1 */ | |
| disposable_packet = etch_malloc(sizeof(test_packet_1), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet_1, sizeof(test_packet_1)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet_1), 256, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, -1); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| /* bad signature 2 */ | |
| disposable_packet = etch_malloc(sizeof(test_packet_2), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet_2, sizeof(test_packet_2)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet_2), 256, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, -1); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| /* bad data length (65536) */ | |
| disposable_packet = etch_malloc(sizeof(test_packet_3), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet_3, sizeof(test_packet_3)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet_3), 256, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result, -1); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_single_single_data() | |
| * 3 tests for single packet in a single buffer | |
| */ | |
| void test_single_single_data(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TSPSB1BYTECOUNT 8 | |
| #define TSPSB2BYTECOUNT 9 | |
| #define TSPSB2RESULTBYTECOUNT 1 | |
| #define TSPSB3BYTECOUNT 10 | |
| #define TSPSB3RESULTBYTECOUNT 2 | |
| byte* disposable_packet = NULL; | |
| etch_nativearray* expected_result_2_array = NULL; | |
| etch_nativearray* expected_result_3_array = NULL; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| byte test_packet_1[TSPSB1BYTECOUNT] = { -34,-83,-66,-17, 0,0,0,0, }; | |
| byte test_packet_2[TSPSB2BYTECOUNT] = { -34,-83,-66,-17, 0,0,0,1, 1, }; | |
| byte test_packet_3[TSPSB3BYTECOUNT] = { -34,-83,-66,-17, 0,0,0,2, 3,4 }; | |
| byte expected_result_2[][TSPSB2RESULTBYTECOUNT] = | |
| { | |
| { | |
| 1 | |
| }, | |
| }; | |
| byte expected_result_3[][TSPSB3RESULTBYTECOUNT] = | |
| { | |
| { | |
| 3, 4 | |
| }, | |
| }; | |
| /* test 1 */ | |
| disposable_packet = etch_malloc(sizeof(test_packet_1), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet_1, sizeof(test_packet_1)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet_1), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet_1)); | |
| result = g_my_packetizer->session_data (g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, NULL); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| /* test 2 */ | |
| disposable_packet = etch_malloc(sizeof(test_packet_2), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet_2, sizeof(test_packet_2)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet_2), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet_2)); | |
| result = g_my_packetizer->session_data (g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| expected_result_2_array = new_nativearray_from | |
| (&expected_result_2, CLASSID_ARRAY_BYTE, sizeof(byte), 2, TSPSB2RESULTBYTECOUNT, 1, 0); | |
| result = check_packetizer_resultx (g_my_sessionpacket, expected_result_2_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| expected_result_2_array->destroy(expected_result_2_array); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| arraylist_clear (mysessionpkt->list, TRUE); | |
| /* test 3 */ | |
| disposable_packet = etch_malloc(sizeof(test_packet_3), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet_3, sizeof(test_packet_3)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet_3), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet_3)); | |
| result = g_my_packetizer->session_data (g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| expected_result_3_array = new_nativearray_from | |
| (&expected_result_3, CLASSID_ARRAY_BYTE, sizeof(byte), 2, TSPSB3RESULTBYTECOUNT, 1, 0); | |
| result = check_packetizer_resultx (g_my_sessionpacket, expected_result_3_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| expected_result_3_array->destroy(expected_result_3_array); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_one_buffer_data_1() | |
| * test two packets in a single buffer | |
| */ | |
| void test_two_in_one_buffer_data_1(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN1_1_BYTECOUNT (8 + 8) | |
| signed char* disposable_packet; | |
| signed char test_packet[TWOIN1_1_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0,0,0, | |
| -34,-83,-66,-17, 0,0,0,0, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, NULL); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_one_buffer_data_2() | |
| * test two packets in a single buffer - 2 | |
| */ | |
| void test_two_in_one_buffer_data_2(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN1_2_BYTECOUNT (8 + 1 + 8) | |
| #define TWOIN1_2_RESULT_BYTECOUNT 1 | |
| byte* disposable_packet; | |
| byte test_packet[TWOIN1_2_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0,0,1, 1, | |
| -34,-83,-66,-17, 0,0,0,0, | |
| }; | |
| byte expected_result[][TWOIN1_2_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 1 | |
| }, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, sizeof(byte), 2, | |
| TWOIN1_2_RESULT_BYTECOUNT, 1, 0); | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_one_buffer_data_3() | |
| * test two packets in a single buffer - 3 | |
| */ | |
| void test_two_in_one_buffer_data_3(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN1_3_BYTECOUNT (8 + 8 + 1) | |
| #define TWOIN1_3_RESULT_BYTECOUNT 1 | |
| byte* disposable_packet; | |
| byte test_packet[TWOIN1_3_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0,0,0, | |
| -34,-83,-66,-17, 0,0,0,1, 2 | |
| }; | |
| byte expected_result[][TWOIN1_3_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 2 | |
| }, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, sizeof(byte), 2, | |
| TWOIN1_3_RESULT_BYTECOUNT, 1, 0); | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 64, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_one_buffer_data_4() | |
| * test two packets in a single buffer - 4 | |
| */ | |
| void test_two_in_one_buffer_data_4(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| signed char* disposable_packet; | |
| /* byte count for all packets */ | |
| #define TWOIN1_4_BYTECOUNT (8 + 1 + 8 + 1) | |
| /* byte count for low order dimension of expected result array ( [2][1] ) */ | |
| #define TWOIN1_4_RESULT_BYTECOUNT 1 | |
| signed char test_packet[TWOIN1_4_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0,0,1, 1, | |
| -34,-83,-66,-17, 0,0,0,1, 2, | |
| }; | |
| signed char expected_result[][TWOIN1_4_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 1, /* packet 1 data */ | |
| }, | |
| { | |
| 2, /* packet 2 data */ | |
| }, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, | |
| sizeof(byte), /* size of an array item is 1 */ | |
| 2, /* count of dimensions [2][1] */ | |
| 1, /* count of items in low order dimension */ | |
| 2, /* count of items in secondary dimension */ | |
| 0); /* 3rd dimension (not applicable) */ | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_one_buffer_data_5() | |
| * test two packets in a single buffer - 5 | |
| */ | |
| void test_two_in_one_buffer_data_5(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| signed char* disposable_packet; | |
| /* byte count for all packets */ | |
| #define TWOIN1_5_BYTECOUNT (8 + 2 + 8 + 2) | |
| /* byte count for low order dimension of expected result array ( [2][2] ) */ | |
| #define TWOIN1_5_RESULT_BYTECOUNT 2 | |
| signed char test_packet[TWOIN1_5_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0,0,2, 3, 4, | |
| -34,-83,-66,-17, 0,0,0,2, 5, 6, | |
| }; | |
| signed char expected_result[][TWOIN1_5_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 3, 4, /* packet 1 data */ | |
| }, | |
| { | |
| 5, 6, /* packet 2 data */ | |
| }, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, | |
| sizeof(byte), /* size of an array item is 1 */ | |
| 2, /* count of dimensions [2][2] */ | |
| 2, /* count of items in low order dimension */ | |
| 2, /* count of items in secondary dimension */ | |
| 0); /* 3rd dimension (not applicable) */ | |
| disposable_packet = etch_malloc(sizeof(test_packet), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, test_packet, sizeof(test_packet)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(test_packet), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(test_packet)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| expected_result_array->destroy(expected_result_array); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_two_buffers_data_1() | |
| * test two packets in two buffers with header split across buffers | |
| * packets are empty in this test | |
| */ | |
| void test_two_in_two_buffers_data_1(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN2_1_BUF1_BYTECOUNT 6 | |
| #define TWOIN2_1_BUF2_BYTECOUNT 10 | |
| etch_flexbuffer* mybuf2=0; | |
| byte* disposable_packet=0; | |
| byte buf1_data[TWOIN2_1_BUF1_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0, /* packet 1 header (partial) */ | |
| }; | |
| byte buf2_data[TWOIN2_1_BUF2_BYTECOUNT] | |
| = { 0, 0, /* packet 1 header (balance) */ | |
| -34,-83,-66,-17, 0,0,0,0, /* packet 2 header */ | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| /* buffer 1 */ | |
| disposable_packet = etch_malloc(sizeof(buf1_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf1_data, sizeof(buf1_data)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(buf1_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(buf1_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| /* buffer 2 */ | |
| disposable_packet = etch_malloc(sizeof(buf2_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf2_data, sizeof(buf2_data)); | |
| mybuf2 = new_flexbuffer_from(disposable_packet, sizeof(buf2_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mybuf2); | |
| CU_ASSERT_EQUAL(mybuf2->datalen, sizeof(buf2_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| /* done - free memory */ | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| mybuf2 ->destroy(mybuf2); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_two_buffers_data_2() | |
| * test two packets in two buffers with header split across buffers | |
| * packets include bodies in this test | |
| */ | |
| void test_two_in_two_buffers_data_2(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN2_2_BUF1_BYTECOUNT 6 | |
| #define TWOIN2_2_BUF2_BYTECOUNT (2 + 2 + 8 + 2) | |
| /* byte count for low order dimension of expected result array ( [2][2] ) */ | |
| #define TWOIN2_2_RESULT_BYTECOUNT 2 | |
| etch_flexbuffer* mybuf2=0; | |
| byte* disposable_packet=0; | |
| byte buf1_data[TWOIN2_2_BUF1_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0,0, /* packet 1 header (partial) */ | |
| }; | |
| byte buf2_data[TWOIN2_2_BUF2_BYTECOUNT] | |
| = { 0, 2, /* packet 1 header (balance) */ | |
| 3, 4, /* packet 1 body */ | |
| -34,-83,-66,-17, 0,0,0,2, /* packet 2 header */ | |
| 5, 6, /* packet 2 body */ | |
| }; | |
| byte expected_result[][TWOIN2_2_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 3, 4, /* packet 1 body */ | |
| }, | |
| { | |
| 5, 6, /* packet 2 body */ | |
| }, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, | |
| sizeof(byte), /* size of an array item is 1 */ | |
| 2, /* count of dimensions [2][2] */ | |
| 2, /* count of items in low order dimension */ | |
| 2, /* count of items in secondary dimension */ | |
| 0 /* 3rd dimension (not applicable) */ | |
| ); | |
| /* buffer 1 */ | |
| disposable_packet = etch_malloc(sizeof(buf1_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf1_data, sizeof(buf1_data)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(buf1_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(buf1_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| /* buffer 2 */ | |
| disposable_packet = etch_malloc(sizeof(buf2_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf2_data, sizeof(buf2_data)); | |
| mybuf2 = new_flexbuffer_from(disposable_packet, sizeof(buf2_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mybuf2); | |
| CU_ASSERT_EQUAL(mybuf2->datalen, sizeof(buf2_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, mybuf2); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| /* done - free memory */ | |
| expected_result_array->destroy(expected_result_array); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| mybuf2 ->destroy(mybuf2); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_two_buffers_data_3() | |
| * test two packets in two buffers with body split across buffers | |
| */ | |
| void test_two_in_two_buffers_data_3(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN2_3_BUF1_BYTECOUNT (8 + 1) /* header1 + body1 1 of 2 */ | |
| #define TWOIN2_3_BUF2_BYTECOUNT (1 + 8 + 2) /* body1 2 of 2 + header2 + body2 */ | |
| /* byte count for low order dimension of expected result array ( [2][2] ) */ | |
| #define TWOIN2_3_RESULT_BYTECOUNT 2 | |
| etch_flexbuffer* mybuf2 = NULL; | |
| signed char* disposable_packet = NULL; | |
| signed char buf1_data[TWOIN2_3_BUF1_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0, 0, 0, 2, /* packet 1 header (length 2) */ | |
| 1, /* packet 1 partial body */ | |
| }; | |
| signed char buf2_data[TWOIN2_3_BUF2_BYTECOUNT] | |
| = { 2, /* packet 1 body balance */ | |
| -34,-83,-66,-17, 0, 0, 0, 2, /* packet 2 header */ | |
| 3, 4, /* packet 2 body */ | |
| }; | |
| signed char expected_result[][TWOIN2_3_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 1, 2, /* packet 1 body */ | |
| }, | |
| { | |
| 3, 4, /* packet 2 body */ | |
| }, | |
| }; | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, | |
| sizeof(byte), /* size of an array item is 1 */ | |
| 2, /* count of dimensions [2][2] */ | |
| 2, /* count of items in low order dimension */ | |
| 2, /* count of items in secondary dimension */ | |
| 0 /* 3rd dimension (not applicable) */ | |
| ); | |
| /* buffer 1 */ | |
| disposable_packet = etch_malloc(sizeof(buf1_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf1_data, sizeof(buf1_data)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(buf1_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(buf1_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| /* buffer 2 */ | |
| disposable_packet = etch_malloc(sizeof(buf2_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf2_data, sizeof(buf2_data)); | |
| mybuf2 = new_flexbuffer_from(disposable_packet, sizeof(buf2_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mybuf2); | |
| CU_ASSERT_EQUAL(mybuf2->datalen, sizeof(buf2_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, mybuf2); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| /* done - free memory */ | |
| expected_result_array->destroy(expected_result_array); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| mybuf2 ->destroy(mybuf2); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_two_in_two_buffers_data_4() | |
| * test two packets in two buffers with body split across buffers | |
| */ | |
| void test_two_in_two_buffers_data_4(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| #define TWOIN2_4_BUF1_BYTECOUNT (8 + 2) /* header1 + body1 2 of 3 */ | |
| #define TWOIN2_4_BUF2_BYTECOUNT (1 + 8 + 3) /* body1 3 of 3 + header2 + body2 */ | |
| /* byte count for low order dimension of expected result array ( [2][2] ) */ | |
| #define TWOIN2_4_RESULT_BYTECOUNT 3 | |
| etch_flexbuffer* mybuf2=0; | |
| byte* disposable_packet=0; | |
| byte buf1_data[TWOIN2_4_BUF1_BYTECOUNT] | |
| = { -34,-83,-66,-17, 0, 0, 0, 3, /* packet 1 header (length 2) */ | |
| 5, 6, /* packet 1 partial body */ | |
| }; | |
| byte buf2_data[TWOIN2_4_BUF2_BYTECOUNT] | |
| = { 7, /* packet 1 body balance */ | |
| -34,-83,-66,-17, 0, 0, 0, 3, /* packet 2 header */ | |
| 8, 9, 10 /* packet 2 body */ | |
| }; | |
| byte expected_result[][TWOIN2_4_RESULT_BYTECOUNT] = | |
| { | |
| { | |
| 5, 6, 7, /* packet 1 body */ | |
| }, | |
| { | |
| 8, 9, 10, /* packet 2 body */ | |
| }, | |
| }; | |
| etch_nativearray* expected_result_array = new_nativearray_from | |
| (&expected_result, CLASSID_ARRAY_BYTE, | |
| sizeof(byte), /* size of an array item is 1 */ | |
| 2, /* count of dimensions [2][2] */ | |
| 3, /* count of items in low order dimension */ | |
| 2, /* count of items in secondary dimension */ | |
| 0 /* 3rd dimension (not applicable) */ | |
| ); | |
| my_impl_sessionpacket* mysessionpkt = g_my_sessionpacket->thisx; | |
| /* buffer 1 */ | |
| disposable_packet = etch_malloc(sizeof(buf1_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf1_data, sizeof(buf1_data)); | |
| g_mybuf = new_flexbuffer_from(disposable_packet, sizeof(buf1_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(g_mybuf); | |
| CU_ASSERT_EQUAL(g_mybuf->datalen, sizeof(buf1_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, g_mybuf); | |
| CU_ASSERT_EQUAL(result,0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(mysessionpkt->sender); | |
| /* buffer 2 */ | |
| disposable_packet = etch_malloc(sizeof(buf2_data), ETCHTYPEB_BYTES); | |
| memcpy(disposable_packet, buf2_data, sizeof(buf2_data)); | |
| mybuf2 = new_flexbuffer_from(disposable_packet, sizeof(buf2_data), 0, 0); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(mybuf2); | |
| CU_ASSERT_EQUAL(mybuf2->datalen, sizeof(buf2_data)); | |
| result = g_my_packetizer->session_data(g_my_packetizer, g_who, mybuf2); | |
| CU_ASSERT_EQUAL(result,0); | |
| result = check_packetizer_resultx(g_my_sessionpacket, expected_result_array); | |
| CU_ASSERT_EQUAL(result, 0); | |
| CU_ASSERT_EQUAL(mysessionpkt->what, WHAT_PACKET); | |
| result = is_equal_who(mysessionpkt->sender, g_who); | |
| CU_ASSERT_EQUAL(result, TRUE); | |
| /* done - free memory */ | |
| expected_result_array->destroy(expected_result_array); | |
| g_mybuf->destroy(g_mybuf); g_mybuf = NULL; | |
| mybuf2 ->destroy(mybuf2); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_session_control | |
| * test the session control notification plumbing | |
| */ | |
| void test_session_control(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| const int MY_CONTROL_CLASSID = 0x5200, MY_VALUE_CLASSID = 0x5201; | |
| etch_object* mycontrolobj = new_etch_object(MY_CONTROL_CLASSID, NULL); | |
| etch_object* myvalueobj = new_etch_object(MY_VALUE_CLASSID, NULL); | |
| /* g_my_sessionpacket is the i_sessionpacket interface | |
| * my_impl_sessionpacket is the implementing test class */ | |
| my_impl_sessionpacket* my_session = g_my_sessionpacket->thisx; | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_session); | |
| CU_ASSERT_EQUAL(my_session->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(my_session->control); | |
| CU_ASSERT_PTR_NULL(my_session->value); | |
| /* we relinquish memory for mycontrolobj and myvalueobj here. | |
| * the session_control terminal destination must destroy them, which here | |
| * is handled by our session object destructor when we teardown_this_test() */ | |
| g_my_packetizer->session_control (g_my_packetizer, mycontrolobj, myvalueobj); | |
| CU_ASSERT_EQUAL(my_session->what, SESSION_CONTROL); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_session->control); | |
| CU_ASSERT_EQUAL(my_session->control->class_id, MY_CONTROL_CLASSID); | |
| CU_ASSERT_EQUAL(my_session->value->class_id, MY_VALUE_CLASSID); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_session_notify | |
| * test the session notify notification plumbing | |
| */ | |
| void test_session_notify(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| const int MY_EVENT_CLASSID = 0x5202; | |
| etch_object* myeventobj = new_etch_object(MY_EVENT_CLASSID, NULL); | |
| /* g_my_sessionpacket is the i_sessionpacket interface | |
| * my_impl_sessionpacket is the implementing test class */ | |
| my_impl_sessionpacket* my_session = g_my_sessionpacket->thisx; | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_session); | |
| CU_ASSERT_EQUAL(my_session->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(my_session->eventx); | |
| /* we relinquish memory for myeventobj here. | |
| * the session_control terminal destination must destroy it, which here | |
| * is handled by our session object destructor when we teardown_this_test() */ | |
| g_my_packetizer->session_notify(g_my_packetizer, myeventobj); | |
| CU_ASSERT_EQUAL(my_session->what, SESSION_NOTIFY); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_session->eventx); | |
| CU_ASSERT_EQUAL(my_session->eventx->class_id, MY_EVENT_CLASSID); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_session_query | |
| * test the session query notification plumbing | |
| */ | |
| void test_session_query(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| const int MY_QUERY_CLASSID = 0x5203, MY_RESULT_CLASSID = 0x5204; | |
| etch_object* myqueryobj = new_etch_object(MY_QUERY_CLASSID, NULL); | |
| etch_object* myresultobj = new_etch_object(MY_RESULT_CLASSID, NULL); | |
| etch_object* queryresult = NULL; | |
| /* g_my_sessionpacket is the i_sessionpacket interface | |
| * my_impl_sessionpacket is the implementing test class */ | |
| my_impl_sessionpacket* my_session = g_my_sessionpacket->thisx; | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_session); | |
| CU_ASSERT_EQUAL(my_session->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(my_session->query); | |
| /* we relinquish myresultobj here. see comments following */ | |
| my_session->query_result = myresultobj; | |
| /* we relinquish memory for myqueryobj here and assume queryresult. | |
| * the session_control terminal destination must destroy it, which here | |
| * is handled by our session object destructor when we teardown_this_test() */ | |
| queryresult = g_my_packetizer->session_query(g_my_packetizer, myqueryobj); | |
| CU_ASSERT_EQUAL(my_session->what, SESSION_QUERY); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_session->query); | |
| CU_ASSERT_EQUAL(my_session->query->class_id, MY_QUERY_CLASSID); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(queryresult); | |
| CU_ASSERT_EQUAL(queryresult->class_id, MY_RESULT_CLASSID); | |
| queryresult->destroy(queryresult); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_transport_control | |
| * test the transport control notification plumbing | |
| */ | |
| void test_transport_control(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| const int MY_CONTROL_CLASSID = 0x5200, MY_VALUE_CLASSID = 0x5201; | |
| etch_object* mycontrolobj = new_etch_object(MY_CONTROL_CLASSID, NULL); | |
| etch_object* myvalueobj = new_etch_object(MY_VALUE_CLASSID, NULL); | |
| /* g_my_transportdata is the i_transportdata interface | |
| * my_impl_transportdata is the implementing test class */ | |
| my_impl_transportdata* my_transport = g_my_transportdata->thisx; | |
| CU_ASSERT_FATAL(is_my_impl_transportdata(my_transport)); | |
| CU_ASSERT_EQUAL(my_transport->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(my_transport->control); | |
| CU_ASSERT_PTR_NULL(my_transport->value); | |
| /* we relinquish memory for mycontrolobj and myvalueobj here. | |
| * the transport_control terminal destination must destroy them, which here | |
| * is handled by our transport object destructor when we teardown_this_test() */ | |
| g_my_packetizer->transport_control(g_my_packetizer, mycontrolobj, myvalueobj); | |
| CU_ASSERT_EQUAL(my_transport->what, TRANSPORT_CONTROL); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport->control); | |
| CU_ASSERT_EQUAL(my_transport->control->class_id, MY_CONTROL_CLASSID); | |
| CU_ASSERT_EQUAL(my_transport->value->class_id, MY_VALUE_CLASSID); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_transport_notify | |
| * test the transport notify notification plumbing | |
| */ | |
| void test_transport_notify(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| const int MY_EVENT_CLASSID = 0x5202; | |
| etch_object* myeventobj = new_etch_object(MY_EVENT_CLASSID, NULL); | |
| /* g_my_transportdata is the i_transportdata interface | |
| * my_impl_transportdata is the implementing test class */ | |
| my_impl_transportdata* my_transport = g_my_transportdata->thisx; | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport); | |
| CU_ASSERT_EQUAL(my_transport->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(my_transport->control); | |
| CU_ASSERT_PTR_NULL(my_transport->value); | |
| /* we relinquish memory for myeventobj here. | |
| * the transport_control terminal destination must destroy it, which here | |
| * is handled by our transport object destructor when we teardown_this_test() */ | |
| g_my_packetizer->transport_notify(g_my_packetizer, myeventobj); | |
| CU_ASSERT_EQUAL(my_transport->what, TRANSPORT_NOTIFY); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport->eventx); | |
| CU_ASSERT_EQUAL(my_transport->eventx->class_id, MY_EVENT_CLASSID); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * test_transport_query | |
| * test the transport query notification plumbing | |
| */ | |
| void test_transport_query(void) | |
| { | |
| setup_this_test(); | |
| do | |
| { int result = 0; | |
| const int MY_QUERY_CLASSID = 0x5203, MY_RESULT_CLASSID = 0x5204; | |
| etch_object* myqueryobj = new_etch_object(MY_QUERY_CLASSID, NULL); | |
| etch_object* myresultobj = new_etch_object(MY_RESULT_CLASSID, NULL); | |
| etch_object* queryresult = NULL; | |
| /* g_my_transportdata is the i_transportdata interface | |
| * my_impl_transportdata is the implementing test class */ | |
| my_impl_transportdata* my_transport = g_my_transportdata->thisx; | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport); | |
| CU_ASSERT_EQUAL(my_transport->what, WHAT_NONE); | |
| CU_ASSERT_PTR_NULL(my_transport->query); | |
| /* we relinquish myresultobj here. see comments following */ | |
| my_transport->query_result = myresultobj; | |
| /* we relinquish memory for myqueryobj here and assume queryresult. | |
| * the transport_control terminal destination must destroy it, which here | |
| * is handled by our transport object destructor when we teardown_this_test() */ | |
| queryresult = g_my_packetizer->transport_query(g_my_packetizer, myqueryobj); | |
| CU_ASSERT_EQUAL(my_transport->what, TRANSPORT_QUERY); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport->query); | |
| CU_ASSERT_EQUAL(my_transport->query->class_id, MY_QUERY_CLASSID); | |
| CU_ASSERT_PTR_NOT_NULL_FATAL(queryresult); | |
| CU_ASSERT_EQUAL(queryresult->class_id, MY_RESULT_CLASSID); | |
| queryresult->destroy(queryresult); | |
| } while(0); | |
| teardown_this_test(); | |
| g_bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE); /* verify all memory freed */ | |
| CU_ASSERT_EQUAL(g_bytes_allocated, 0); | |
| memtable_clear(); /* start fresh for next test */ | |
| } | |
| /** | |
| * main | |
| */ | |
| int _tmain(int argc, _TCHAR* argv[]) | |
| { | |
| char c=0; | |
| CU_pSuite ps = NULL; | |
| g_is_automated_test = argc > 1 && 0 != wcscmp(argv[1], L"-a"); | |
| if (CUE_SUCCESS != CU_initialize_registry()) return 0; | |
| CU_set_output_filename("../test_packetizer"); | |
| ps = CU_add_suite("suite_packetizer", init_suite, clean_suite); | |
| etch_watch_id = 0; | |
| CU_add_test(ps, "test sessionpacket ctor/dtor", test_sessionpacket_constructor); | |
| CU_add_test(ps, "test transportdata ctor/dtor", test_transportdata_constructor); | |
| CU_add_test(ps, "test packetizer ctor/dtor", test_packetizer_constructor); | |
| CU_add_test(ps, "test unit test setup/teardown", test_test_setup); | |
| CU_add_test(ps, "test packet1 to source", test_to_source_packet1); | |
| CU_add_test(ps, "test packet2 to source", test_to_source_packet2); | |
| CU_add_test(ps, "test packet3 to source", test_to_source_packet3); | |
| CU_add_test(ps, "test bad packet 0", test_to_source_badpacket1); | |
| CU_add_test(ps, "test bad packet 1", test_badpacket1); | |
| CU_add_test(ps, "test 1 packet 1 buffer", test_single_single_data); | |
| CU_add_test(ps, "test 2 in 1 buffer 1", test_two_in_one_buffer_data_1); | |
| CU_add_test(ps, "test 2 in 1 buffer 2", test_two_in_one_buffer_data_2); | |
| CU_add_test(ps, "test 2 in 1 buffer 3", test_two_in_one_buffer_data_3); | |
| CU_add_test(ps, "test 2 in 1 buffer 4", test_two_in_one_buffer_data_4); | |
| CU_add_test(ps, "test 2 in 1 buffer 5", test_two_in_one_buffer_data_5); | |
| CU_add_test(ps, "test 2 in 2 buffers 1", test_two_in_two_buffers_data_1); | |
| CU_add_test(ps, "test 2 in 2 buffers 2", test_two_in_two_buffers_data_2); | |
| CU_add_test(ps, "test 2 in 2 buffers 3", test_two_in_two_buffers_data_3); | |
| CU_add_test(ps, "test 2 in 2 buffers 4", test_two_in_two_buffers_data_4); | |
| CU_add_test(ps, "test session control", test_session_control); | |
| CU_add_test(ps, "test session notify", test_session_notify); | |
| CU_add_test(ps, "test session query", test_session_query); | |
| CU_add_test(ps, "test transport control", test_transport_control); | |
| CU_add_test(ps, "test transport notify", test_transport_notify); | |
| CU_add_test(ps, "test transport query", test_transport_query); | |
| if (g_is_automated_test) | |
| CU_automated_run_tests(); | |
| else | |
| { CU_basic_set_mode(CU_BRM_VERBOSE); | |
| CU_basic_run_tests(); | |
| } | |
| if (!g_is_automated_test) { printf("any key ..."); while(!c) c = _getch(); wprintf(L"\n"); } | |
| CU_cleanup_registry(); | |
| return CU_get_error(); | |
| } |