blob: 99bd47b40e9fc16d9ad00aaa0e66a54da86254bd [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_remote.c
* test remote, delivery service, etc.
*/
#include "etch_runtime.h"
#include "etch_svcobj_masks.h"
#include "etch_transport.h"
#include "etch_thread.h"
#include "etch_stub.h"
#include "etch_remote.h"
#include "etch_default_value_factory.h"
#include "etch_plain_mailbox.h"
#include "etch_plain_mailbox_manager.h"
#include "etch_objecttypes.h"
#include "etch_general.h"
#include "etch_map.h"
#include "etch_log.h"
#include <stdio.h>
#include "CUnit.h"
#ifdef _WIN32
#pragma message ( "this testsuite is not active" )
#else
#warning "this testsuite is not active"
#endif
#define IS_DEBUG_CONSOLE FALSE
/* - - - - - - - - - - - - - -
* 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;
}
#if 0
// extern types
extern apr_pool_t* g_etch_main_pool;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - -
* unit test support
* - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#define THISTEST_WHO_VALUE 0x5151
#define TEST_MSGID 0x1001
#define TEST_QDELAYMS 1000
#define TEST_MBOX_LIFETIME_UNTIL_CLOSE 0
#define TEST_LIFETIME_ONE_SECOND 1000
#define TEST_MAXMSGS_ONE 1
static unsigned short CLASSID_MY_VF;
static unsigned short CLASSID_MY_VF_VTAB;
static unsigned short CLASSID_MY_VF_IMPL;
static unsigned short CLASSID_MY_REMOTEIMPL;
static unsigned short CLASSID_MY_IMPLBASE;
static unsigned short CLASSID_MY_REMOTEBASE;
static unsigned short CLASSID_MY_RESULT;
typedef enum whats
{ TRANSPORT_MESSAGE = 1, TRANSPORT_QUERY, TRANSPORT_CONTROL, TRANSPORT_NOTIFY,
BEGIN_CALL, END_CALL
} whats;
static etch_resources* g_my_resources;
static default_value_factory* g_my_vf;
static etch_plainmailbox* g_my_mbox;
static i_mailbox* g_my_ibox;
static etch_plainmailboxmgr* g_my_mboxmgr;
static i_delivery_service* g_my_ds;
static etch_type* g_mt_foo;
static etch_type* g_mt_bar;
static etch_who* gds_who;
static int64 gds_messageid;
static int gds_what;
static int gds_rtypeid;
static int gds_eventval;
static int gds_queryval;
static int gds_controlval;
static int gds_valueval;
static i_delivery_service* new_my_delivery_service();
static int my_pmboxmgr_session_notify (etch_plainmailboxmgr*, etch_event*);
static default_value_factory* new_fake_valuefactory();
static char* LOGSRC = "TEST";
/**
* new_my_resources()
* resources map constructor
*/
static etch_resources* new_my_resources(void* valuefactory)
{
etch_resources* resx = get_etch_transport_resources(NULL);
etch_resources_add(resx, ETCH_RESXKEY_MSGIZER_VALUFACT, valuefactory);
return resx;
}
/**
* setup_this_test()
* set up an individual unit test
*/
static int setup_this_test()
{
CLASSID_MY_VF = get_dynamic_classid();
CLASSID_MY_VF_VTAB = get_dynamic_classid();
CLASSID_MY_VF_IMPL = get_dynamic_classid();
#if(IS_DEBUG_CONSOLE)
printf("\n");
#endif
g_mt_foo = new_static_type(L"foo");
g_mt_bar = new_static_type(L"bar");
g_my_vf = new_fake_valuefactory();
set_etchobj_static_all(g_my_vf); /* so resources map will not destroy */
/* get resources map populated with transport resources such as thread pools */
g_my_resources = new_my_resources(g_my_vf);
g_my_ds = new_my_delivery_service ();
/* the ids itm object belongs to the ds transport which is the mailbox manager */
g_my_mboxmgr = g_my_ds->transport->thisx;
CU_ASSERT_FATAL(is_etch_mailboxmgr(g_my_mboxmgr));
/* register a new mailbox with the manager */
g_my_mbox = new_mailbox (g_my_mboxmgr->imanager, TEST_MSGID,
TEST_QDELAYMS, TEST_MBOX_LIFETIME_UNTIL_CLOSE, TEST_MAXMSGS_ONE);
CU_ASSERT_PTR_NOT_NULL_FATAL(g_my_mbox);
g_my_ibox = g_my_mbox->imailbox;
g_my_mboxmgr->session_notify = my_pmboxmgr_session_notify;
return 0;
}
/**
* teardown_this_test()
* tear down an individual unit test
*/
static void teardown_this_test()
{
if (g_my_mboxmgr)
if (g_my_mbox)
etch_object_destroy(g_my_mbox);
if (g_my_resources)
{ /* we did a set_etchobj_static_all() on the g_my_vf value factory
* and as a result the map will not destroy it. if we had not done
* so, the vf would have been destroyed with the resources map. */
etch_object_destroy(g_my_resources);
}
if (g_my_vf)
{ /* we clear the set_etchobj_static_all() on the g_my_vf value factory
* and as a result we can then destroy it */
clear_etchobj_static_all(g_my_vf);
etch_object_destroy(g_my_vf);
}
etch_object_destroy(g_my_ds);
destroy_static_type(g_mt_foo);
destroy_static_type(g_mt_bar);
gds_what = 0;
gds_who = NULL;
g_my_vf = NULL;
g_my_ds = NULL;
g_my_mbox = NULL;
g_my_ibox = NULL;
g_my_mboxmgr = NULL;
g_mt_foo = g_mt_bar = NULL;
gds_eventval= gds_queryval = gds_controlval = gds_valueval = 0;
g_my_resources = NULL;
gds_messageid = 0;
gds_rtypeid = 0;
etchvf_free_builtins();
}
/* - - - - - - - - - -
* mailbox manager
* - - - - - - - - - -
*/
static int my_pmboxmgr_session_notify (etch_plainmailboxmgr* mgr, etch_event* evt)
{
switch(evt->value)
{ case ETCHEVT_SESSION_DOWN: pmboxmgr_unregister_all(mgr);
}
// ETCHOBJ_DESTROY();
etch_object_destroy(evt);
evt = NULL;
return 0;
}
/* - - - - - - - - - -
* remote object
* - - - - - - - - - -
*/
/**
* my_remoteobj
* xxxx_remote_either
* this represents for this test what would be a service remote_server or remote_client in practice.
*/
typedef struct my_remoteobj
{
etch_object object;
i_xxxx_either* xxxx_either_base; /* owned server or client */
xxxx_remote* remote_base; /* owned */
void* either_factory; /* owned */
default_value_factory* vf; /* owned by base */
/* note that the transport interface is accessed via the remote_base */
} my_remoteobj;
/* - - - - - - - - - -
* value factory
* - - - - - - - - - -
*/
/**
* my_valufactory_impl
* value factory instance data object
*/
typedef struct my_valufactory_impl
{
etch_object object;
} my_valufactory_impl;
/**
* destroy_my_valufactory_impl()
* destructor for inheriting value factory instance data
*/
static int destroy_my_valufactory_impl(my_valufactory_impl* impl)
{
if (NULL == impl) return -1;
if (!is_etchobj_static_content(impl))
{
/* no custom types to destroy - they are global for this test */
}
return destroy_objectex((etch_object*) impl);
}
/**
* new_my_valufactory_impl()
* constructor for our value factory's instance data
*/
static my_valufactory_impl* new_my_valufactory_impl()
{
unsigned short class_id = CLASSID_MY_VF_IMPL? CLASSID_MY_VF_IMPL:
(CLASSID_MY_VF_IMPL = get_dynamic_classid());
my_valufactory_impl* impl = (my_valufactory_impl*) new_object
(sizeof(my_valufactory_impl), ETCHTYPEB_VALUEFACTIMP, class_id);
((etch_object*)impl)->destroy = destroy_my_valufactory_impl;
return impl;
}
/**
* new_fake_valuefactory()
*/
static default_value_factory* new_fake_valuefactory()
{
my_valufactory_impl* impl = NULL;
etchparentinfo* inheritlist = NULL;
const unsigned short classid_vf = get_dynamic_classid_unique(&CLASSID_MY_VF);
const unsigned short classid_vf_vtab = get_dynamic_classid_unique(&CLASSID_MY_VF_VTAB);
g_my_vf = new_default_value_factory(NULL, NULL);
/* ensure parent type keys exist in the (one-based) inheritance list.
* parent class of our custom vf is default_value_factory.
* inheritance list is used by validators and object assignment logic.
*/
inheritlist = get_vtab_inheritance_list((etch_object*)g_my_vf, 2, 1, classid_vf_vtab);
inheritlist[1].obj_type = ETCHTYPEB_VALUEFACTORY;
inheritlist[1].class_id = CLASSID_VALUEFACTORY; /* parent class */
((etch_object*)g_my_vf)->class_id = classid_vf; /* our class */
/* instantiate the custom vf's instance data and assign it to the vf.
* the impl comprises all data specific to the inheriting class, including
* data and methods if any. the default value factory destructor will call
* the destructor on the vf's impl object.
*/
impl = new_my_valufactory_impl();
g_my_vf->impl = (etch_object*) impl;
((struct i_value_factory*)((etch_object*)g_my_vf)->vtab)->add_type(g_my_vf, g_mt_foo);
((struct i_value_factory*)((etch_object*)g_my_vf)->vtab)->add_type(g_my_vf, g_mt_bar);
/* set msgid validator so we can set and retrieve message IDs */
etchtype_put_validator(g_mt_foo, builtins._mf__message_id, (etch_object*) etchvtor_int64_get(0));
etchtype_put_validator(g_mt_bar, builtins._mf__message_id, (etch_object*) etchvtor_int64_get(0));
return g_my_vf;
}
/* - - - - - - - - - -
* delivery service
* - - - - - - - - - -
*/
/**
* myds_begincall()
* override for i_delivery_service.begin_call().
* typedef int (*etch_delivsvc_begincall)(void* thisx, etch_message*, void** out);
* @param msg caller relinquishes on success, retains on failure
* @param out mailbox interface returned on success
* @return 0 success, or -1 failure. new mailbox return in out parameter.
*/
static int myds_begincall (i_delivery_service* thisx, etch_message* msg, void** out)
{
etch_int64* msgid = NULL;
assert(out);
*out = g_my_ibox;
gds_what = BEGIN_CALL;
msgid = message_get_id(msg);
gds_messageid = msgid? msgid->value: 0;
etch_object_destroy(msg);
msg = NULL;
return 0;
}
/**
* myds_endcall()
* override for i_delivery_service.end_call().
* typedef int (*etch_delvisvc_endcall)(void* thisx, i_mailbox*, etch_type*, void** out);
* message response received. close mailbox and return response.
* @param mbox the current mailbox (interface), caller retains.
* @param response_type type of the response message, caller retains.
* @param out pointer to caller's location to receive the message response object.
* @return 0 success, -1 failure. response object returned via out parameter.
* @remarks assumed that the reply message and its wrapper are destroyed with the mailbox.
*/
static int myds_endcall (i_delivery_service* thisx, i_mailbox* mbox, etch_type* rtype, void** out)
{
etch_int32* resultobj = new_int32(CLASSID_MY_RESULT);
((etch_object*)resultobj)->class_id = CLASSID_MY_RESULT;
gds_what = END_CALL;
gds_rtypeid = rtype->id;
assert(out);
*out = resultobj;
return 0;
}
/* - - - - - - - - - - - - - - - - -
* delivery service i_sessionmessage
* - - - - - - - - - - - - - - - - -
*/
/* this is the i_delivery_service implementation of i_sessionmessage,
* distinct from the transport.session's implementation of i_sessionmessage
* which is implemented externally and set via set_session().
*/
/**
* myds_session_message()
* override for i_delivery_service.ism.session_message().
* @param whofrom caller retains, can be null.
* @param msg caller relinquishes
* @return 0 (message handled), or -1 (error, closed, or timeout)
*/
static int myds_session_message (etch_tcp_delivery_service* thisx, etch_who* whofrom, etch_message* msg)
{
etch_object_destroy(msg);
msg = NULL;
return -1;
}
/**
* myds_session_control()
* override for i_delivery_service.ism.session_control().
* @param control event, caller relinquishes.
* @param value control value, caller relinquishes.
*/
static int myds_session_control (etch_tcp_delivery_service* thisx, etch_event* control, etch_object* value)
{
etch_object_destroy(control);
control = NULL;
etch_object_destroy(value);
value = NULL;
return -1;
}
/**
* myds_session_notify()
* override for i_delivery_service.ism.session_notify().
* @param evt event, caller relinquishes.
*/
static int myds_session_notify (etch_tcp_delivery_service* thisx, etch_event* evt)
{
etch_object_destroy(evt);
evt = NULL;
return -1;
}
/**
* myds_session_query()
* override for i_delivery_service.ism.session_query().
* @param query, caller relinquishes.
*/
static etch_object* myds_session_query (void* data, etch_query* query)
{
etch_tcp_delivery_service* thisx = (etch_tcp_delivery_service*)data;
etch_object_destroy(query);
query = NULL;
return NULL;
}
/* - - - - - - - - - - - - - - - - - -
* delivery service i_transportmessage
* - - - - - - - - - - - - - - - - - -
*/
/**
* myds_transport_message()
* override for i_delivery_service.itm.transport_message().
* @param whoto recipient - caller retains
* @param message caller relinquishes on success, retains on failure.
* @return 0 success, -1 error.
*/
static int myds_transport_message (etch_tcp_delivery_service* thisx, etch_who* whoto, etch_message* msg)
{
etch_int64* msgid = NULL;
gds_what = TRANSPORT_MESSAGE;
gds_who = whoto;
msgid = message_get_id(msg);
gds_messageid = msgid? msgid->value: 0;
etch_object_destroy(msg);
msg = NULL;
return 0;
}
/**
* myds_transport_control()
* override for i_delivery_service.itm.transport_control()
* @param control caller relinquishes.
* @param value caller relinquishes.
*/
static int myds_transport_control (void* data, etch_event* control, etch_object* value)
{
etch_tcp_delivery_service* thisx = (etch_tcp_delivery_service*)data;
etch_int32* i = NULL;
assert(control);
gds_what = TRANSPORT_CONTROL;
gds_controlval = control->value;
i = (etch_int32*)value;
gds_valueval = i? i->value: -1;
etch_object_destroy(control);
control = NULL;
etch_object_destroy(value);
value = NULL;
return 0;
}
/**
* myds_transport_notify()
* override for i_delivery_service.itm.transport_notify()
* i_transportmessage::transport_notify override.
* @param evt, caller relinquishes.
*/
static int myds_transport_notify (etch_tcp_delivery_service* thisx, etch_event* evt)
{
assert(evt);
gds_what = TRANSPORT_NOTIFY;
gds_eventval = evt->value;
etch_object_destroy(evt);
return 0;
}
/**
* myds_transport_query()
* override for i_delivery_service.itm.transport_query()
* i_transportmessage::transport_query override.
* @param query, caller relinquishes.
*/
static etch_object* myds_transport_query (etch_tcp_delivery_service* thisx, etch_query* query)
{
etch_int32* resultobj = new_int32(CLASSID_MY_RESULT);
((etch_object*)resultobj)->class_id = CLASSID_MY_RESULT;
gds_what = TRANSPORT_QUERY;
gds_queryval = query->value;
etch_object_destroy(query);
return (etch_object*) resultobj;
}
/**
* myds_get_session()
* override for i_delivery_service.itm.get_session()
* i_transportmessage::get_session override.
*/
static struct i_sessionmessage* myds_get_session (void* data)
{
etch_tcp_delivery_service* thisx = (etch_tcp_delivery_service*)data;
assert(FALSE);
return NULL;
}
/**
* myds_set_session()
* override for i_delivery_service.itm.set_session()
* i_transportmessage::set_session override.
*/
static void myds_set_session (etch_tcp_delivery_service* thisx, i_sessionmessage* newsession)
{
assert(FALSE);
}
/* - - - - - - - - - - - - - - -
* delivery service construction
* - - - - - - - - - - - - - - -
*/
/**
* new_my_delivery_service()
*/
static i_delivery_service* new_my_delivery_service()
{
etch_tcp_connection* nullconnection = NULL;
etch_tcp_delivery_service* delsvc = NULL;
i_sessionmessage* ism = NULL;
i_transportmessage* itm = NULL;
etch_client_factory* impl_factory = new_client_factory (NULL, NULL, NULL);
i_delivery_service* ids = new_etch_transport(L"http://www.cisco.com:9999/cuae",
(etch_factory_params*) impl_factory, nullconnection);
CU_ASSERT_PTR_NOT_NULL_FATAL(ids);
delsvc = ids->thisx;
CU_ASSERT_PTR_NOT_NULL_FATAL(delsvc);
CU_ASSERT_EQUAL_FATAL(is_etch_deliverysvc(delsvc), TRUE);
ism = ids->ism;
itm = ids->itm;
CU_ASSERT_PTR_NOT_NULL_FATAL(ism);
CU_ASSERT_EQUAL_FATAL(is_etch_sessionmsg(ism), TRUE);
CU_ASSERT_PTR_NOT_NULL_FATAL(itm);
CU_ASSERT_EQUAL_FATAL(is_etch_transportmsg(itm), TRUE);
/* override delivery service i_sessionmessage to implementations herein */
ids->begin_call = delsvc->begin_call = myds_begincall;
ids->end_call = delsvc->end_call = myds_endcall;
ism->session_message = delsvc->session_message = myds_session_message;
ism->session_control = delsvc->session_control = myds_session_control;
ism->session_notify = delsvc->session_notify = myds_session_notify;
ism->session_query = delsvc->session_query = myds_session_query;
/* override delivery service i_transportmessage to implementations herein.
* note that we swap out the virtuals, but the not the itm object, which
* is the ds transport, which is the mailbox manager's itm. the mailbox
* manager owns it and will destroy it when destroyed during destruction
* of the delivery service.
*/
itm->transport_message = delsvc->transport_message = myds_transport_message;
itm->transport_control = delsvc->transport_control = myds_transport_control;
itm->transport_notify = delsvc->transport_notify = myds_transport_notify;
itm->transport_query = delsvc->transport_query = myds_transport_query;
itm->get_session = delsvc->get_session = myds_get_session;
itm->set_session = delsvc->set_session = myds_set_session;
return ids;
}
/* - - - - - - - - - - - - - - - - -
* remote androgynous object
* - - - - - - - - - - - - - - - - -
*/
/**
* destroy_my_remoteobj()
* destructor for our remote object
*/
static int destroy_my_remoteobj(my_remoteobj* thisx)
{
etch_object_destroy(thisx->xxxx_either_base);
thisx->xxxx_either_base = NULL;
etch_object_destroy(thisx->remote_base);
thisx->remote_base = NULL;
return destroy_objectex((etch_object*) thisx);
}
/**
* destroy_my_clientorserver_impl()
* destructor for our remoteobj.xxxx_either_base
*/
static int destroy_my_clientorserver_impl(i_xxxx_either* thisx)
{
etch_free(thisx->iobjsession);
return destroy_objectex((etch_object*) thisx);
}
/**
* new_my_clientorserver_impl()
* instatiate my_remoteobj.xxxx_either_base
*/
static i_xxxx_either* new_my_clientorserver_impl(my_remoteobj* thisx)
{
i_xxxx_either* either_base = (i_xxxx_either*) new_object (sizeof(i_xxxx_either),
ETCHTYPEB_EXESERVERBASE, get_dynamic_classid_unique(&CLASSID_MY_IMPLBASE));
((etch_object*)either_base)->destroy = destroy_my_clientorserver_impl;
either_base->thisx = (etch_object*) thisx;
{ /* populate as much of xxxx_either_impl as we need */
i_objsession* ios = new_default_objsession_interface (thisx);
either_base->iobjsession = ios;
either_base->_session_control = ios->_session_control;
either_base->_session_notify = ios->_session_notify;
either_base->_session_query = ios->_session_query;
}
return either_base;
}
/**
* new_my_remote_base
* instantiates remote base.
* @param ids delivery service -- caller retains.
* @param vf default value factory -- caller retains.
* @param ixxxx service interface -- caller retains.
*/
static xxxx_remote* new_my_remote_base (void* thisx,
i_delivery_service* ids, etch_value_factory* vf, etch_object* ixxxx)
{
xxxx_remote* remote = new_etch_remote_base (thisx, ETCH_DEFSIZE,
get_dynamic_classid_unique(&CLASSID_MY_REMOTEBASE), ids, vf, ixxxx);
return remote;
}
/**
* new_my_remote_client_or_server()
* instatiate and return an implementing object for the remote base.
*/
static my_remoteobj* new_my_remote_client_or_server (void* thisx, i_delivery_service* ids, etch_value_factory* vf)
{
/* for these tests it doesn't matter whether we use obj_type of client or server */
my_remoteobj* remoteobj = (my_remoteobj*) new_object (sizeof(my_remoteobj),
ETCHTYPEB_REMOTESERVER, get_dynamic_classid_unique(&CLASSID_MY_REMOTEIMPL));
((etch_object*)remoteobj)->destroy = destroy_my_remoteobj;
remoteobj->remote_base = new_my_remote_base (remoteobj, ids, vf, NULL);
remoteobj->xxxx_either_base = new_my_clientorserver_impl(remoteobj);
return remoteobj;
}
/* - - - - - - - - - - - - - - - - - - - - -
* unit tests
* - - - - - - - - - - - - - - - - - - - - -
*/
/**
* test_setup()
* test instantiation and teardown of test components such as delivery service,
* value factory, etc.
*/
static void test_setup(void)
{
setup_this_test();
do
{
} 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_new_message()
*/
static void test_new_message(void)
{
setup_this_test();
do
{ int result = 0;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through etchremote_new_message() */
etch_message* newmsg = remote->new_message(remote, g_mt_foo);
CU_ASSERT_PTR_NOT_NULL_FATAL(newmsg);
result = is_equal_types(message_type(newmsg), g_mt_foo);
CU_ASSERT_EQUAL(result, TRUE);
CU_ASSERT_PTR_EQUAL(newmsg->vf, g_my_vf);
etch_object_destroy(newmsg);
etch_object_destroy(myremote);
} 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_send()
*/
static void test_send(void)
{
setup_this_test();
do
{ int result = 0, MSGIDVAL = 54321;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
etch_message* newmsg = remote->new_message (myremote->remote_base, g_mt_foo);
message_set_id (newmsg, new_int64(MSGIDVAL));
/* this call goes through delivery service.transport_message,
* which we overrode to myds_transport_message() above.
*/
result = remote->send (remote, newmsg); /* send message */
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(TRANSPORT_MESSAGE, gds_what);
CU_ASSERT_EQUAL(gds_messageid, MSGIDVAL);
if (0 != result) /* message was relinquished on send() success */
{
etch_object_destroy(newmsg);
newmsg = NULL;
}
((etch_object*)myremote)->destroy(myremote);
} 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_begincall()
*/
static void test_begincall(void)
{
setup_this_test();
do
{ int result = 0, MSGIDVAL = 65432;
i_mailbox* outmbox = NULL;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
etch_message* newmsg = remote->new_message (myremote->remote_base, g_mt_foo);
message_set_id (newmsg, new_int64(MSGIDVAL));
/* this call goes through delivery service.begin_call,
* which we overrode to myds_begincall() above.
*/
result = remote->begin_call (remote, newmsg, &outmbox);
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(BEGIN_CALL, gds_what);
CU_ASSERT_EQUAL(gds_messageid, MSGIDVAL);
CU_ASSERT_PTR_EQUAL(g_my_ibox, outmbox);
if (0 != result) /* message was relinquished on begin_call() success */
{
etch_object_destroy(newmsg);
newmsg = NULL;
}
etch_object_destroy(myremote);
} 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_endcall()
*/
static void test_endcall(void)
{
setup_this_test();
do
{ int result = 0, resultval = 0;
etch_object* resultobj = NULL;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through delivery service.end_call,
* which we overrode to myds_endcall() above.
*/
result = remote->end_call (remote, g_my_ibox, g_mt_bar, &resultobj);
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(END_CALL, gds_what);
CU_ASSERT_PTR_NOT_NULL_FATAL(resultobj);
CU_ASSERT_EQUAL(((etch_object*)resultobj)->class_id, CLASSID_MY_RESULT);
CU_ASSERT_EQUAL(g_mt_bar->id, gds_rtypeid);
etch_object_destroy(resultobj);
resultobj = NULL;
etch_object_destroy(myremote);
} 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()
*/
static void test_transport_query(void)
{
setup_this_test();
do
{ int result = 0, resultval = 0, THISQUERYVAL = 76543;
etch_object* resultobj = NULL;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through delivery service.transport_query,
* which we overrode to myds_transport_query() above.
*/
resultobj = remote->transport_query (remote, new_etch_query(0, THISQUERYVAL));
CU_ASSERT_PTR_NOT_NULL_FATAL(resultobj);
CU_ASSERT_EQUAL(((etch_object*)resultobj)->class_id, CLASSID_MY_RESULT);
CU_ASSERT_EQUAL(TRANSPORT_QUERY, gds_what);
etch_object_destroy(resultobj);
resultobj = NULL;
etch_object_destroy(myremote);
} 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()
*/
static void test_transport_control(void)
{
setup_this_test();
do
{ int result = 0, resultval = 0, THISCTLVAL = 87654, THISVALVAL = 98765;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through delivery service.transport_control,
* which we overrode to myds_transport_control() above.
*/
result = remote->transport_control (remote, new_etch_control(0, THISCTLVAL), new_int32(THISVALVAL));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(TRANSPORT_CONTROL, gds_what);
CU_ASSERT_EQUAL(gds_controlval, THISCTLVAL);
CU_ASSERT_EQUAL(gds_valueval, THISVALVAL);
etch_object_destroy(myremote);
} 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()
*/
static void test_transport_notify(void)
{
setup_this_test();
do
{ int result = 0, resultval = 0, THISEVTVAL = 45678;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through delivery service.transport_notify,
* which we overrode to myds_transport_notify() above.
*/
result = remote->transport_notify (remote, new_etch_event(0, THISEVTVAL));
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(TRANSPORT_NOTIFY, gds_what);
CU_ASSERT_EQUAL(gds_eventval, THISEVTVAL);
etch_object_destroy(myremote);
} 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_start_waitup()
*/
static void test_start_waitup(void)
{
setup_this_test();
do
{ int result = 0, resultval = 0, THISWAITMS = 3000;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through delivery service.transport_control,
* which we overrode to myds_transport_control() in our ds constuctor
* above. so we're not testing an actual connection waitup, we're testing
* that the call reaches delivery service.transport_control(), and that
* we can override delivery service.transport_control() at will.
*/
result = remote->start_waitup(remote, ETCH_NOWAIT);
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(TRANSPORT_CONTROL, gds_what);
CU_ASSERT_EQUAL(gds_controlval, ETCH_NOWAIT);
result = remote->start_waitup(remote, THISWAITMS);
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(gds_controlval, THISWAITMS);
etch_object_destroy(myremote);
} 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_stop_waitdown()
*/
static void test_stop_waitdown(void)
{
setup_this_test();
do
{ int result = 0, resultval = 0, THISWAITMS = 3000;
my_remoteobj* myremote = new_my_remote_client_or_server (NULL,
g_my_ds, (etch_value_factory*) g_my_vf);
etch_remote* remote = myremote->remote_base;
/* this call goes through delivery service.transport_control,
* which we overrode to myds_transport_control() in our ds constuctor
* above. so we're not testing an actual connection waitdown, we're testing
* that the call reaches delivery service.transport_control(), and that
* we can override delivery service.transport_control() at will.
*/
result = remote->stop_waitdown(remote, ETCH_NOWAIT);
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(TRANSPORT_CONTROL, gds_what);
CU_ASSERT_EQUAL(gds_controlval, ETCH_NOWAIT);
result = remote->stop_waitdown(remote, THISWAITMS);
CU_ASSERT_EQUAL(result, 0);
CU_ASSERT_EQUAL(gds_controlval, THISWAITMS);
etch_object_destroy(myremote);
} 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
}
#endif
CU_pSuite test_etch_remote_suite()
{
CU_pSuite ps = CU_add_suite("remote base test suite", init_suite, clean_suite);
// THESE TESTS ARE BROKEN
// TODO first fix the stub tests per java tests, then redo these tests similarly.
//CU_add_test(ps, "test test setup and teardown", test_setup);
//CU_add_test(ps, "test remote.new_message", test_new_message);
//CU_add_test(ps, "test remote.send", test_send);
//CU_add_test(ps, "test remote.begin_call", test_begincall);
//CU_add_test(ps, "test remote.end_call", test_endcall);
//CU_add_test(ps, "test remote.transport_query", test_transport_query);
//CU_add_test(ps, "test remote.transport_control", test_transport_control);
//CU_add_test(ps, "test remote.transport_notify", test_transport_notify);
//CU_add_test(ps, "test remote.start_waitup", test_start_waitup);
//CU_add_test(ps, "test remote.stop_waitdown", test_stop_waitdown);
return ps;
}