blob: 2dd0547acd98a4063edc704c49697490ccea5ae8 [file] [log] [blame]
/* $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 "etch_runtime.h"
#include "etch_packetizer.h"
#include "etch_connection.h"
#include "etch_nativearray.h"
#include "etch_encoding.h"
#include "etch_thread.h"
#include "etch_objecttypes.h"
#include "etch_general.h"
#include "etch_log.h"
#include "etch_mem.h"
#include <stdio.h>
#include "CUnit.h"
#define IS_DEBUG_CONSOLE FALSE
// extern types
extern apr_pool_t* g_etch_main_pool;
/* - - - - - - - - - - - - - -
* unit test infrastructure
* - - - - - - - - - - - - - -
*/
static int init_suite(void)
{
etch_status_t etch_status = ETCH_SUCCESS;
etch_status = etch_runtime_initialize(NULL);
if(etch_status != NULL) {
// error
}
return 0;
}
static int clean_suite(void)
{
etch_runtime_shutdown();
return 0;
}
/* - - - - - - - - - - - - - -
* unit test support
* - - - - - - - - - - - - - -
*/
static etch_packetizer* g_my_packetizer;
static i_sessionpacket* g_my_sessionpacket;
static i_transportdata* g_my_transportdata;
static etch_flexbuffer* g_mybuf;
static etch_who* g_who;
#define THISTEST_WHO_VALUE 0x5151
static unsigned short CLASSID_MY_IMPL_SP;
static unsigned short CLASSID_MY_IMPL_TD;
#define is_my_impl_transportdata(x) \
(x && ((etch_object*)x)->obj_type == ETCHTYPEB_TRANSPORTDATA && ((etch_object*)x)->class_id == CLASSID_MY_IMPL_TD)
#define is_my_impl_sessionpkt(x) \
(x && ((etch_object*)x)->obj_type == ETCHTYPEB_SESSIONPKT&& ((etch_object*)x)->class_id == CLASSID_MY_IMPL_SP)
static int check_packetizer_results(i_transportdata*, etch_nativearray*);
static int check_packetizer_resultx(i_sessionpacket*, etch_nativearray*);
static int check_packetized_results (etch_arraylist*, etch_nativearray*);
static int check_packetized_result (byte* v1, size_t c1, byte* v2, size_t c2);
static 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;
static int is_equal_who(etch_who* who1, etch_who* who2)
{
int n1 = 0, n2 = 0;
if (!who1 || !who2) return FALSE;
if (((etch_object*)who1)->class_id != CLASSID_WHO || ((etch_object*)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
{
etch_object object;
/* 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 */
etch_object_destructor 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
*/
static int destroy_my_impl_transportdata (void* data)
{
my_impl_transportdata* thisx = (my_impl_transportdata*)data;
if (!is_etchobj_static_content(thisx))
{ /* invoke original i_transportdata destructor */
if (thisx->itd && thisx->destroy_transportdata)
thisx->destroy_transportdata(thisx->itd);
etch_object_destroy(thisx->list);
etch_object_destroy(thisx->query);
etch_object_destroy(thisx->query_result);
etch_object_destroy(thisx->control);
etch_object_destroy(thisx->value);
etch_object_destroy(thisx->eventx);
}
return destroy_objectex((etch_object*) thisx);
}
/**
* impl_transport_data()
* my_impl_transportdata::transport_data
* @param whoto caller retains, can be null
* @param fbuf caller retains
*/
static int impl_transport_data (void* data, void* who, void* buffer)
{
my_impl_transportdata* mytd = (my_impl_transportdata*)data;
etch_who* whoto = (etch_who*)who;
etch_flexbuffer* fbuf = (etch_flexbuffer*)buffer;
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_etch_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 etch_arraylist_add (mytd->list, wrapped_array);
}
/**
* my_transport_control()
* my_impl_transportdata::itransport::transport_control
*/
static 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
*/
static 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
*/
static etch_object* 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 (etch_object*) resultobj; /* caller owns */
}
/**
* my_transport_get_session()
* my_impl_transportdata::itransport::get_session
*/
static 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
*/
static 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.
*/
static int destroy_my_transportdata(void* data)
{
i_transportdata* itd = (i_transportdata*)data;
my_impl_transportdata* mytd = NULL;
if (NULL == itd) return -1;
mytd = itd->thisx;
etch_object_destroy(mytd);
return 0;
}
/**
* new_my_impl_transportdata()
* my_impl_transportdata constructor
*/
static 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);
((etch_object*)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 = ((etch_object*)itd)->destroy;
/* replace i_transportdata destructor with one which will destroy this object */
((etch_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
{
etch_object object;
/* 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 */
etch_object_destructor 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
*/
static int destroy_my_impl_sessionpacket(void* data)
{
my_impl_sessionpacket* thisx = (my_impl_sessionpacket*)data;
if (!is_etchobj_static_content(thisx))
{ /* invoke original i_sessionpacket destructor */
if (thisx->isp && thisx->destroy_sessionpacket)
thisx->destroy_sessionpacket(thisx->isp);
etch_object_destroy(thisx->list);
etch_object_destroy(thisx->query);
etch_object_destroy(thisx->query_result);
etch_object_destroy(thisx->control);
etch_object_destroy(thisx->value);
etch_object_destroy(thisx->eventx);
}
return destroy_objectex((etch_object*) thisx);
}
/**
* impl_session_packet()
* my_impl_sessionpacket::session_packet
* @param whofrom caller retains, can be null
* @param fbuf caller retains
*/
static int impl_session_packet (void* data, void* who, void* buffer)
{
my_impl_sessionpacket* mysp = (my_impl_sessionpacket*)data;
etch_who* whofrom = (etch_who*)who;
etch_flexbuffer* fbuf = (etch_flexbuffer*)buffer;
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_etch_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 etch_arraylist_add(mysp->list, wrapped_array);
}
/**
* my_session_control()
* my_impl_sessionpacket::isession::session_control
*/
static 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
*/
static 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
*/
static etch_object* 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 (etch_object*) 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
*/
static etch_arraylist* new_packetizertest_list()
{
etch_arraylist* list = new_etch_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.
*/
static int destroy_my_sessionpacket(void* data)
{
i_sessionpacket* itp = (i_sessionpacket*)data;
my_impl_sessionpacket* mytp = NULL;
if (NULL == itp) return -1;
mytp = itp->thisx;
etch_object_destroy(mytp);
return 0;
}
/**
* new_my_impl_sessionpacket()
* my_impl_sessionpacket constructor
*/
static 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);
((etch_object*)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 = ((etch_object*)isessionpkt)->destroy;
/* replace i_sessionpacket destructor with one which will destroy this object */
((etch_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.
*/
static 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.
*/
static 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()
*/
static 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 = etch_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.
*/
static 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()
*/
static 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));
/* 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()
*/
static int teardown_this_test()
{
etch_object_destroy(g_my_packetizer);
etch_object_destroy(g_my_sessionpacket); // destroy() is now 0xfeeefeee
etch_object_destroy(g_my_transportdata);
etch_object_destroy(g_who);
etch_object_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()
*/
static 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;
etch_object_destroy(isp);
} while(0);
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_transportdata_constructor()
*/
static 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;
etch_object_destroy(itd);
} while(0);
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_packetizer_constructor()
*/
static 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://127.0.0.1:4001?Packetizer.maxPktSize=110480", NULL);
CU_ASSERT_TRUE(pzr->maxpacketsize == 110480);
CU_ASSERT_PTR_NOT_NULL_FATAL(pzr);
etch_object_destroy(pzr);
/* i_transportdata.destroy() will destroy my_impl_transportdata */
etch_object_destroy(itd);
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* 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.
*/
static 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();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_to_source_packet1()
* test 1 for packets delivered to packet source
*/
static 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_etch_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), 8, 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);
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_to_source_packet2()
* test 2 for packets delivered to packet source
*/
static 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_etch_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), 9, 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);
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_to_source_packet3()
* test 3 for packets delivered to packet source
*/
static 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_etch_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), 10, 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);
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_to_source_badpacket1()
* test 4 for packets delivered to packet source
*/
static void test_to_source_badpacket1(void)
{
setup_this_test();
do
{ int result = 0;
#define TTSP4BYTECOUNT 7
byte* disposable_packet = NULL;
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();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_badpacket1()
* test 1 for bad packet data
*/
static 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);
etch_object_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);
etch_object_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);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_single_single_data()
* 3 tests for single packet in a single buffer
*/
static 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);
etch_object_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), 9, 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_etch_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);
etch_object_destroy(expected_result_2_array);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_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), 10, 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_etch_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);
etch_object_destroy(expected_result_3_array);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_one_buffer_data_1()
* test two packets in a single buffer
*/
static 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);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_one_buffer_data_2()
* test two packets in a single buffer - 2
*/
static 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_etch_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), 17, 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);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_one_buffer_data_3()
* test two packets in a single buffer - 3
*/
static 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_etch_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), 17, 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);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_one_buffer_data_4()
* test two packets in a single buffer - 4
*/
static 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_etch_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);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_one_buffer_data_5()
* test two packets in a single buffer - 5
*/
static 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_etch_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);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(expected_result_array);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_two_buffers_data_1()
* test two packets in two buffers with header split across buffers
* packets are empty in this test
*/
static 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 */
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(mybuf2);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_two_buffers_data_2()
* test two packets in two buffers with header split across buffers
* packets include bodies in this test
*/
static 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_etch_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 */
etch_object_destroy(expected_result_array);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(mybuf2);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_two_buffers_data_3()
* test two packets in two buffers with body split across buffers
*/
static 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_etch_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 */
etch_object_destroy(expected_result_array);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(mybuf2);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_two_in_two_buffers_data_4()
* test two packets in two buffers with body split across buffers
*/
static 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_etch_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), 10, 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 */
etch_object_destroy(expected_result_array);
etch_object_destroy(g_mybuf); g_mybuf = NULL;
etch_object_destroy(mybuf2);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_session_control
* test the session control notification plumbing
*/
static void test_session_control(void)
{
setup_this_test();
do
{
const int MY_CONTROL_CLASSID = 0x5200, MY_VALUE_CLASSID = 0x5201;
etch_object* mycontrolobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_CONTROL_CLASSID);
etch_object* myvalueobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_VALUE_CLASSID);
/* 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, (void*)mycontrolobj, myvalueobj);
CU_ASSERT_EQUAL(my_session->what, SESSION_CONTROL);
CU_ASSERT_PTR_NOT_NULL_FATAL(my_session->control);
CU_ASSERT_EQUAL(((etch_object*)my_session->control)->class_id, MY_CONTROL_CLASSID);
CU_ASSERT_EQUAL(((etch_object*)my_session->value)->class_id, MY_VALUE_CLASSID);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_session_notify
* test the session notify notification plumbing
*/
static void test_session_notify(void)
{
setup_this_test();
do
{
const int MY_EVENT_CLASSID = 0x5202;
etch_object* myeventobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_EVENT_CLASSID);
/* 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, (void*)myeventobj);
CU_ASSERT_EQUAL(my_session->what, SESSION_NOTIFY);
CU_ASSERT_PTR_NOT_NULL_FATAL(my_session->eventx);
CU_ASSERT_EQUAL(((etch_object*)my_session->eventx)->class_id, MY_EVENT_CLASSID);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_session_query
* test the session query notification plumbing
*/
static void test_session_query(void)
{
setup_this_test();
do
{
const int MY_QUERY_CLASSID = 0x5203, MY_RESULT_CLASSID = 0x5204;
etch_object* myqueryobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_QUERY_CLASSID);
etch_object* myresultobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_RESULT_CLASSID);
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, (etch_query*)myqueryobj);
CU_ASSERT_EQUAL(my_session->what, SESSION_QUERY);
CU_ASSERT_PTR_NOT_NULL_FATAL(my_session->query);
CU_ASSERT_EQUAL(((etch_object*)my_session->query)->class_id, MY_QUERY_CLASSID);
CU_ASSERT_PTR_NOT_NULL_FATAL(queryresult);
CU_ASSERT_EQUAL(((etch_object*)queryresult)->class_id, MY_RESULT_CLASSID);
etch_object_destroy(queryresult);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_transport_control
* test the transport control notification plumbing
*/
static void test_transport_control(void)
{
setup_this_test();
do
{
const int MY_CONTROL_CLASSID = 0x5200, MY_VALUE_CLASSID = 0x5201;
etch_object* mycontrolobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_CONTROL_CLASSID);
etch_object* myvalueobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_VALUE_CLASSID);
/* 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, (etch_event*)mycontrolobj, myvalueobj);
CU_ASSERT_EQUAL(my_transport->what, TRANSPORT_CONTROL);
CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport->control);
CU_ASSERT_EQUAL(((etch_object*)my_transport->control)->class_id, MY_CONTROL_CLASSID);
CU_ASSERT_EQUAL(((etch_object*)my_transport->value)->class_id, MY_VALUE_CLASSID);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_transport_notify
* test the transport notify notification plumbing
*/
static void test_transport_notify(void)
{
setup_this_test();
do
{
const int MY_EVENT_CLASSID = 0x5202;
etch_object* myeventobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_EVENT_CLASSID);
/* 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, (etch_event*)myeventobj);
CU_ASSERT_EQUAL(my_transport->what, TRANSPORT_NOTIFY);
CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport->eventx);
CU_ASSERT_EQUAL(((etch_object*)my_transport->eventx)->class_id, MY_EVENT_CLASSID);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* test_transport_query
* test the transport query notification plumbing
*/
static void test_transport_query(void)
{
setup_this_test();
do
{
const int MY_QUERY_CLASSID = 0x5203, MY_RESULT_CLASSID = 0x5204;
etch_object* myqueryobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_QUERY_CLASSID);
etch_object* myresultobj = new_object(sizeof(etch_object),ETCHTYPEB_ETCHOBJECT, MY_RESULT_CLASSID);
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, (etch_query*)myqueryobj);
CU_ASSERT_EQUAL(my_transport->what, TRANSPORT_QUERY);
CU_ASSERT_PTR_NOT_NULL_FATAL(my_transport->query);
CU_ASSERT_EQUAL(((etch_object*)my_transport->query)->class_id, MY_QUERY_CLASSID);
CU_ASSERT_PTR_NOT_NULL_FATAL(queryresult);
CU_ASSERT_EQUAL(((etch_object*)queryresult)->class_id, MY_RESULT_CLASSID);
etch_object_destroy(queryresult);
} while(0);
teardown_this_test();
#ifdef ETCH_DEBUGALLOC
g_bytes_allocated = etch_showmem(0,IS_DEBUG_CONSOLE); /* verify all memory freed */
CU_ASSERT_EQUAL(g_bytes_allocated, 0);
// start fresh for next test
memtable_clear();
#endif
}
/**
* main
*/
//int wmain( int argc, wchar_t* argv[], wchar_t* envp[])
CU_pSuite test_etch_packetizer_suite()
{
CU_pSuite ps = CU_add_suite("suite_packetizer", init_suite, clean_suite);
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);
return ps;
}