Testing of instantiate_object(BMessage* archive, image_id* id)
@note No cases are currently defined for NULL 'id' parameter, since NULL
is a valid value for it. Perhaps there should be to ensure that the
instantiate_object is, in fact, dealing with that case correctly.
There are also no tests against instantiate_object(BMessage*) as it
simply calls instantiate_object(BMessage*, image_id*) with NULL for
the image_id parameter.
*/
#include "InstantiateObjectTester.h"
#include <errno.h>
#include <stdexcept>
#include <iostream>
#include <Roster.h>
#include <Entry.h>
#include <Path.h>
#include <cppunit/Exception.h>
#include <TestShell.h>
#include "remoteobjectdef/RemoteTestObject.h"
#include "LocalTestObject.h"
using namespace std;
#define FORMAT_AND_THROW(MSG, ERR) \
FormatAndThrow(__LINE__, __FILE__, MSG, ERR)
const char* gInvalidClassName = "TInvalidClassName";
const char* gInvalidSig = "application/x-vnd.InvalidSignature";
const char* gLocalClassName = "TIOTest";
const char* gLocalSig = "application/x-vnd.LocalSignature";
const char* gRemoteClassName = "TRemoteTestObject";
const char* gRemoteSig = "application/x-vnd.RemoteObjectDef";
const char* gValidSig = gRemoteSig;
#if !TEST_R5
const char* gRemoteLib = "/lib/libsupporttest_RemoteTestObject.so";
#else
const char* gRemoteLib = "/lib/libsupporttest_RemoteTestObject_r5.so";
#endif
void FormatAndThrow(int line, const char* file, const char* msg, int err);
TInstantiateObjectTester::TInstantiateObjectTester(string name)
: BTestCase(name), fAddonId(B_ERROR)
{
;
}
instantiate_object(BMessage* archive, image_id* id)
@case Invalid archive
@param archive NULL
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE.
errno is set to B_BAD_VALUE.
*/
void TInstantiateObjectTester::Case1()
{
errno = B_OK;
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(NULL, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
instantiate_object(BMessage* archive, image_id* id)
@case No class name
@param archive Valid BMessage pointer without string field "class"
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE.
errno is set to B_OK.
*/
void TInstantiateObjectTester::Case2()
{
errno = B_OK;
BMessage Archive;
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_OK);
}
instantiate_object(BMessage* archive, image_id* id)
@case Invalid class name
@param archive Valid BMessage pointer, with string field labeled "class"
containing an invalid class name
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE.
errno is set to B_BAD_VALUE.
*/
void TInstantiateObjectTester::Case3()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gInvalidClassName);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
instantiate_object(BMessage* archive, image_id* id)
@case Invalid class name and signature
@param archive Valid BMessage pointer, with string fields labeled "class"
and "add_on", containing invalid class name and signature,
respectively
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE.
errno is set to B_LAUNCH_FAILED_APP_NOT_FOUND.
*/
void TInstantiateObjectTester::Case4()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gInvalidClassName);
Archive.AddString("add_on", gInvalidSig);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_LAUNCH_FAILED_APP_NOT_FOUND);
}
instantiate_object(BMessage* archive, image_id* id)
@case Invalid class name, valid signature
@param archive Valid BMessage pointer with string fields labeled "class"
and "add_on", containing invalid class name and valid
signature, respectively
@param id Valid image_id pointer
@requires RemoteObjectDef add-on must be built and accessible
@results Returns NULL.
*id is > 0 (add-on was loaded)
errno is set to B_BAD_VALUE.
*/
void TInstantiateObjectTester::Case5()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gInvalidClassName);
Archive.AddString("add_on", gValidSig);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id > 0);
unload_add_on(id);
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of class defined in local image
@param archive Valid BMessage pointer with string field "class" containing
name of locally defined class which can be instantiated via
archiving mechanism
@param id Valid image_id pointer
@requires locally defined class which can be instantiated via
archiving mechanism
@results Returns valid TIOTest instance.
*id is set to B_BAD_VALUE (no image was loaded).
errno is set to B_OK.
*/
void TInstantiateObjectTester::Case6()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gLocalClassName);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test != NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_OK);
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of class defined in add-on explicitely loaded
by this team
@param archive Valid BMessage pointer with string field "class" containing
name of remotely defined class which can be instantiated via
archiving mechanism
@param id Valid image_id pointer
@requires RemoteObjectDef add-on must be built and accessible
@results Returns valid TRemoteTestObject instance.
*id is set to B_BAD_VALUE (no image was loaded).
errno is set to B_OK.
*/
void TInstantiateObjectTester::Case7()
{
errno = B_OK;
LoadAddon();
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
image_id id = B_OK;
TRemoteTestObject* Test = (TRemoteTestObject*)instantiate_object(&Archive,
&id);
CPPUNIT_ASSERT(Test != NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_OK);
UnloadAddon();
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of remotely-defined class, without required
signature of the defining add-on
@param archive Valid BMessage pointer with string field "class" containing
name of remotely-defined class; no "add-on" field
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE (no image loaded).
errno is set to B_BAD_VALUE.
*/
void TInstantiateObjectTester::Case8()
{
errno = B_OK;
BMessage Archive;
CPPUNIT_ASSERT(Archive.AddString("class", gRemoteClassName) == B_OK);
image_id id = B_OK;
TRemoteTestObject* Test = (TRemoteTestObject*)instantiate_object(&Archive,
&id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_BAD_VALUE);
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive naming locally defined class with invalid
signature
@param archive Valid BMessage pointer with string field "class" containing
name of locally defined class and string field "add_on"
containing invalid signature
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE (no image loaded).
errno is set to B_LAUNCH_FAILED_APP_NOT_FOUND.
*/
void TInstantiateObjectTester::Case9()
{
errno = B_OK;
BMessage Archive;
CPPUNIT_ASSERT(Archive.AddString("class", gLocalClassName) == B_OK);
CPPUNIT_ASSERT(Archive.AddString("add_on", gInvalidSig) == B_OK);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_LAUNCH_FAILED_APP_NOT_FOUND);
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of class defined in add-on explicitely loaded
by this team, but with an invalid signature
@param archive Valid BMessage pointer with string field "class" containing
name of remotely-defined class and string field "add_on"
containing invalid signature
@param id Valid image_id pointer
@requires RemoteObjectDef add-on must be built and accessible
@results Returns NULL.
*id is set to B_BAD_VALUE (no image loaded).
errno is set to B_LAUNCH_FAILED_APP_NOT_FOUND.
*/
void TInstantiateObjectTester::Case10()
{
errno = B_OK;
LoadAddon();
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
Archive.AddString("add_on", gInvalidSig);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_LAUNCH_FAILED_APP_NOT_FOUND);
UnloadAddon();
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of remotely-defined class, with invalid
signature
@param archive Valid BMessage pointer with string field "class" containing
name of remotely-defined class and string field add-on
containing invalid signature
@param id Valid image_id pointer
@results Returns NULL.
*id is set to B_BAD_VALUE.
errno is set to B_LAUNCH_FAILED_APP_NOT_FOUND
*/
void TInstantiateObjectTester::Case11()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
Archive.AddString("add_on", gInvalidSig);
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test == NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_LAUNCH_FAILED_APP_NOT_FOUND);
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of locally-defined class with correct
signature
@param archive Valid BMessage pointer with string field "class" containing
name of locally-defined class and string field "add_on"
containing signature of current team
@param id Valid image_id pointer
@requires locally defined class which can be instantiated via
archiving mechanism
@results Returns valid TIOTest instance.
*id is set to B_BAD_VALUE (no image loaded).
errno is set to B_OK.
@note This test is not currently used; GetLocalSignature() doesn't
seem to work without a BApplication instance constructed.
See GetLocalSignature() for more info.
*/
void TInstantiateObjectTester::Case12()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gLocalClassName);
Archive.AddString("add_on", GetLocalSignature().c_str());
image_id id = B_OK;
TIOTest* Test = (TIOTest*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test != NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_OK);
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of class defined in add-on explicitely loaded
by this team with signature of add-on
@param archive Valid BMessage pointer with string field "class" containing
name of remotely-defined class and string field "add_on"
containing signature of loaded add-on
@param id Valid image_id pointer
@requires RemoteObjectDef add-on must be built and accessible
@results Returns valid instance of TRemoteTestObject.
*id is set to B_BAD_VALUE (image load not necessary).
errno is set to B_OK.
*/
void TInstantiateObjectTester::Case13()
{
errno = B_OK;
LoadAddon();
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
Archive.AddString("add_on", gRemoteSig);
image_id id = B_OK;
TRemoteTestObject* Test = (TRemoteTestObject*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test != NULL);
CPPUNIT_ASSERT(id == B_BAD_VALUE);
CPPUNIT_ASSERT(errno == B_OK);
UnloadAddon();
}
instantiate_object(BMessage* archive, image_id* id)
@case Valid archive of remotely-defined class with correct
signature
@param archive Valid BMessage pointer with string field "class" containing
name of remotely-defined class and string field "add_on"
containing signature of defining add-on
@param id Valid image_id pointer
@requires RemoteObjectDef must be built and accessible
@results Returns valid instance of TRemoteTestObject.
*id > 0 (image was loaded).
errno is set to B_OK.
*/
void TInstantiateObjectTester::Case14()
{
errno = B_OK;
BMessage Archive;
Archive.AddString("class", gRemoteClassName);
Archive.AddString("add_on", gRemoteSig);
image_id id = B_OK;
TRemoteTestObject* Test = (TRemoteTestObject*)instantiate_object(&Archive, &id);
CPPUNIT_ASSERT(Test != NULL);
CPPUNIT_ASSERT(id > 0);
unload_add_on(id);
CPPUNIT_ASSERT(errno == B_OK);
}
CppUnit::Test* TInstantiateObjectTester::Suite()
{
CppUnit::TestSuite* SuiteOfTests = new CppUnit::TestSuite;
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case1);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case2);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case3);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case4);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case5);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case6);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case8);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case7);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case9);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case10);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case11);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case13);
ADD_TEST(SuiteOfTests, TInstantiateObjectTester, Case14);
return SuiteOfTests;
}
void TInstantiateObjectTester::LoadAddon()
{
if (fAddonId > 0)
return;
std::string libPath = std::string(BTestShell::GlobalTestDir()) + gRemoteLib;
cout << "dir == '" << libPath << "'" << endl;
fAddonId = load_add_on(libPath.c_str());
RES(fAddonId);
if (fAddonId <= 0)
{
FORMAT_AND_THROW(" failed to load addon: ", fAddonId);
}
}
void TInstantiateObjectTester::UnloadAddon()
{
if (fAddonId > 0)
{
status_t err = unload_add_on(fAddonId);
fAddonId = B_ERROR;
if (err)
{
FORMAT_AND_THROW(" failed to unload addon: ", err);
}
}
}
std::string TInstantiateObjectTester::GetLocalSignature()
{
BRoster Roster;
app_info ai;
team_id team;
thread_id tid = find_thread(NULL);
thread_info ti;
status_t err = get_thread_info(tid, &ti);
if (err)
{
FORMAT_AND_THROW(" failed to get thread_info: ", err);
}
team = ti.team;
team_info info;
err = get_team_info(team, &info);
if (err)
{
FORMAT_AND_THROW(" failed to get team_info: ", err);
}
team = info.team;
err = Roster.GetRunningAppInfo(team, &ai);
if (err)
{
FORMAT_AND_THROW(" failed to get app_info: ", err);
}
return ai.signature;
}
void FormatAndThrow(int line, const char *file, const char *msg, int err)
{
std::string s("line: ");
s += IntToStr(line);
s += " ";
s += file;
s += msg;
s += strerror(err);
s += "(";
s += IntToStr(err);
s += ")";
CppUnit::Exception re(s.c_str());
throw re;
}
void
TInstantiateObjectTester::RunTests() {
NextSubTest();
Case1();
NextSubTest();
Case2();
NextSubTest();
Case3();
NextSubTest();
Case4();
NextSubTest();
Case5();
NextSubTest();
Case6();
NextSubTest();
Case7();
NextSubTest();
Case8();
NextSubTest();
Case9();
NextSubTest();
Case10();
NextSubTest();
Case11();
NextSubTest();
Case12();
NextSubTest();
Case13();
NextSubTest();
Case14();
}
* $Log $
*
* $Id $
*
*/